@@ -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 {
@@ -94,6 +94,7 @@ attribute_parsers!(
9494 BodyStabilityParser ,
9595 ConfusablesParser ,
9696 ConstStabilityParser ,
97+ NakedParser ,
9798 StabilityParser ,
9899 // tidy-alphabetical-end
99100
@@ -109,7 +110,6 @@ attribute_parsers!(
109110 Single <ConstStabilityIndirectParser >,
110111 Single <DeprecationParser >,
111112 Single <InlineParser >,
112- Single <NakedParser >,
113113 Single <OptimizeParser >,
114114 Single <RustcForceInlineParser >,
115115 Single <TransparencyParser >,
@@ -168,7 +168,7 @@ pub struct Late;
168168///
169169/// Gives [`AttributeParser`]s enough information to create errors, for example.
170170pub ( crate ) struct AcceptContext < ' f , ' sess , S : Stage > {
171- pub ( crate ) finalize_cx : FinalizeContext < ' f , ' sess , S > ,
171+ pub ( crate ) shared : SharedContext < ' f , ' sess , S > ,
172172 /// The span of the attribute currently being parsed
173173 pub ( crate ) attr_span : Span ,
174174
@@ -181,7 +181,7 @@ pub(crate) struct AcceptContext<'f, 'sess, S: Stage> {
181181 pub ( crate ) attr_path : AttrPath ,
182182}
183183
184- impl < ' f , ' sess : ' f , S : Stage > AcceptContext < ' f , ' sess , S > {
184+ impl < ' f , ' sess : ' f , S : Stage > SharedContext < ' f , ' sess , S > {
185185 pub ( crate ) fn emit_err ( & self , diag : impl for < ' x > Diagnostic < ' x > ) -> ErrorGuaranteed {
186186 S :: emit_err ( & self . sess , diag)
187187 }
@@ -219,7 +219,9 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
219219 unused_span,
220220 )
221221 }
222+ }
222223
224+ impl < ' f , ' sess : ' f , S : Stage > AcceptContext < ' f , ' sess , S > {
223225 pub ( crate ) fn unknown_key (
224226 & self ,
225227 span : Span ,
@@ -352,24 +354,24 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
352354}
353355
354356impl < ' f , ' sess , S : Stage > Deref for AcceptContext < ' f , ' sess , S > {
355- type Target = FinalizeContext < ' f , ' sess , S > ;
357+ type Target = SharedContext < ' f , ' sess , S > ;
356358
357359 fn deref ( & self ) -> & Self :: Target {
358- & self . finalize_cx
360+ & self . shared
359361 }
360362}
361363
362364impl < ' f , ' sess , S : Stage > DerefMut for AcceptContext < ' f , ' sess , S > {
363365 fn deref_mut ( & mut self ) -> & mut Self :: Target {
364- & mut self . finalize_cx
366+ & mut self . shared
365367 }
366368}
367369
368370/// Context given to every attribute parser during finalization.
369371///
370372/// Gives [`AttributeParser`](crate::attributes::AttributeParser)s enough information to create
371373/// errors, for example.
372- pub ( crate ) struct FinalizeContext < ' p , ' sess , S : Stage > {
374+ pub ( crate ) struct SharedContext < ' p , ' sess , S : Stage > {
373375 /// The parse context, gives access to the session and the
374376 /// diagnostics context.
375377 pub ( crate ) cx : & ' p mut AttributeParser < ' sess , S > ,
@@ -378,18 +380,48 @@ pub(crate) struct FinalizeContext<'p, 'sess, S: Stage> {
378380 /// The id ([`NodeId`] if `S` is `Early`, [`HirId`] if `S` is `Late`) of the syntactical component this attribute was applied to
379381 pub ( crate ) target_id : S :: Id ,
380382
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 > ] ,
382400}
383401
384402impl < ' 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 > {
385417 type Target = AttributeParser < ' sess , S > ;
386418
387419 fn deref ( & self ) -> & Self :: Target {
388420 self . cx
389421 }
390422}
391423
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 > {
393425 fn deref_mut ( & mut self ) -> & mut Self :: Target {
394426 self . cx
395427 }
@@ -499,6 +531,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
499531 mut emit_lint : impl FnMut ( AttributeLint < S :: Id > ) ,
500532 ) -> Vec < Attribute > {
501533 let mut attributes = Vec :: new ( ) ;
534+ let mut attr_paths = Vec :: new ( ) ;
502535
503536 for attr in attrs {
504537 // 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> {
542575 // }))
543576 // }
544577 ast:: AttrKind :: Normal ( n) => {
578+ attr_paths. push ( PathParser :: Ast ( & n. item . path ) ) ;
579+
545580 let parser = MetaItemParser :: from_attr ( n, self . dcx ( ) ) ;
546581 let path = parser. path ( ) ;
547582 let args = parser. args ( ) ;
@@ -550,7 +585,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
550585 if let Some ( accepts) = S :: parsers ( ) . 0 . get ( parts. as_slice ( ) ) {
551586 for ( template, accept) in accepts {
552587 let mut cx: AcceptContext < ' _ , ' sess , S > = AcceptContext {
553- finalize_cx : FinalizeContext {
588+ shared : SharedContext {
554589 cx : self ,
555590 target_span,
556591 target_id,
@@ -594,10 +629,13 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
594629 let mut parsed_attributes = Vec :: new ( ) ;
595630 for f in & S :: parsers ( ) . 1 {
596631 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,
601639 } ) {
602640 parsed_attributes. push ( Attribute :: Parsed ( attr) ) ;
603641 }
0 commit comments