@@ -3,15 +3,17 @@ use rustc::hir::def_id::DefId;
33use rustc:: lint;
44use rustc:: ty;
55use rustc:: ty:: adjustment;
6+ use rustc_data_structures:: fx:: FxHashMap ;
67use lint:: { LateContext , EarlyContext , LintContext , LintArray } ;
78use lint:: { LintPass , EarlyLintPass , LateLintPass } ;
89
910use syntax:: ast;
1011use syntax:: attr;
1112use syntax:: errors:: Applicability ;
12- use syntax:: feature_gate:: { BUILTIN_ATTRIBUTES , AttributeType } ;
13+ use syntax:: feature_gate:: { AttributeType , BuiltinAttribute , BUILTIN_ATTRIBUTE_MAP } ;
1314use syntax:: print:: pprust;
1415use syntax:: symbol:: keywords;
16+ use syntax:: symbol:: Symbol ;
1517use syntax:: util:: parser;
1618use syntax_pos:: Span ;
1719
@@ -210,17 +212,32 @@ declare_lint! {
210212 "detects attributes that were not used by the compiler"
211213}
212214
213- declare_lint_pass ! ( UnusedAttributes => [ UNUSED_ATTRIBUTES ] ) ;
215+ #[ derive( Copy , Clone ) ]
216+ pub struct UnusedAttributes {
217+ builtin_attributes : & ' static FxHashMap < Symbol , & ' static BuiltinAttribute > ,
218+ }
219+
220+ impl UnusedAttributes {
221+ pub fn new ( ) -> Self {
222+ UnusedAttributes {
223+ builtin_attributes : & * BUILTIN_ATTRIBUTE_MAP ,
224+ }
225+ }
226+ }
227+
228+ impl_lint_pass ! ( UnusedAttributes => [ UNUSED_ATTRIBUTES ] ) ;
214229
215230impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for UnusedAttributes {
216231 fn check_attribute ( & mut self , cx : & LateContext < ' _ , ' _ > , attr : & ast:: Attribute ) {
217232 debug ! ( "checking attribute: {:?}" , attr) ;
218- // Note that check_name() marks the attribute as used if it matches.
219- for & ( name, ty, ..) in BUILTIN_ATTRIBUTES {
233+
234+ let attr_info = attr. ident ( ) . and_then ( |ident| self . builtin_attributes . get ( & ident. name ) ) ;
235+
236+ if let Some ( & & ( name, ty, ..) ) = attr_info {
220237 match ty {
221- AttributeType :: Whitelisted if attr . check_name ( name ) => {
238+ AttributeType :: Whitelisted => {
222239 debug ! ( "{:?} is Whitelisted" , name) ;
223- break ;
240+ return ;
224241 }
225242 _ => ( ) ,
226243 }
@@ -239,11 +256,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
239256 debug ! ( "Emitting warning for: {:?}" , attr) ;
240257 cx. span_lint ( UNUSED_ATTRIBUTES , attr. span , "unused attribute" ) ;
241258 // Is it a builtin attribute that must be used at the crate level?
242- let known_crate = BUILTIN_ATTRIBUTES . iter ( )
243- . find ( |& & ( builtin, ty, ..) | {
244- name == builtin && ty == AttributeType :: CrateLevel
245- } )
246- . is_some ( ) ;
259+ let known_crate = attr_info. map ( |& & ( _, ty, ..) | {
260+ ty == AttributeType :: CrateLevel
261+ } ) . unwrap_or ( false ) ;
247262
248263 // Has a plugin registered this attribute as one that must be used at
249264 // the crate level?
0 commit comments