Preallocate BUILTIN_ATTRIBUTES symbols and use a hash map instead of looping
This commit is contained in:
parent
fcf850f34a
commit
b82ab24bbf
9 changed files with 645 additions and 417 deletions
|
@ -3356,9 +3356,11 @@ name = "syntax"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc_data_structures 0.0.0",
|
"rustc_data_structures 0.0.0",
|
||||||
"rustc_errors 0.0.0",
|
"rustc_errors 0.0.0",
|
||||||
|
"rustc_macros 0.1.0",
|
||||||
"rustc_target 0.0.0",
|
"rustc_target 0.0.0",
|
||||||
"scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serialize 0.0.0",
|
"serialize 0.0.0",
|
||||||
|
|
|
@ -42,7 +42,7 @@ use syntax::edition::Edition;
|
||||||
use syntax::feature_gate::{AttributeGate, AttributeTemplate, AttributeType};
|
use syntax::feature_gate::{AttributeGate, AttributeTemplate, AttributeType};
|
||||||
use syntax::feature_gate::{Stability, deprecated_attributes};
|
use syntax::feature_gate::{Stability, deprecated_attributes};
|
||||||
use syntax_pos::{BytePos, Span, SyntaxContext};
|
use syntax_pos::{BytePos, Span, SyntaxContext};
|
||||||
use syntax::symbol::keywords;
|
use syntax::symbol::{Symbol, keywords};
|
||||||
use syntax::errors::{Applicability, DiagnosticBuilder};
|
use syntax::errors::{Applicability, DiagnosticBuilder};
|
||||||
use syntax::print::pprust::expr_to_string;
|
use syntax::print::pprust::expr_to_string;
|
||||||
use syntax::visit::FnKind;
|
use syntax::visit::FnKind;
|
||||||
|
@ -653,7 +653,7 @@ impl EarlyLintPass for AnonymousParameters {
|
||||||
pub struct DeprecatedAttr {
|
pub struct DeprecatedAttr {
|
||||||
// This is not free to compute, so we want to keep it around, rather than
|
// This is not free to compute, so we want to keep it around, rather than
|
||||||
// compute it for every attribute.
|
// compute it for every attribute.
|
||||||
depr_attrs: Vec<&'static (&'static str, AttributeType, AttributeTemplate, AttributeGate)>,
|
depr_attrs: Vec<&'static (Symbol, AttributeType, AttributeTemplate, AttributeGate)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_lint_pass!(DeprecatedAttr => []);
|
impl_lint_pass!(DeprecatedAttr => []);
|
||||||
|
@ -668,9 +668,8 @@ impl DeprecatedAttr {
|
||||||
|
|
||||||
impl EarlyLintPass for DeprecatedAttr {
|
impl EarlyLintPass for DeprecatedAttr {
|
||||||
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
|
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
|
||||||
let name = attr.name_or_empty();
|
|
||||||
for &&(n, _, _, ref g) in &self.depr_attrs {
|
for &&(n, _, _, ref g) in &self.depr_attrs {
|
||||||
if name == n {
|
if attr.ident().map(|ident| ident.name) == Some(n) {
|
||||||
if let &AttributeGate::Gated(Stability::Deprecated(link, suggestion),
|
if let &AttributeGate::Gated(Stability::Deprecated(link, suggestion),
|
||||||
ref name,
|
ref name,
|
||||||
ref reason,
|
ref reason,
|
||||||
|
|
|
@ -118,7 +118,7 @@ macro_rules! late_lint_passes {
|
||||||
UnusedBrokenConst: UnusedBrokenConst,
|
UnusedBrokenConst: UnusedBrokenConst,
|
||||||
|
|
||||||
// Uses attr::is_used which is untracked, can't be an incremental module pass.
|
// Uses attr::is_used which is untracked, can't be an incremental module pass.
|
||||||
UnusedAttributes: UnusedAttributes,
|
UnusedAttributes: UnusedAttributes::new(),
|
||||||
|
|
||||||
// Needs to run after UnusedAttributes as it marks all `feature` attributes as used.
|
// Needs to run after UnusedAttributes as it marks all `feature` attributes as used.
|
||||||
UnstableFeatures: UnstableFeatures,
|
UnstableFeatures: UnstableFeatures,
|
||||||
|
|
|
@ -3,15 +3,17 @@ use rustc::hir::def_id::DefId;
|
||||||
use rustc::lint;
|
use rustc::lint;
|
||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
use rustc::ty::adjustment;
|
use rustc::ty::adjustment;
|
||||||
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use lint::{LateContext, EarlyContext, LintContext, LintArray};
|
use lint::{LateContext, EarlyContext, LintContext, LintArray};
|
||||||
use lint::{LintPass, EarlyLintPass, LateLintPass};
|
use lint::{LintPass, EarlyLintPass, LateLintPass};
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::errors::Applicability;
|
use syntax::errors::Applicability;
|
||||||
use syntax::feature_gate::{BUILTIN_ATTRIBUTES, AttributeType};
|
use syntax::feature_gate::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
|
||||||
use syntax::print::pprust;
|
use syntax::print::pprust;
|
||||||
use syntax::symbol::keywords;
|
use syntax::symbol::keywords;
|
||||||
|
use syntax::symbol::Symbol;
|
||||||
use syntax::util::parser;
|
use syntax::util::parser;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
|
||||||
|
@ -210,17 +212,32 @@ declare_lint! {
|
||||||
"detects attributes that were not used by the compiler"
|
"detects attributes that were not used by the compiler"
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint_pass!(UnusedAttributes => [UNUSED_ATTRIBUTES]);
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct UnusedAttributes {
|
||||||
|
builtin_attributes: &'static FxHashMap<Symbol, &'static BuiltinAttribute>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UnusedAttributes {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
UnusedAttributes {
|
||||||
|
builtin_attributes: &*BUILTIN_ATTRIBUTE_MAP,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_lint_pass!(UnusedAttributes => [UNUSED_ATTRIBUTES]);
|
||||||
|
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
|
||||||
fn check_attribute(&mut self, cx: &LateContext<'_, '_>, attr: &ast::Attribute) {
|
fn check_attribute(&mut self, cx: &LateContext<'_, '_>, attr: &ast::Attribute) {
|
||||||
debug!("checking attribute: {:?}", attr);
|
debug!("checking attribute: {:?}", attr);
|
||||||
// Note that check_name() marks the attribute as used if it matches.
|
|
||||||
for &(name, ty, ..) in BUILTIN_ATTRIBUTES {
|
let attr_info = attr.ident().and_then(|ident| self.builtin_attributes.get(&ident.name));
|
||||||
|
|
||||||
|
if let Some(&&(name, ty, ..)) = attr_info {
|
||||||
match ty {
|
match ty {
|
||||||
AttributeType::Whitelisted if attr.check_name(name) => {
|
AttributeType::Whitelisted => {
|
||||||
debug!("{:?} is Whitelisted", name);
|
debug!("{:?} is Whitelisted", name);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
@ -239,11 +256,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
|
||||||
debug!("Emitting warning for: {:?}", attr);
|
debug!("Emitting warning for: {:?}", attr);
|
||||||
cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
|
cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
|
||||||
// Is it a builtin attribute that must be used at the crate level?
|
// Is it a builtin attribute that must be used at the crate level?
|
||||||
let known_crate = BUILTIN_ATTRIBUTES.iter()
|
let known_crate = attr_info.map(|&&(_, ty, ..)| {
|
||||||
.find(|&&(builtin, ty, ..)| {
|
ty == AttributeType::CrateLevel
|
||||||
name == builtin && ty == AttributeType::CrateLevel
|
}).unwrap_or(false);
|
||||||
})
|
|
||||||
.is_some();
|
|
||||||
|
|
||||||
// Has a plugin registered this attribute as one that must be used at
|
// Has a plugin registered this attribute as one that must be used at
|
||||||
// the crate level?
|
// the crate level?
|
||||||
|
|
|
@ -360,8 +360,8 @@ impl<'a> Resolver<'a> {
|
||||||
|
|
||||||
let attr_candidates = BUILTIN_ATTRIBUTES
|
let attr_candidates = BUILTIN_ATTRIBUTES
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(name, _, _, gate)| {
|
.filter_map(|&(name, _, _, ref gate)| {
|
||||||
if name.starts_with("rustc_") && !features.rustc_attrs {
|
if name.as_str().starts_with("rustc_") && !features.rustc_attrs {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,7 +376,6 @@ impl<'a> Resolver<'a> {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(|name| Symbol::intern(name))
|
|
||||||
.chain(
|
.chain(
|
||||||
// Add built-in macro attributes as well.
|
// Add built-in macro attributes as well.
|
||||||
self.builtin_macros.iter().filter_map(|(name, binding)| {
|
self.builtin_macros.iter().filter_map(|(name, binding)| {
|
||||||
|
|
|
@ -14,8 +14,10 @@ bitflags = "1.0"
|
||||||
serialize = { path = "../libserialize" }
|
serialize = { path = "../libserialize" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
scoped-tls = "1.0"
|
scoped-tls = "1.0"
|
||||||
|
lazy_static = "1.0.0"
|
||||||
syntax_pos = { path = "../libsyntax_pos" }
|
syntax_pos = { path = "../libsyntax_pos" }
|
||||||
errors = { path = "../librustc_errors", package = "rustc_errors" }
|
errors = { path = "../librustc_errors", package = "rustc_errors" }
|
||||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||||
|
rustc_macros = { path = "../librustc_macros" }
|
||||||
rustc_target = { path = "../librustc_target" }
|
rustc_target = { path = "../librustc_target" }
|
||||||
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
|
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -100,8 +100,127 @@ symbols! {
|
||||||
|
|
||||||
// Other symbols that can be referred to with syntax_pos::symbols::*
|
// Other symbols that can be referred to with syntax_pos::symbols::*
|
||||||
Other {
|
Other {
|
||||||
doc, cfg, masked, spotlight, alias, keyword, feature, include, simd, align, stable,
|
alias,
|
||||||
unstable, rustc_const_unstable,
|
align,
|
||||||
|
alloc_error_handler,
|
||||||
|
allow,
|
||||||
|
allow_fail,
|
||||||
|
allow_internal_unsafe,
|
||||||
|
allow_internal_unstable,
|
||||||
|
automatically_derived,
|
||||||
|
cfg,
|
||||||
|
cfg_attr,
|
||||||
|
cold,
|
||||||
|
compiler_builtins,
|
||||||
|
crate_id,
|
||||||
|
crate_name,
|
||||||
|
crate_type,
|
||||||
|
default_lib_allocator,
|
||||||
|
deny,
|
||||||
|
deprecated,
|
||||||
|
derive,
|
||||||
|
doc,
|
||||||
|
export_name,
|
||||||
|
feature,
|
||||||
|
ffi_returns_twice,
|
||||||
|
forbid,
|
||||||
|
fundamental,
|
||||||
|
global_allocator,
|
||||||
|
ignore,
|
||||||
|
include,
|
||||||
|
inline,
|
||||||
|
keyword,
|
||||||
|
lang,
|
||||||
|
link,
|
||||||
|
link_args,
|
||||||
|
link_name,
|
||||||
|
link_section,
|
||||||
|
linkage,
|
||||||
|
macro_escape,
|
||||||
|
macro_export,
|
||||||
|
macro_use,
|
||||||
|
main,
|
||||||
|
marker,
|
||||||
|
masked,
|
||||||
|
may_dangle,
|
||||||
|
must_use,
|
||||||
|
naked,
|
||||||
|
needs_allocator,
|
||||||
|
needs_panic_runtime,
|
||||||
|
no_builtins,
|
||||||
|
no_core,
|
||||||
|
no_debug,
|
||||||
|
no_implicit_prelude,
|
||||||
|
no_link,
|
||||||
|
no_main,
|
||||||
|
no_mangle,
|
||||||
|
no_start,
|
||||||
|
no_std,
|
||||||
|
non_exhaustive,
|
||||||
|
omit_gdb_pretty_printer_section,
|
||||||
|
optimize,
|
||||||
|
panic_handler,
|
||||||
|
panic_runtime,
|
||||||
|
path,
|
||||||
|
plugin,
|
||||||
|
plugin_registrar,
|
||||||
|
prelude_import,
|
||||||
|
proc_macro,
|
||||||
|
proc_macro_attribute,
|
||||||
|
proc_macro_derive,
|
||||||
|
profiler_runtime,
|
||||||
|
recursion_limit,
|
||||||
|
reexport_test_harness_main,
|
||||||
|
repr,
|
||||||
|
rustc_args_required_const,
|
||||||
|
rustc_clean,
|
||||||
|
rustc_const_unstable,
|
||||||
|
rustc_conversion_suggestion,
|
||||||
|
rustc_copy_clone_marker,
|
||||||
|
rustc_def_path,
|
||||||
|
rustc_deprecated,
|
||||||
|
rustc_dirty,
|
||||||
|
rustc_dump_program_clauses,
|
||||||
|
rustc_dump_user_substs,
|
||||||
|
rustc_error,
|
||||||
|
rustc_expected_cgu_reuse,
|
||||||
|
rustc_if_this_changed,
|
||||||
|
rustc_inherit_overflow_checks,
|
||||||
|
rustc_layout,
|
||||||
|
rustc_layout_scalar_valid_range_end,
|
||||||
|
rustc_layout_scalar_valid_range_start,
|
||||||
|
rustc_mir,
|
||||||
|
rustc_on_unimplemented,
|
||||||
|
rustc_outlives,
|
||||||
|
rustc_paren_sugar,
|
||||||
|
rustc_partition_codegened,
|
||||||
|
rustc_partition_reused,
|
||||||
|
rustc_proc_macro_decls,
|
||||||
|
rustc_regions,
|
||||||
|
rustc_std_internal_symbol,
|
||||||
|
rustc_symbol_name,
|
||||||
|
rustc_synthetic,
|
||||||
|
rustc_test_marker,
|
||||||
|
rustc_then_this_would_need,
|
||||||
|
rustc_transparent_macro,
|
||||||
|
rustc_variance,
|
||||||
|
sanitizer_runtime,
|
||||||
|
should_panic,
|
||||||
|
simd,
|
||||||
|
spotlight,
|
||||||
|
stable,
|
||||||
|
start,
|
||||||
|
structural_match,
|
||||||
|
target_feature,
|
||||||
|
test_runner,
|
||||||
|
thread_local,
|
||||||
|
type_length_limit,
|
||||||
|
unsafe_destructor_blind_to_params,
|
||||||
|
unstable,
|
||||||
|
unwind,
|
||||||
|
used,
|
||||||
|
warn,
|
||||||
|
windows_subsystem,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,14 +356,6 @@ newtype_index! {
|
||||||
pub struct SymbolIndex { .. }
|
pub struct SymbolIndex { .. }
|
||||||
}
|
}
|
||||||
|
|
||||||
// The interner is pointed to by a thread local value which is only set on the main thread
|
|
||||||
// with parallelization is disabled. So we don't allow `Symbol` to transfer between threads
|
|
||||||
// to avoid panics and other errors, even though it would be memory safe to do so.
|
|
||||||
#[cfg(not(parallel_compiler))]
|
|
||||||
impl !Send for Symbol { }
|
|
||||||
#[cfg(not(parallel_compiler))]
|
|
||||||
impl !Sync for Symbol { }
|
|
||||||
|
|
||||||
impl Symbol {
|
impl Symbol {
|
||||||
const fn new(n: u32) -> Self {
|
const fn new(n: u32) -> Self {
|
||||||
Symbol(SymbolIndex::from_u32_const(n))
|
Symbol(SymbolIndex::from_u32_const(n))
|
||||||
|
|
|
@ -27,7 +27,7 @@ LL | #[inline = ""]
|
||||||
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
|
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
|
||||||
|
|
||||||
warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...",
|
warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...",
|
||||||
/*opt*/ cfg = "...")]`
|
/*opt*/ cfg = "...")]`
|
||||||
--> $DIR/malformed-regressions.rs:6:1
|
--> $DIR/malformed-regressions.rs:6:1
|
||||||
|
|
|
|
||||||
LL | #[link]
|
LL | #[link]
|
||||||
|
@ -37,7 +37,7 @@ LL | #[link]
|
||||||
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
|
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
|
||||||
|
|
||||||
warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...",
|
warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...",
|
||||||
/*opt*/ cfg = "...")]`
|
/*opt*/ cfg = "...")]`
|
||||||
--> $DIR/malformed-regressions.rs:7:1
|
--> $DIR/malformed-regressions.rs:7:1
|
||||||
|
|
|
|
||||||
LL | #[link = ""]
|
LL | #[link = ""]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue