1
Fork 0

Preallocate BUILTIN_ATTRIBUTES symbols and use a hash map instead of looping

This commit is contained in:
John Kåre Alsaker 2019-04-10 19:47:55 +02:00
parent fcf850f34a
commit b82ab24bbf
9 changed files with 645 additions and 417 deletions

View file

@ -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",

View file

@ -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,

View file

@ -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,

View file

@ -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?

View file

@ -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)| {

View file

@ -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

View file

@ -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))

View file

@ -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 = ""]