1- use rustc_ast:: MetaItem ;
2- use rustc_expand:: base:: ExtCtxt ;
1+ use rustc_ast:: { Attribute , MetaItem } ;
2+ use rustc_expand:: base:: { Annotatable , ExtCtxt } ;
33use rustc_feature:: AttributeTemplate ;
4+ use rustc_lint_defs:: builtin:: DUPLICATE_MACRO_ATTRIBUTES ;
45use rustc_parse:: validate_attr;
56use rustc_span:: Symbol ;
67
@@ -10,3 +11,33 @@ pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, na
1011 let attr = ecx. attribute ( meta_item. clone ( ) ) ;
1112 validate_attr:: check_builtin_attribute ( & ecx. sess . parse_sess , & attr, name, template) ;
1213}
14+
15+ /// Emit a warning if the item is annotated with the given attribute. This is used to diagnose when
16+ /// an attribute may have been mistakenly duplicated.
17+ pub fn warn_on_duplicate_attribute ( ecx : & ExtCtxt < ' _ > , item : & Annotatable , name : Symbol ) {
18+ let attrs: Option < & [ Attribute ] > = match item {
19+ Annotatable :: Item ( item) => Some ( & item. attrs ) ,
20+ Annotatable :: TraitItem ( item) => Some ( & item. attrs ) ,
21+ Annotatable :: ImplItem ( item) => Some ( & item. attrs ) ,
22+ Annotatable :: ForeignItem ( item) => Some ( & item. attrs ) ,
23+ Annotatable :: Expr ( expr) => Some ( & expr. attrs ) ,
24+ Annotatable :: Arm ( arm) => Some ( & arm. attrs ) ,
25+ Annotatable :: ExprField ( field) => Some ( & field. attrs ) ,
26+ Annotatable :: PatField ( field) => Some ( & field. attrs ) ,
27+ Annotatable :: GenericParam ( param) => Some ( & param. attrs ) ,
28+ Annotatable :: Param ( param) => Some ( & param. attrs ) ,
29+ Annotatable :: FieldDef ( def) => Some ( & def. attrs ) ,
30+ Annotatable :: Variant ( variant) => Some ( & variant. attrs ) ,
31+ _ => None ,
32+ } ;
33+ if let Some ( attrs) = attrs {
34+ if let Some ( attr) = ecx. sess . find_by_name ( attrs, name) {
35+ ecx. parse_sess ( ) . buffer_lint (
36+ DUPLICATE_MACRO_ATTRIBUTES ,
37+ attr. span ,
38+ ecx. current_expansion . lint_node_id ,
39+ "duplicated attribute" ,
40+ ) ;
41+ }
42+ }
43+ }
0 commit comments