@@ -71,7 +71,7 @@ use crate::session_diagnostics::{
71
71
type GroupType < S > = LazyLock < GroupTypeInner < S > > ;
72
72
73
73
struct GroupTypeInner < S : Stage > {
74
- accepters : BTreeMap < & ' static [ Symbol ] , GroupTypeInnerAccept < S > > ,
74
+ accepters : BTreeMap < & ' static [ Symbol ] , Vec < GroupTypeInnerAccept < S > > > ,
75
75
finalizers : Vec < FinalizeFn < S > > ,
76
76
}
77
77
@@ -111,7 +111,7 @@ macro_rules! attribute_parsers {
111
111
@[ $stage: ty] pub ( crate ) static $name: ident = [ $( $names: ty) ,* $( , ) ?] ;
112
112
) => {
113
113
pub ( crate ) static $name: GroupType <$stage> = LazyLock :: new( || {
114
- let mut accepts = BTreeMap :: <_, GroupTypeInnerAccept <$stage>>:: new( ) ;
114
+ let mut accepts = BTreeMap :: <_, Vec < GroupTypeInnerAccept <$stage> >>:: new( ) ;
115
115
let mut finalizes = Vec :: <FinalizeFn <$stage>>:: new( ) ;
116
116
$(
117
117
{
@@ -120,17 +120,15 @@ macro_rules! attribute_parsers {
120
120
} ;
121
121
122
122
for ( path, template, accept_fn) in <$names>:: ATTRIBUTES {
123
- if accepts. insert ( * path, GroupTypeInnerAccept {
123
+ accepts. entry ( * path) . or_default ( ) . push ( GroupTypeInnerAccept {
124
124
template: * template,
125
125
accept_fn: Box :: new( |cx, args| {
126
126
STATE_OBJECT . with_borrow_mut( |s| {
127
127
accept_fn( s, cx, args)
128
128
} )
129
129
} ) ,
130
130
allowed_targets: <$names as crate :: attributes:: AttributeParser <$stage>>:: ALLOWED_TARGETS ,
131
- } ) . is_some( ) {
132
- panic!( "Found two attribute parsers for attribute {path:?}" ) ;
133
- }
131
+ } ) ;
134
132
}
135
133
136
134
finalizes. push( Box :: new( |cx| {
@@ -903,53 +901,55 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
903
901
let args = parser. args ( ) ;
904
902
let parts = path. segments ( ) . map ( |i| i. name ) . collect :: < Vec < _ > > ( ) ;
905
903
906
- if let Some ( accept) = S :: parsers ( ) . accepters . get ( parts. as_slice ( ) ) {
907
- let mut cx: AcceptContext < ' _ , ' sess , S > = AcceptContext {
908
- shared : SharedContext {
909
- cx : self ,
910
- target_span,
911
- target_id,
912
- emit_lint : & mut emit_lint,
913
- } ,
914
- attr_span : lower_span ( attr. span ) ,
915
- template : & accept. template ,
916
- attr_path : path. get_attribute_path ( ) ,
917
- } ;
918
-
919
- ( accept. accept_fn ) ( & mut cx, args) ;
920
-
921
- if self . stage . should_emit ( ) . should_emit ( ) {
922
- match accept. allowed_targets . is_allowed ( target) {
923
- AllowedResult :: Allowed => { }
924
- AllowedResult :: Warn => {
925
- let allowed_targets = accept. allowed_targets . allowed_targets ( ) ;
926
- emit_lint ( AttributeLint {
927
- id : target_id,
928
- span : attr. span ,
929
- kind : AttributeLintKind :: InvalidTarget {
904
+ if let Some ( accepts) = S :: parsers ( ) . accepters . get ( parts. as_slice ( ) ) {
905
+ for accept in accepts {
906
+ let mut cx: AcceptContext < ' _ , ' sess , S > = AcceptContext {
907
+ shared : SharedContext {
908
+ cx : self ,
909
+ target_span,
910
+ target_id,
911
+ emit_lint : & mut emit_lint,
912
+ } ,
913
+ attr_span : lower_span ( attr. span ) ,
914
+ template : & accept. template ,
915
+ attr_path : path. get_attribute_path ( ) ,
916
+ } ;
917
+
918
+ ( accept. accept_fn ) ( & mut cx, args) ;
919
+
920
+ if self . stage . should_emit ( ) . should_emit ( ) {
921
+ match accept. allowed_targets . is_allowed ( target) {
922
+ AllowedResult :: Allowed => { }
923
+ AllowedResult :: Warn => {
924
+ let allowed_targets = accept. allowed_targets . allowed_targets ( ) ;
925
+ emit_lint ( AttributeLint {
926
+ id : target_id,
927
+ span : attr. span ,
928
+ kind : AttributeLintKind :: InvalidTarget {
929
+ name : parts[ 0 ] ,
930
+ target : target. plural_name ( ) ,
931
+ only : if allowed_targets. len ( ) == 1 {
932
+ "only "
933
+ } else {
934
+ ""
935
+ } ,
936
+ applied : allowed_targets_applied (
937
+ allowed_targets,
938
+ target,
939
+ ) ,
940
+ } ,
941
+ } ) ;
942
+ }
943
+ AllowedResult :: Error => {
944
+ let allowed_targets = accept. allowed_targets . allowed_targets ( ) ;
945
+ self . dcx ( ) . emit_err ( InvalidTarget {
946
+ span : attr. span ,
930
947
name : parts[ 0 ] ,
931
948
target : target. plural_name ( ) ,
932
- only : if allowed_targets. len ( ) == 1 {
933
- "only "
934
- } else {
935
- ""
936
- } ,
937
- applied : allowed_targets_applied (
938
- allowed_targets,
939
- target,
940
- ) ,
941
- } ,
942
- } ) ;
943
- }
944
- AllowedResult :: Error => {
945
- let allowed_targets = accept. allowed_targets . allowed_targets ( ) ;
946
- self . dcx ( ) . emit_err ( InvalidTarget {
947
- span : attr. span ,
948
- name : parts[ 0 ] ,
949
- target : target. plural_name ( ) ,
950
- only : if allowed_targets. len ( ) == 1 { "only " } else { "" } ,
951
- applied : allowed_targets_applied ( allowed_targets, target) ,
952
- } ) ;
949
+ only : if allowed_targets. len ( ) == 1 { "only " } else { "" } ,
950
+ applied : allowed_targets_applied ( allowed_targets, target) ,
951
+ } ) ;
952
+ }
953
953
}
954
954
}
955
955
}
0 commit comments