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"
dependencies = [
"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)",
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
"rustc_macros 0.1.0",
"rustc_target 0.0.0",
"scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"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::{Stability, deprecated_attributes};
use syntax_pos::{BytePos, Span, SyntaxContext};
use syntax::symbol::keywords;
use syntax::symbol::{Symbol, keywords};
use syntax::errors::{Applicability, DiagnosticBuilder};
use syntax::print::pprust::expr_to_string;
use syntax::visit::FnKind;
@ -653,7 +653,7 @@ impl EarlyLintPass for AnonymousParameters {
pub struct DeprecatedAttr {
// This is not free to compute, so we want to keep it around, rather than
// 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 => []);
@ -668,9 +668,8 @@ impl DeprecatedAttr {
impl EarlyLintPass for DeprecatedAttr {
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
let name = attr.name_or_empty();
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),
ref name,
ref reason,

View File

@ -118,7 +118,7 @@ macro_rules! late_lint_passes {
UnusedBrokenConst: UnusedBrokenConst,
// 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.
UnstableFeatures: UnstableFeatures,

View File

@ -3,15 +3,17 @@ use rustc::hir::def_id::DefId;
use rustc::lint;
use rustc::ty;
use rustc::ty::adjustment;
use rustc_data_structures::fx::FxHashMap;
use lint::{LateContext, EarlyContext, LintContext, LintArray};
use lint::{LintPass, EarlyLintPass, LateLintPass};
use syntax::ast;
use syntax::attr;
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::symbol::keywords;
use syntax::symbol::Symbol;
use syntax::util::parser;
use syntax_pos::Span;
@ -210,17 +212,32 @@ declare_lint! {
"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 {
fn check_attribute(&mut self, cx: &LateContext<'_, '_>, attr: &ast::Attribute) {
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 {
AttributeType::Whitelisted if attr.check_name(name) => {
AttributeType::Whitelisted => {
debug!("{:?} is Whitelisted", name);
break;
return;
}
_ => (),
}
@ -239,11 +256,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
debug!("Emitting warning for: {:?}", attr);
cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
// Is it a builtin attribute that must be used at the crate level?
let known_crate = BUILTIN_ATTRIBUTES.iter()
.find(|&&(builtin, ty, ..)| {
name == builtin && ty == AttributeType::CrateLevel
})
.is_some();
let known_crate = attr_info.map(|&&(_, ty, ..)| {
ty == AttributeType::CrateLevel
}).unwrap_or(false);
// Has a plugin registered this attribute as one that must be used at
// the crate level?

View File

@ -360,8 +360,8 @@ impl<'a> Resolver<'a> {
let attr_candidates = BUILTIN_ATTRIBUTES
.iter()
.filter_map(|(name, _, _, gate)| {
if name.starts_with("rustc_") && !features.rustc_attrs {
.filter_map(|&(name, _, _, ref gate)| {
if name.as_str().starts_with("rustc_") && !features.rustc_attrs {
return None;
}
@ -376,7 +376,6 @@ impl<'a> Resolver<'a> {
_ => None,
}
})
.map(|name| Symbol::intern(name))
.chain(
// Add built-in macro attributes as well.
self.builtin_macros.iter().filter_map(|(name, binding)| {

View File

@ -14,8 +14,10 @@ bitflags = "1.0"
serialize = { path = "../libserialize" }
log = "0.4"
scoped-tls = "1.0"
lazy_static = "1.0.0"
syntax_pos = { path = "../libsyntax_pos" }
errors = { path = "../librustc_errors", package = "rustc_errors" }
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_macros = { path = "../librustc_macros" }
rustc_target = { path = "../librustc_target" }
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 {
doc, cfg, masked, spotlight, alias, keyword, feature, include, simd, align, stable,
unstable, rustc_const_unstable,
alias,
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 { .. }
}
// 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 {
const fn new(n: u32) -> Self {
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>
warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...",
/*opt*/ cfg = "...")]`
/*opt*/ cfg = "...")]`
--> $DIR/malformed-regressions.rs:6:1
|
LL | #[link]
@ -37,7 +37,7 @@ LL | #[link]
= 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|...",
/*opt*/ cfg = "...")]`
/*opt*/ cfg = "...")]`
--> $DIR/malformed-regressions.rs:7:1
|
LL | #[link = ""]