@@ -27,7 +27,7 @@ use crate::attributes::stability::{
27
27
} ;
28
28
use crate :: attributes:: transparency:: TransparencyParser ;
29
29
use crate :: attributes:: { AttributeParser as _, Combine , Single } ;
30
- use crate :: parser:: { ArgParser , MetaItemParser } ;
30
+ use crate :: parser:: { ArgParser , MetaItemParser , PathParser } ;
31
31
use crate :: session_diagnostics:: { AttributeParseError , AttributeParseErrorReason , UnknownMetaItem } ;
32
32
33
33
macro_rules! group_type {
@@ -96,6 +96,7 @@ attribute_parsers!(
96
96
BodyStabilityParser ,
97
97
ConfusablesParser ,
98
98
ConstStabilityParser ,
99
+ NakedParser ,
99
100
StabilityParser ,
100
101
// tidy-alphabetical-end
101
102
@@ -112,7 +113,6 @@ attribute_parsers!(
112
113
Single <DeprecationParser >,
113
114
Single <InlineParser >,
114
115
Single <MayDangleParser >,
115
- Single <NakedParser >,
116
116
Single <OptimizeParser >,
117
117
Single <RustcForceInlineParser >,
118
118
Single <TransparencyParser >,
@@ -171,7 +171,7 @@ pub struct Late;
171
171
///
172
172
/// Gives [`AttributeParser`]s enough information to create errors, for example.
173
173
pub ( crate ) struct AcceptContext < ' f , ' sess , S : Stage > {
174
- pub ( crate ) finalize_cx : FinalizeContext < ' f , ' sess , S > ,
174
+ pub ( crate ) shared : SharedContext < ' f , ' sess , S > ,
175
175
/// The span of the attribute currently being parsed
176
176
pub ( crate ) attr_span : Span ,
177
177
@@ -184,7 +184,7 @@ pub(crate) struct AcceptContext<'f, 'sess, S: Stage> {
184
184
pub ( crate ) attr_path : AttrPath ,
185
185
}
186
186
187
- impl < ' f , ' sess : ' f , S : Stage > AcceptContext < ' f , ' sess , S > {
187
+ impl < ' f , ' sess : ' f , S : Stage > SharedContext < ' f , ' sess , S > {
188
188
pub ( crate ) fn emit_err ( & self , diag : impl for < ' x > Diagnostic < ' x > ) -> ErrorGuaranteed {
189
189
S :: emit_err ( & self . sess , diag)
190
190
}
@@ -222,7 +222,9 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
222
222
unused_span,
223
223
)
224
224
}
225
+ }
225
226
227
+ impl < ' f , ' sess : ' f , S : Stage > AcceptContext < ' f , ' sess , S > {
226
228
pub ( crate ) fn unknown_key (
227
229
& self ,
228
230
span : Span ,
@@ -355,24 +357,24 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
355
357
}
356
358
357
359
impl < ' f , ' sess , S : Stage > Deref for AcceptContext < ' f , ' sess , S > {
358
- type Target = FinalizeContext < ' f , ' sess , S > ;
360
+ type Target = SharedContext < ' f , ' sess , S > ;
359
361
360
362
fn deref ( & self ) -> & Self :: Target {
361
- & self . finalize_cx
363
+ & self . shared
362
364
}
363
365
}
364
366
365
367
impl < ' f , ' sess , S : Stage > DerefMut for AcceptContext < ' f , ' sess , S > {
366
368
fn deref_mut ( & mut self ) -> & mut Self :: Target {
367
- & mut self . finalize_cx
369
+ & mut self . shared
368
370
}
369
371
}
370
372
371
373
/// Context given to every attribute parser during finalization.
372
374
///
373
375
/// Gives [`AttributeParser`](crate::attributes::AttributeParser)s enough information to create
374
376
/// errors, for example.
375
- pub ( crate ) struct FinalizeContext < ' p , ' sess , S : Stage > {
377
+ pub ( crate ) struct SharedContext < ' p , ' sess , S : Stage > {
376
378
/// The parse context, gives access to the session and the
377
379
/// diagnostics context.
378
380
pub ( crate ) cx : & ' p mut AttributeParser < ' sess , S > ,
@@ -381,18 +383,48 @@ pub(crate) struct FinalizeContext<'p, 'sess, S: Stage> {
381
383
/// The id ([`NodeId`] if `S` is `Early`, [`HirId`] if `S` is `Late`) of the syntactical component this attribute was applied to
382
384
pub ( crate ) target_id : S :: Id ,
383
385
384
- pub ( crate ) emit_lint : & ' p mut dyn FnMut ( AttributeLint < S :: Id > ) ,
386
+ emit_lint : & ' p mut dyn FnMut ( AttributeLint < S :: Id > ) ,
387
+ }
388
+
389
+ /// Context given to every attribute parser during finalization.
390
+ ///
391
+ /// Gives [`AttributeParser`](crate::attributes::AttributeParser)s enough information to create
392
+ /// errors, for example.
393
+ pub ( crate ) struct FinalizeContext < ' p , ' sess , S : Stage > {
394
+ pub ( crate ) shared : SharedContext < ' p , ' sess , S > ,
395
+
396
+ /// A list of all attribute on this syntax node.
397
+ ///
398
+ /// Useful for compatibility checks with other attributes in [`finalize`](crate::attributes::AttributeParser::finalize)
399
+ ///
400
+ /// Usually, you should use normal attribute parsing logic instead,
401
+ /// especially when making a *denylist* of other attributes.
402
+ pub ( crate ) all_attrs : & ' p [ PathParser < ' p > ] ,
385
403
}
386
404
387
405
impl < ' p , ' sess : ' p , S : Stage > Deref for FinalizeContext < ' p , ' sess , S > {
406
+ type Target = SharedContext < ' p , ' sess , S > ;
407
+
408
+ fn deref ( & self ) -> & Self :: Target {
409
+ & self . shared
410
+ }
411
+ }
412
+
413
+ impl < ' p , ' sess : ' p , S : Stage > DerefMut for FinalizeContext < ' p , ' sess , S > {
414
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
415
+ & mut self . shared
416
+ }
417
+ }
418
+
419
+ impl < ' p , ' sess : ' p , S : Stage > Deref for SharedContext < ' p , ' sess , S > {
388
420
type Target = AttributeParser < ' sess , S > ;
389
421
390
422
fn deref ( & self ) -> & Self :: Target {
391
423
self . cx
392
424
}
393
425
}
394
426
395
- impl < ' p , ' sess : ' p , S : Stage > DerefMut for FinalizeContext < ' p , ' sess , S > {
427
+ impl < ' p , ' sess : ' p , S : Stage > DerefMut for SharedContext < ' p , ' sess , S > {
396
428
fn deref_mut ( & mut self ) -> & mut Self :: Target {
397
429
self . cx
398
430
}
@@ -407,8 +439,7 @@ pub enum OmitDoc {
407
439
/// Context created once, for example as part of the ast lowering
408
440
/// context, through which all attributes can be lowered.
409
441
pub struct AttributeParser < ' sess , S : Stage = Late > {
410
- #[ expect( dead_code) ] // FIXME(jdonszelmann): needed later to verify we parsed all attributes
411
- tools : Vec < Symbol > ,
442
+ pub ( crate ) tools : Vec < Symbol > ,
412
443
features : Option < & ' sess Features > ,
413
444
sess : & ' sess Session ,
414
445
stage : PhantomData < S > ,
@@ -496,6 +527,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
496
527
mut emit_lint : impl FnMut ( AttributeLint < S :: Id > ) ,
497
528
) -> Vec < Attribute > {
498
529
let mut attributes = Vec :: new ( ) ;
530
+ let mut attr_paths = Vec :: new ( ) ;
499
531
500
532
for attr in attrs {
501
533
// If we're only looking for a single attribute, skip all the ones we don't care about.
@@ -539,6 +571,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
539
571
// }))
540
572
// }
541
573
ast:: AttrKind :: Normal ( n) => {
574
+ attr_paths. push ( PathParser :: Ast ( & n. item . path ) ) ;
575
+
542
576
let parser = MetaItemParser :: from_attr ( n, self . dcx ( ) ) ;
543
577
let path = parser. path ( ) ;
544
578
let args = parser. args ( ) ;
@@ -547,7 +581,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
547
581
if let Some ( accepts) = S :: parsers ( ) . 0 . get ( parts. as_slice ( ) ) {
548
582
for ( template, accept) in accepts {
549
583
let mut cx: AcceptContext < ' _ , ' sess , S > = AcceptContext {
550
- finalize_cx : FinalizeContext {
584
+ shared : SharedContext {
551
585
cx : self ,
552
586
target_span,
553
587
target_id,
@@ -591,10 +625,13 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
591
625
let mut parsed_attributes = Vec :: new ( ) ;
592
626
for f in & S :: parsers ( ) . 1 {
593
627
if let Some ( attr) = f ( & mut FinalizeContext {
594
- cx : self ,
595
- target_span,
596
- target_id,
597
- emit_lint : & mut emit_lint,
628
+ shared : SharedContext {
629
+ cx : self ,
630
+ target_span,
631
+ target_id,
632
+ emit_lint : & mut emit_lint,
633
+ } ,
634
+ all_attrs : & attr_paths,
598
635
} ) {
599
636
parsed_attributes. push ( Attribute :: Parsed ( attr) ) ;
600
637
}
0 commit comments