@@ -26,24 +26,29 @@ macro_rules! attribute_groups {
26
26
(
27
27
pub ( crate ) static $name: ident = [ $( $names: ty) ,* $( , ) ?] ;
28
28
) => {
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( ) ;
35
39
$(
36
40
{
37
41
thread_local! {
38
42
static STATE_OBJECT : RefCell <$names> = RefCell :: new( <$names>:: default ( ) ) ;
39
43
} ;
40
44
41
45
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| {
43
47
STATE_OBJECT . with_borrow_mut( |s| {
44
48
v( s, cx, args)
45
49
} )
46
50
} ) ) ;
51
+ assert!( old. is_none( ) ) ;
47
52
}
48
53
49
54
finalizes. push( Box :: new( |cx| {
@@ -110,7 +115,8 @@ impl<'a> Deref for AcceptContext<'a> {
110
115
111
116
/// Context given to every attribute parser during finalization.
112
117
///
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.
114
120
pub ( crate ) struct FinalizeContext < ' a > {
115
121
/// The parse context, gives access to the session and the
116
122
/// diagnostics context.
@@ -141,10 +147,9 @@ pub struct AttributeParser<'sess> {
141
147
sess : & ' sess Session ,
142
148
features : Option < & ' sess Features > ,
143
149
144
- /// *only * parse attributes with this symbol.
150
+ /// *Only * parse attributes with this symbol.
145
151
///
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.
148
153
parse_only : Option < Symbol > ,
149
154
150
155
/// Can be used to instruct parsers to reduce the number of diagnostics it emits.
@@ -157,9 +162,9 @@ impl<'sess> AttributeParser<'sess> {
157
162
/// One example where this is necessary, is to parse `feature` attributes themselves for
158
163
/// example.
159
164
///
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).
163
168
///
164
169
/// To make sure use is limited, supply a `Symbol` you'd like to parse. Only attributes with
165
170
/// that symbol are picked out of the list of instructions and parsed. Those are returned.
@@ -217,19 +222,18 @@ impl<'sess> AttributeParser<'sess> {
217
222
let group_cx = FinalizeContext { cx : self , target_span } ;
218
223
219
224
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.
222
226
if let Some ( expected) = self . parse_only {
223
227
if !attr. has_name ( expected) {
224
228
continue ;
225
229
}
226
230
}
227
231
228
- // sometimes , for example for `#![doc = include_str!("readme.md")]`,
232
+ // Sometimes , for example for `#![doc = include_str!("readme.md")]`,
229
233
// doc still contains a non-literal. You might say, when we're lowering attributes
230
234
// that's expanded right? But no, sometimes, when parsing attributes on macros,
231
235
// 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.
233
237
if omit_doc == OmitDoc :: Skip && attr. has_name ( sym:: doc) {
234
238
continue ;
235
239
}
@@ -263,21 +267,17 @@ impl<'sess> AttributeParser<'sess> {
263
267
let ( path, args) = parser. deconstruct ( ) ;
264
268
let parts = path. segments ( ) . map ( |i| i. name ) . collect :: < Vec < _ > > ( ) ;
265
269
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 ) } ;
272
273
273
- f ( & cx, & args)
274
- }
274
+ accept ( & cx, & args)
275
275
} 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.
281
281
282
282
// FIXME(jdonszelmann): convert other attributes, and check with this that
283
283
// we caught em all
0 commit comments