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