Skip to content
Permalink
Browse files

Preallocate BUILTIN_ATTRIBUTES symbols and use a hash map instead of …

…looping
  • Loading branch information...
Zoxc committed Apr 10, 2019
1 parent fcf850f commit b82ab24bbf9b6dc6bf7cdccb516ea196f3d0a71f
@@ -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",
@@ -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,
@@ -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,
@@ -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?
@@ -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)| {
@@ -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"] }
Oops, something went wrong.

0 comments on commit b82ab24

Please sign in to comment.
You can’t perform that action at this time.