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