@@ -185,6 +185,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
185
185
Attribute :: Parsed ( AttributeKind :: Naked ( attr_span) ) => {
186
186
self . check_naked ( hir_id, * attr_span, span, target)
187
187
}
188
+ Attribute :: Parsed ( AttributeKind :: Path ( _, attr_span) ) => {
189
+ self . check_generic_attr ( hir_id, sym:: path, * attr_span, target, Target :: Mod )
190
+ }
188
191
Attribute :: Parsed ( AttributeKind :: TrackCaller ( attr_span) ) => {
189
192
self . check_track_caller ( hir_id, * attr_span, attrs, span, target)
190
193
}
@@ -294,16 +297,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
294
297
[ sym:: macro_use, ..] | [ sym:: macro_escape, ..] => {
295
298
self . check_macro_use ( hir_id, attr, target)
296
299
}
297
- [ sym:: path, ..] => self . check_generic_attr ( hir_id, attr, target, Target :: Mod ) ,
298
300
[ sym:: macro_export, ..] => self . check_macro_export ( hir_id, attr, target) ,
299
301
[ sym:: ignore, ..] | [ sym:: should_panic, ..] => {
300
- self . check_generic_attr ( hir_id, attr, target, Target :: Fn )
302
+ self . check_generic_attr_unparsed ( hir_id, attr, target, Target :: Fn )
301
303
}
302
304
[ sym:: automatically_derived, ..] => {
303
- self . check_generic_attr ( hir_id, attr, target, Target :: Impl )
305
+ self . check_generic_attr_unparsed ( hir_id, attr, target, Target :: Impl )
304
306
}
305
307
[ sym:: no_implicit_prelude, ..] => {
306
- self . check_generic_attr ( hir_id, attr, target, Target :: Mod )
308
+ self . check_generic_attr_unparsed ( hir_id, attr, target, Target :: Mod )
307
309
}
308
310
[ sym:: proc_macro, ..] => {
309
311
self . check_proc_macro ( hir_id, target, ProcMacroKind :: FunctionLike )
@@ -312,7 +314,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
312
314
self . check_proc_macro ( hir_id, target, ProcMacroKind :: Attribute ) ;
313
315
}
314
316
[ sym:: proc_macro_derive, ..] => {
315
- self . check_generic_attr ( hir_id, attr, target, Target :: Fn ) ;
317
+ self . check_generic_attr_unparsed ( hir_id, attr, target, Target :: Fn ) ;
316
318
self . check_proc_macro ( hir_id, target, ProcMacroKind :: Derive )
317
319
}
318
320
[ sym:: autodiff_forward, ..] | [ sym:: autodiff_reverse, ..] => {
@@ -621,7 +623,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
621
623
}
622
624
}
623
625
624
- fn check_generic_attr (
626
+ fn check_generic_attr_unparsed (
625
627
& self ,
626
628
hir_id : HirId ,
627
629
attr : & Attribute ,
@@ -644,6 +646,27 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
644
646
}
645
647
}
646
648
649
+ fn check_generic_attr (
650
+ & self ,
651
+ hir_id : HirId ,
652
+ attr_name : Symbol ,
653
+ attr_span : Span ,
654
+ target : Target ,
655
+ allowed_target : Target ,
656
+ ) {
657
+ if target != allowed_target {
658
+ self . tcx . emit_node_span_lint (
659
+ UNUSED_ATTRIBUTES ,
660
+ hir_id,
661
+ attr_span,
662
+ errors:: OnlyHasEffectOn {
663
+ attr_name : attr_name. to_string ( ) ,
664
+ target_name : allowed_target. name ( ) . replace ( ' ' , "_" ) ,
665
+ } ,
666
+ ) ;
667
+ }
668
+ }
669
+
647
670
/// Checks if `#[naked]` is applied to a function definition.
648
671
fn check_naked ( & self , hir_id : HirId , attr_span : Span , span : Span , target : Target ) {
649
672
match target {
@@ -2804,7 +2827,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
2804
2827
// resolution for the attribute macro error.
2805
2828
const ATTRS_TO_CHECK : & [ Symbol ] = & [
2806
2829
sym:: macro_export,
2807
- sym:: path,
2808
2830
sym:: automatically_derived,
2809
2831
sym:: rustc_main,
2810
2832
sym:: derive,
@@ -2822,6 +2844,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
2822
2844
( attr. span ( ) , * a)
2823
2845
} else if let Attribute :: Parsed ( AttributeKind :: Repr ( r) ) = attr {
2824
2846
( r. first ( ) . unwrap ( ) . 1 , sym:: repr)
2847
+ } else if let Attribute :: Parsed ( AttributeKind :: Path ( .., span) ) = attr {
2848
+ ( * span, sym:: path)
2825
2849
} else {
2826
2850
continue ;
2827
2851
} ;
0 commit comments