@@ -71,7 +71,7 @@ use crate::session_diagnostics::{
7171type GroupType < S > = LazyLock < GroupTypeInner < S > > ;
7272
7373struct GroupTypeInner < S : Stage > {
74- accepters : BTreeMap < & ' static [ Symbol ] , GroupTypeInnerAccept < S > > ,
74+ accepters : BTreeMap < & ' static [ Symbol ] , Vec < GroupTypeInnerAccept < S > > > ,
7575 finalizers : Vec < FinalizeFn < S > > ,
7676}
7777
@@ -111,7 +111,7 @@ macro_rules! attribute_parsers {
111111 @[ $stage: ty] pub ( crate ) static $name: ident = [ $( $names: ty) ,* $( , ) ?] ;
112112 ) => {
113113 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( ) ;
115115 let mut finalizes = Vec :: <FinalizeFn <$stage>>:: new( ) ;
116116 $(
117117 {
@@ -120,17 +120,15 @@ macro_rules! attribute_parsers {
120120 } ;
121121
122122 for ( path, template, accept_fn) in <$names>:: ATTRIBUTES {
123- if accepts. insert ( * path, GroupTypeInnerAccept {
123+ accepts. entry ( * path) . or_default ( ) . push ( GroupTypeInnerAccept {
124124 template: * template,
125125 accept_fn: Box :: new( |cx, args| {
126126 STATE_OBJECT . with_borrow_mut( |s| {
127127 accept_fn( s, cx, args)
128128 } )
129129 } ) ,
130130 allowed_targets: <$names as crate :: attributes:: AttributeParser <$stage>>:: ALLOWED_TARGETS ,
131- } ) . is_some( ) {
132- panic!( "Found two attribute parsers for attribute {path:?}" ) ;
133- }
131+ } ) ;
134132 }
135133
136134 finalizes. push( Box :: new( |cx| {
@@ -903,53 +901,55 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
903901 let args = parser. args ( ) ;
904902 let parts = path. segments ( ) . map ( |i| i. name ) . collect :: < Vec < _ > > ( ) ;
905903
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 ,
930947 name : parts[ 0 ] ,
931948 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+ }
953953 }
954954 }
955955 }
0 commit comments