@@ -26,7 +26,7 @@ use crate::attributes::stability::{
2626} ;
2727use crate :: attributes:: transparency:: TransparencyParser ;
2828use crate :: attributes:: { AttributeParser as _, Combine , Single } ;
29- use crate :: parser:: { ArgParser , MetaItemParser } ;
29+ use crate :: parser:: { ArgParser , MetaItemParser , PathParser } ;
3030use crate :: session_diagnostics:: { AttributeParseError , AttributeParseErrorReason , UnknownMetaItem } ;
3131
3232macro_rules! group_type {
@@ -95,6 +95,7 @@ attribute_parsers!(
9595 BodyStabilityParser ,
9696 ConfusablesParser ,
9797 ConstStabilityParser ,
98+ NakedParser ,
9899 StabilityParser ,
99100 // tidy-alphabetical-end
100101
@@ -110,7 +111,6 @@ attribute_parsers!(
110111 Single <ConstStabilityIndirectParser >,
111112 Single <DeprecationParser >,
112113 Single <InlineParser >,
113- Single <NakedParser >,
114114 Single <OptimizeParser >,
115115 Single <RustcForceInlineParser >,
116116 Single <TransparencyParser >,
@@ -169,7 +169,7 @@ pub struct Late;
169169///
170170/// Gives [`AttributeParser`]s enough information to create errors, for example.
171171pub ( crate ) struct AcceptContext < ' f , ' sess , S : Stage > {
172- pub ( crate ) finalize_cx : FinalizeContext < ' f , ' sess , S > ,
172+ pub ( crate ) shared : SharedContext < ' f , ' sess , S > ,
173173 /// The span of the attribute currently being parsed
174174 pub ( crate ) attr_span : Span ,
175175
@@ -182,7 +182,7 @@ pub(crate) struct AcceptContext<'f, 'sess, S: Stage> {
182182 pub ( crate ) attr_path : AttrPath ,
183183}
184184
185- impl < ' f , ' sess : ' f , S : Stage > AcceptContext < ' f , ' sess , S > {
185+ impl < ' f , ' sess : ' f , S : Stage > SharedContext < ' f , ' sess , S > {
186186 pub ( crate ) fn emit_err ( & self , diag : impl for < ' x > Diagnostic < ' x > ) -> ErrorGuaranteed {
187187 S :: emit_err ( & self . sess , diag)
188188 }
@@ -220,7 +220,9 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
220220 unused_span,
221221 )
222222 }
223+ }
223224
225+ impl < ' f , ' sess : ' f , S : Stage > AcceptContext < ' f , ' sess , S > {
224226 pub ( crate ) fn unknown_key (
225227 & self ,
226228 span : Span ,
@@ -353,24 +355,24 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
353355}
354356
355357impl < ' f , ' sess , S : Stage > Deref for AcceptContext < ' f , ' sess , S > {
356- type Target = FinalizeContext < ' f , ' sess , S > ;
358+ type Target = SharedContext < ' f , ' sess , S > ;
357359
358360 fn deref ( & self ) -> & Self :: Target {
359- & self . finalize_cx
361+ & self . shared
360362 }
361363}
362364
363365impl < ' f , ' sess , S : Stage > DerefMut for AcceptContext < ' f , ' sess , S > {
364366 fn deref_mut ( & mut self ) -> & mut Self :: Target {
365- & mut self . finalize_cx
367+ & mut self . shared
366368 }
367369}
368370
369371/// Context given to every attribute parser during finalization.
370372///
371373/// Gives [`AttributeParser`](crate::attributes::AttributeParser)s enough information to create
372374/// errors, for example.
373- pub ( crate ) struct FinalizeContext < ' p , ' sess , S : Stage > {
375+ pub ( crate ) struct SharedContext < ' p , ' sess , S : Stage > {
374376 /// The parse context, gives access to the session and the
375377 /// diagnostics context.
376378 pub ( crate ) cx : & ' p mut AttributeParser < ' sess , S > ,
@@ -379,18 +381,48 @@ pub(crate) struct FinalizeContext<'p, 'sess, S: Stage> {
379381 /// The id ([`NodeId`] if `S` is `Early`, [`HirId`] if `S` is `Late`) of the syntactical component this attribute was applied to
380382 pub ( crate ) target_id : S :: Id ,
381383
382- pub ( crate ) emit_lint : & ' p mut dyn FnMut ( AttributeLint < S :: Id > ) ,
384+ emit_lint : & ' p mut dyn FnMut ( AttributeLint < S :: Id > ) ,
385+ }
386+
387+ /// Context given to every attribute parser during finalization.
388+ ///
389+ /// Gives [`AttributeParser`](crate::attributes::AttributeParser)s enough information to create
390+ /// errors, for example.
391+ pub ( crate ) struct FinalizeContext < ' p , ' sess , S : Stage > {
392+ pub ( crate ) shared : SharedContext < ' p , ' sess , S > ,
393+
394+ /// A list of all attribute on this syntax node.
395+ ///
396+ /// Useful for allowlists in finalize.
397+ ///
398+ /// Usually, you should use normal attribute parsing logic instead,
399+ /// especially when making a *denylist* of other attributes.
400+ pub ( crate ) all_attrs : & ' p [ PathParser < ' p > ] ,
383401}
384402
385403impl < ' p , ' sess : ' p , S : Stage > Deref for FinalizeContext < ' p , ' sess , S > {
404+ type Target = SharedContext < ' p , ' sess , S > ;
405+
406+ fn deref ( & self ) -> & Self :: Target {
407+ & self . shared
408+ }
409+ }
410+
411+ impl < ' p , ' sess : ' p , S : Stage > DerefMut for FinalizeContext < ' p , ' sess , S > {
412+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
413+ & mut self . shared
414+ }
415+ }
416+
417+ impl < ' p , ' sess : ' p , S : Stage > Deref for SharedContext < ' p , ' sess , S > {
386418 type Target = AttributeParser < ' sess , S > ;
387419
388420 fn deref ( & self ) -> & Self :: Target {
389421 self . cx
390422 }
391423}
392424
393- impl < ' p , ' sess : ' p , S : Stage > DerefMut for FinalizeContext < ' p , ' sess , S > {
425+ impl < ' p , ' sess : ' p , S : Stage > DerefMut for SharedContext < ' p , ' sess , S > {
394426 fn deref_mut ( & mut self ) -> & mut Self :: Target {
395427 self . cx
396428 }
@@ -500,6 +532,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
500532 mut emit_lint : impl FnMut ( AttributeLint < S :: Id > ) ,
501533 ) -> Vec < Attribute > {
502534 let mut attributes = Vec :: new ( ) ;
535+ let mut attr_paths = Vec :: new ( ) ;
503536
504537 for attr in attrs {
505538 // If we're only looking for a single attribute, skip all the ones we don't care about.
@@ -543,6 +576,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
543576 // }))
544577 // }
545578 ast:: AttrKind :: Normal ( n) => {
579+ attr_paths. push ( PathParser :: Ast ( & n. item . path ) ) ;
580+
546581 let parser = MetaItemParser :: from_attr ( n, self . dcx ( ) ) ;
547582 let path = parser. path ( ) ;
548583 let args = parser. args ( ) ;
@@ -551,7 +586,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
551586 if let Some ( accepts) = S :: parsers ( ) . 0 . get ( parts. as_slice ( ) ) {
552587 for ( template, accept) in accepts {
553588 let mut cx: AcceptContext < ' _ , ' sess , S > = AcceptContext {
554- finalize_cx : FinalizeContext {
589+ shared : SharedContext {
555590 cx : self ,
556591 target_span,
557592 target_id,
@@ -595,10 +630,13 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
595630 let mut parsed_attributes = Vec :: new ( ) ;
596631 for f in & S :: parsers ( ) . 1 {
597632 if let Some ( attr) = f ( & mut FinalizeContext {
598- cx : self ,
599- target_span,
600- target_id,
601- emit_lint : & mut emit_lint,
633+ shared : SharedContext {
634+ cx : self ,
635+ target_span,
636+ target_id,
637+ emit_lint : & mut emit_lint,
638+ } ,
639+ all_attrs : & attr_paths,
602640 } ) {
603641 parsed_attributes. push ( Attribute :: Parsed ( attr) ) ;
604642 }
0 commit comments