@@ -26,24 +26,29 @@ macro_rules! attribute_groups {
2626    ( 
2727        pub ( crate )  static  $name:  ident = [ $( $names:  ty) ,*  $( , ) ?] ; 
2828    )  => { 
29-         pub ( crate )  static  $name:  LazyLock <( 
30-             BTreeMap <& ' static  [ Symbol ] ,  Vec <Box <dyn Fn ( & AcceptContext <' _>,  & ArgParser <' _>)  + Send  + Sync >>>, 
31-             Vec <Box <dyn Send  + Sync  + Fn ( & FinalizeContext <' _>)  -> Option <AttributeKind >>>
32-         ) > = LazyLock :: new( || { 
33-             let  mut  accepts = BTreeMap :: <_,  Vec <Box <dyn Fn ( & AcceptContext <' _>,  & ArgParser <' _>)  + Send  + Sync >>>:: new( ) ; 
34-             let  mut  finalizes = Vec :: <Box <dyn Send  + Sync  + Fn ( & FinalizeContext <' _>)  -> Option <AttributeKind >>>:: new( ) ; 
29+         type  Accepts  = BTreeMap <
30+             & ' static  [ Symbol ] , 
31+             Box <dyn Send  + Sync  + Fn ( & AcceptContext <' _>,  & ArgParser <' _>) >
32+         >; 
33+         type  Finalizes  = Vec <
34+             Box <dyn Send  + Sync  + Fn ( & FinalizeContext <' _>)  -> Option <AttributeKind >>
35+         >; 
36+         pub ( crate )  static  $name:  LazyLock <( Accepts ,  Finalizes ) > = LazyLock :: new( || { 
37+             let  mut  accepts = Accepts :: new( ) ; 
38+             let  mut  finalizes = Finalizes :: new( ) ; 
3539            $( 
3640                { 
3741                    thread_local! { 
3842                        static  STATE_OBJECT :  RefCell <$names> = RefCell :: new( <$names>:: default ( ) ) ; 
3943                    } ; 
4044
4145                    for  ( k,  v)  in <$names>:: ATTRIBUTES  { 
42-                         accepts. entry ( * k) . or_default ( ) . push ( Box :: new( |cx,  args| { 
46+                         let  old =  accepts. insert ( * k,   Box :: new( |cx,  args| { 
4347                            STATE_OBJECT . with_borrow_mut( |s| { 
4448                                v( s,  cx,  args) 
4549                            } ) 
4650                        } ) ) ; 
51+                         assert!( old. is_none( ) ) ; 
4752                    } 
4853
4954                    finalizes. push( Box :: new( |cx| { 
@@ -110,7 +115,8 @@ impl<'a> Deref for AcceptContext<'a> {
110115
111116/// Context given to every attribute parser during finalization. 
112117/// 
113- /// Gives [`AttributeParser`](crate::attributes::AttributeParser)s enough information to create errors, for example. 
118+ /// Gives [`AttributeParser`](crate::attributes::AttributeParser)s enough information to create 
119+ /// errors, for example. 
114120pub ( crate )  struct  FinalizeContext < ' a >  { 
115121    /// The parse context, gives access to the session and the 
116122/// diagnostics context. 
@@ -141,10 +147,9 @@ pub struct AttributeParser<'sess> {
141147    sess :  & ' sess  Session , 
142148    features :  Option < & ' sess  Features > , 
143149
144-     /// *only * parse attributes with this symbol. 
150+     /// *Only * parse attributes with this symbol. 
145151/// 
146- /// Used in cases where we want the lowering infrastructure for 
147- /// parse just a single attribute. 
152+ /// Used in cases where we want the lowering infrastructure for parse just a single attribute. 
148153parse_only :  Option < Symbol > , 
149154
150155    /// Can be used to instruct parsers to reduce the number of diagnostics it emits. 
@@ -157,9 +162,9 @@ impl<'sess> AttributeParser<'sess> {
157162/// One example where this is necessary, is to parse `feature` attributes themselves for 
158163/// example. 
159164/// 
160- /// Try to use this as little as possible. Attributes *should* be lowered during `rustc_ast_lowering`.  
161- /// Some attributes require access to features to parse, which would crash if you tried to do so  
162- /// through [`parse_limited`](Self::parse_limited). 
165+ /// Try to use this as little as possible. Attributes *should* be lowered during 
166+ /// `rustc_ast_lowering`.  Some attributes require access to features to parse, which would 
167+ /// crash if you tried to do so  through [`parse_limited`](Self::parse_limited). 
163168/// 
164169/// To make sure use is limited, supply a `Symbol` you'd like to parse. Only attributes with 
165170/// that symbol are picked out of the list of instructions and parsed. Those are returned. 
@@ -217,19 +222,18 @@ impl<'sess> AttributeParser<'sess> {
217222        let  group_cx = FinalizeContext  {  cx :  self ,  target_span } ; 
218223
219224        for  attr in  attrs { 
220-             // if we're only looking for a single attribute, 
221-             // skip all the ones we don't care about 
225+             // If we're only looking for a single attribute, skip all the ones we don't care about. 
222226            if  let  Some ( expected)  = self . parse_only  { 
223227                if  !attr. has_name ( expected)  { 
224228                    continue ; 
225229                } 
226230            } 
227231
228-             // sometimes , for example for `#![doc = include_str!("readme.md")]`, 
232+             // Sometimes , for example for `#![doc = include_str!("readme.md")]`, 
229233            // doc still contains a non-literal. You might say, when we're lowering attributes 
230234            // that's expanded right? But no, sometimes, when parsing attributes on macros, 
231235            // we already use the lowering logic and these are still there. So, when `omit_doc` 
232-             // is set we *also* want to ignore these 
236+             // is set we *also* want to ignore these.  
233237            if  omit_doc == OmitDoc :: Skip  && attr. has_name ( sym:: doc)  { 
234238                continue ; 
235239            } 
@@ -263,21 +267,17 @@ impl<'sess> AttributeParser<'sess> {
263267                    let  ( path,  args)  = parser. deconstruct ( ) ; 
264268                    let  parts = path. segments ( ) . map ( |i| i. name ) . collect :: < Vec < _ > > ( ) ; 
265269
266-                     if  let  Some ( accepts)  = ATTRIBUTE_MAPPING . 0 . get ( parts. as_slice ( ) )  { 
267-                         for  f in  accepts { 
268-                             let  cx = AcceptContext  { 
269-                                 group_cx :  & group_cx, 
270-                                 attr_span :  lower_span ( attr. span ) , 
271-                             } ; 
270+                     if  let  Some ( accept)  = ATTRIBUTE_MAPPING . 0 . get ( parts. as_slice ( ) )  { 
271+                         let  cx =
272+                             AcceptContext  {  group_cx :  & group_cx,  attr_span :  lower_span ( attr. span )  } ; 
272273
273-                             f ( & cx,  & args) 
274-                         } 
274+                         accept ( & cx,  & args) 
275275                    }  else  { 
276-                         // if  we're here, we must be compiling a tool attribute... Or someone forgot to  
277-                         // parse their fancy new attribute. Let's warn them in any case. If you are that  
278-                         // person, and you really your attribute should remain unparsed, carefully read the  
279-                         // documentation in this module and if you still think so you can add an exception  
280-                         // to this assertion. 
276+                         // If  we're here, we must be compiling a tool attribute... Or someone 
277+                         // forgot to  parse their fancy new attribute. Let's warn them in any case. 
278+                         // If you are that  person, and you really think  your attribute should 
279+                         // remain unparsed, carefully read the  documentation in this module and if 
280+                         // you still think so you can add an exception  to this assertion. 
281281
282282                        // FIXME(jdonszelmann): convert other attributes, and check with this that 
283283                        // we caught em all 
0 commit comments