@@ -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.
148153 parse_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