@@ -358,6 +358,7 @@ struct Context<'a> {
358
358
features : Vec < & ' static str > ,
359
359
span_handler : & ' a SpanHandler ,
360
360
cm : & ' a CodeMap ,
361
+ plugin_attributes : & ' a [ ( String , AttributeType ) ] ,
361
362
}
362
363
363
364
impl < ' a > Context < ' a > {
@@ -372,7 +373,7 @@ impl<'a> Context<'a> {
372
373
self . features . iter ( ) . any ( |& n| n == feature)
373
374
}
374
375
375
- fn check_attribute ( & self , attr : & ast:: Attribute ) {
376
+ fn check_attribute ( & self , attr : & ast:: Attribute , is_macro : bool ) {
376
377
debug ! ( "check_attribute(attr = {:?})" , attr) ;
377
378
let name = & * attr. name ( ) ;
378
379
for & ( n, ty) in KNOWN_ATTRIBUTES {
@@ -384,6 +385,15 @@ impl<'a> Context<'a> {
384
385
return ;
385
386
}
386
387
}
388
+ for & ( ref n, ref ty) in self . plugin_attributes . iter ( ) {
389
+ if & * n == name {
390
+ // Plugins can't gate attributes, so we don't check for it
391
+ // unlike the code above; we only use this loop to
392
+ // short-circuit to avoid the checks below
393
+ debug ! ( "check_attribute: {:?} is registered by a plugin, {:?}" , name, ty) ;
394
+ return ;
395
+ }
396
+ }
387
397
if name. starts_with ( "rustc_" ) {
388
398
self . gate_feature ( "rustc_attrs" , attr. span ,
389
399
"unless otherwise specified, attributes \
@@ -394,12 +404,18 @@ impl<'a> Context<'a> {
394
404
"attributes of the form `#[derive_*]` are reserved \
395
405
for the compiler") ;
396
406
} else {
397
- self . gate_feature ( "custom_attribute" , attr. span ,
398
- & format ! ( "The attribute `{}` is currently \
399
- unknown to the compiler and \
400
- may have meaning \
401
- added to it in the future",
402
- name) ) ;
407
+ // Only run the custom attribute lint during regular
408
+ // feature gate checking. Macro gating runs
409
+ // before the plugin attributes are registered
410
+ // so we skip this then
411
+ if !is_macro {
412
+ self . gate_feature ( "custom_attribute" , attr. span ,
413
+ & format ! ( "The attribute `{}` is currently \
414
+ unknown to the compiler and \
415
+ may have meaning \
416
+ added to it in the future",
417
+ name) ) ;
418
+ }
403
419
}
404
420
}
405
421
}
@@ -478,7 +494,7 @@ impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> {
478
494
}
479
495
480
496
fn visit_attribute ( & mut self , attr : & ' v ast:: Attribute ) {
481
- self . context . check_attribute ( attr) ;
497
+ self . context . check_attribute ( attr, true ) ;
482
498
}
483
499
}
484
500
@@ -497,7 +513,7 @@ impl<'a> PostExpansionVisitor<'a> {
497
513
impl < ' a , ' v > Visitor < ' v > for PostExpansionVisitor < ' a > {
498
514
fn visit_attribute ( & mut self , attr : & ast:: Attribute ) {
499
515
if !self . context . cm . span_allows_unstable ( attr. span ) {
500
- self . context . check_attribute ( attr) ;
516
+ self . context . check_attribute ( attr, false ) ;
501
517
}
502
518
}
503
519
@@ -684,6 +700,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
684
700
685
701
fn check_crate_inner < F > ( cm : & CodeMap , span_handler : & SpanHandler ,
686
702
krate : & ast:: Crate ,
703
+ plugin_attributes : & [ ( String , AttributeType ) ] ,
687
704
check : F )
688
705
-> Features
689
706
where F : FnOnce ( & mut Context , & ast:: Crate )
@@ -692,6 +709,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
692
709
features : Vec :: new ( ) ,
693
710
span_handler : span_handler,
694
711
cm : cm,
712
+ plugin_attributes : plugin_attributes,
695
713
} ;
696
714
697
715
let mut accepted_features = Vec :: new ( ) ;
@@ -764,14 +782,14 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
764
782
765
783
pub fn check_crate_macros ( cm : & CodeMap , span_handler : & SpanHandler , krate : & ast:: Crate )
766
784
-> Features {
767
- check_crate_inner ( cm, span_handler, krate,
785
+ check_crate_inner ( cm, span_handler, krate, & [ ] as & ' static [ _ ] ,
768
786
|ctx, krate| visit:: walk_crate ( & mut MacroVisitor { context : ctx } , krate) )
769
787
}
770
788
771
- pub fn check_crate ( cm : & CodeMap , span_handler : & SpanHandler , krate : & ast:: Crate )
772
- -> Features
789
+ pub fn check_crate ( cm : & CodeMap , span_handler : & SpanHandler , krate : & ast:: Crate ,
790
+ plugin_attributes : & [ ( String , AttributeType ) ] ) -> Features
773
791
{
774
- check_crate_inner ( cm, span_handler, krate,
792
+ check_crate_inner ( cm, span_handler, krate, plugin_attributes ,
775
793
|ctx, krate| visit:: walk_crate ( & mut PostExpansionVisitor { context : ctx } ,
776
794
krate) )
777
795
}
0 commit comments