@@ -26,7 +26,7 @@ use crate::attributes::stability::{
26
26
} ;
27
27
use crate :: attributes:: transparency:: TransparencyParser ;
28
28
use crate :: attributes:: { AttributeParser as _, Combine , Single } ;
29
- use crate :: parser:: { ArgParser , MetaItemParser } ;
29
+ use crate :: parser:: { ArgParser , MetaItemParser , PathParser } ;
30
30
use crate :: session_diagnostics:: { AttributeParseError , AttributeParseErrorReason , UnknownMetaItem } ;
31
31
32
32
macro_rules! group_type {
@@ -94,6 +94,7 @@ attribute_parsers!(
94
94
BodyStabilityParser ,
95
95
ConfusablesParser ,
96
96
ConstStabilityParser ,
97
+ NakedParser ,
97
98
StabilityParser ,
98
99
// tidy-alphabetical-end
99
100
@@ -109,7 +110,6 @@ attribute_parsers!(
109
110
Single <ConstStabilityIndirectParser >,
110
111
Single <DeprecationParser >,
111
112
Single <InlineParser >,
112
- Single <NakedParser >,
113
113
Single <OptimizeParser >,
114
114
Single <RustcForceInlineParser >,
115
115
Single <TransparencyParser >,
@@ -168,7 +168,7 @@ pub struct Late;
168
168
///
169
169
/// Gives [`AttributeParser`]s enough information to create errors, for example.
170
170
pub ( crate ) struct AcceptContext < ' f , ' sess , S : Stage > {
171
- pub ( crate ) finalize_cx : FinalizeContext < ' f , ' sess , S > ,
171
+ pub ( crate ) shared : SharedContext < ' f , ' sess , S > ,
172
172
/// The span of the attribute currently being parsed
173
173
pub ( crate ) attr_span : Span ,
174
174
@@ -181,7 +181,7 @@ pub(crate) struct AcceptContext<'f, 'sess, S: Stage> {
181
181
pub ( crate ) attr_path : AttrPath ,
182
182
}
183
183
184
- impl < ' f , ' sess : ' f , S : Stage > AcceptContext < ' f , ' sess , S > {
184
+ impl < ' f , ' sess : ' f , S : Stage > SharedContext < ' f , ' sess , S > {
185
185
pub ( crate ) fn emit_err ( & self , diag : impl for < ' x > Diagnostic < ' x > ) -> ErrorGuaranteed {
186
186
S :: emit_err ( & self . sess , diag)
187
187
}
@@ -219,7 +219,9 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
219
219
unused_span,
220
220
)
221
221
}
222
+ }
222
223
224
+ impl < ' f , ' sess : ' f , S : Stage > AcceptContext < ' f , ' sess , S > {
223
225
pub ( crate ) fn unknown_key (
224
226
& self ,
225
227
span : Span ,
@@ -352,24 +354,24 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
352
354
}
353
355
354
356
impl < ' f , ' sess , S : Stage > Deref for AcceptContext < ' f , ' sess , S > {
355
- type Target = FinalizeContext < ' f , ' sess , S > ;
357
+ type Target = SharedContext < ' f , ' sess , S > ;
356
358
357
359
fn deref ( & self ) -> & Self :: Target {
358
- & self . finalize_cx
360
+ & self . shared
359
361
}
360
362
}
361
363
362
364
impl < ' f , ' sess , S : Stage > DerefMut for AcceptContext < ' f , ' sess , S > {
363
365
fn deref_mut ( & mut self ) -> & mut Self :: Target {
364
- & mut self . finalize_cx
366
+ & mut self . shared
365
367
}
366
368
}
367
369
368
370
/// Context given to every attribute parser during finalization.
369
371
///
370
372
/// Gives [`AttributeParser`](crate::attributes::AttributeParser)s enough information to create
371
373
/// errors, for example.
372
- pub ( crate ) struct FinalizeContext < ' p , ' sess , S : Stage > {
374
+ pub ( crate ) struct SharedContext < ' p , ' sess , S : Stage > {
373
375
/// The parse context, gives access to the session and the
374
376
/// diagnostics context.
375
377
pub ( crate ) cx : & ' p mut AttributeParser < ' sess , S > ,
@@ -378,18 +380,48 @@ pub(crate) struct FinalizeContext<'p, 'sess, S: Stage> {
378
380
/// The id ([`NodeId`] if `S` is `Early`, [`HirId`] if `S` is `Late`) of the syntactical component this attribute was applied to
379
381
pub ( crate ) target_id : S :: Id ,
380
382
381
- pub ( crate ) emit_lint : & ' p mut dyn FnMut ( AttributeLint < S :: Id > ) ,
383
+ emit_lint : & ' p mut dyn FnMut ( AttributeLint < S :: Id > ) ,
384
+ }
385
+
386
+ /// Context given to every attribute parser during finalization.
387
+ ///
388
+ /// Gives [`AttributeParser`](crate::attributes::AttributeParser)s enough information to create
389
+ /// errors, for example.
390
+ pub ( crate ) struct FinalizeContext < ' p , ' sess , S : Stage > {
391
+ pub ( crate ) shared : SharedContext < ' p , ' sess , S > ,
392
+
393
+ /// A list of all attribute on this syntax node.
394
+ ///
395
+ /// Useful for allowlists in finalize.
396
+ ///
397
+ /// Usually, you should use normal attribute parsing logic instead,
398
+ /// especially when making a *denylist* of other attributes.
399
+ pub ( crate ) all_attrs : & ' p [ PathParser < ' p > ] ,
382
400
}
383
401
384
402
impl < ' p , ' sess : ' p , S : Stage > Deref for FinalizeContext < ' p , ' sess , S > {
403
+ type Target = SharedContext < ' p , ' sess , S > ;
404
+
405
+ fn deref ( & self ) -> & Self :: Target {
406
+ & self . shared
407
+ }
408
+ }
409
+
410
+ impl < ' p , ' sess : ' p , S : Stage > DerefMut for FinalizeContext < ' p , ' sess , S > {
411
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
412
+ & mut self . shared
413
+ }
414
+ }
415
+
416
+ impl < ' p , ' sess : ' p , S : Stage > Deref for SharedContext < ' p , ' sess , S > {
385
417
type Target = AttributeParser < ' sess , S > ;
386
418
387
419
fn deref ( & self ) -> & Self :: Target {
388
420
self . cx
389
421
}
390
422
}
391
423
392
- impl < ' p , ' sess : ' p , S : Stage > DerefMut for FinalizeContext < ' p , ' sess , S > {
424
+ impl < ' p , ' sess : ' p , S : Stage > DerefMut for SharedContext < ' p , ' sess , S > {
393
425
fn deref_mut ( & mut self ) -> & mut Self :: Target {
394
426
self . cx
395
427
}
@@ -499,6 +531,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
499
531
mut emit_lint : impl FnMut ( AttributeLint < S :: Id > ) ,
500
532
) -> Vec < Attribute > {
501
533
let mut attributes = Vec :: new ( ) ;
534
+ let mut attr_paths = Vec :: new ( ) ;
502
535
503
536
for attr in attrs {
504
537
// If we're only looking for a single attribute, skip all the ones we don't care about.
@@ -542,6 +575,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
542
575
// }))
543
576
// }
544
577
ast:: AttrKind :: Normal ( n) => {
578
+ attr_paths. push ( PathParser :: Ast ( & n. item . path ) ) ;
579
+
545
580
let parser = MetaItemParser :: from_attr ( n, self . dcx ( ) ) ;
546
581
let path = parser. path ( ) ;
547
582
let args = parser. args ( ) ;
@@ -550,7 +585,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
550
585
if let Some ( accepts) = S :: parsers ( ) . 0 . get ( parts. as_slice ( ) ) {
551
586
for ( template, accept) in accepts {
552
587
let mut cx: AcceptContext < ' _ , ' sess , S > = AcceptContext {
553
- finalize_cx : FinalizeContext {
588
+ shared : SharedContext {
554
589
cx : self ,
555
590
target_span,
556
591
target_id,
@@ -594,10 +629,13 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
594
629
let mut parsed_attributes = Vec :: new ( ) ;
595
630
for f in & S :: parsers ( ) . 1 {
596
631
if let Some ( attr) = f ( & mut FinalizeContext {
597
- cx : self ,
598
- target_span,
599
- target_id,
600
- emit_lint : & mut emit_lint,
632
+ shared : SharedContext {
633
+ cx : self ,
634
+ target_span,
635
+ target_id,
636
+ emit_lint : & mut emit_lint,
637
+ } ,
638
+ all_attrs : & attr_paths,
601
639
} ) {
602
640
parsed_attributes. push ( Attribute :: Parsed ( attr) ) ;
603
641
}
0 commit comments