@@ -62,15 +62,23 @@ use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
6262use crate :: parser:: { ArgParser , MetaItemParser , PathParser } ;
6363use crate :: session_diagnostics:: { AttributeParseError , AttributeParseErrorReason , UnknownMetaItem } ;
6464
65- macro_rules! group_type {
66- ( $stage: ty) => {
67- LazyLock <(
68- BTreeMap <& ' static [ Symbol ] , Vec <( AttributeTemplate , Box <dyn for <' sess, ' a> Fn ( & mut AcceptContext <' _, ' sess, $stage>, & ArgParser <' a>) + Send + Sync >) >>,
69- Vec <Box <dyn Send + Sync + Fn ( & mut FinalizeContext <' _, ' _, $stage>) -> Option <AttributeKind >>>
70- ) >
71- } ;
65+ type GroupType < S > = LazyLock < GroupTypeInner < S > > ;
66+
67+ struct GroupTypeInner < S : Stage > {
68+ accepters : BTreeMap < & ' static [ Symbol ] , Vec < GroupTypeInnerAccept < S > > > ,
69+ finalizers : Vec < FinalizeFn < S > > ,
70+ }
71+
72+ struct GroupTypeInnerAccept < S : Stage > {
73+ template : AttributeTemplate ,
74+ accept_fn : AcceptFn < S > ,
7275}
7376
77+ type AcceptFn < S > =
78+ Box < dyn for <' sess , ' a > Fn ( & mut AcceptContext < ' _ , ' sess , S > , & ArgParser < ' a > ) + Send + Sync > ;
79+ type FinalizeFn < S > =
80+ Box < dyn Send + Sync + Fn ( & mut FinalizeContext < ' _ , ' _ , S > ) -> Option < AttributeKind > > ;
81+
7482macro_rules! attribute_parsers {
7583 (
7684 pub ( crate ) static $name: ident = [ $( $names: ty) ,* $( , ) ?] ;
@@ -93,23 +101,26 @@ macro_rules! attribute_parsers {
93101 }
94102 } ;
95103 (
96- @[ $ty : ty] pub ( crate ) static $name: ident = [ $( $names: ty) ,* $( , ) ?] ;
104+ @[ $stage : ty] pub ( crate ) static $name: ident = [ $( $names: ty) ,* $( , ) ?] ;
97105 ) => {
98- pub ( crate ) static $name: group_type! ( $ty ) = LazyLock :: new( || {
99- let mut accepts = BTreeMap :: <_, Vec <( AttributeTemplate , Box <dyn for < ' sess , ' a> Fn ( & mut AcceptContext < ' _ , ' sess , $ty> , & ArgParser < ' a> ) + Send + Sync > ) >>:: new( ) ;
100- let mut finalizes = Vec :: <Box <dyn Send + Sync + Fn ( & mut FinalizeContext < ' _ , ' _ , $ty> ) -> Option < AttributeKind > >>:: new( ) ;
106+ pub ( crate ) static $name: GroupType <$stage> = LazyLock :: new( || {
107+ let mut accepts = BTreeMap :: <_, Vec <GroupTypeInnerAccept <$stage> >>:: new( ) ;
108+ let mut finalizes = Vec :: <FinalizeFn <$stage >>:: new( ) ;
101109 $(
102110 {
103111 thread_local! {
104112 static STATE_OBJECT : RefCell <$names> = RefCell :: new( <$names>:: default ( ) ) ;
105113 } ;
106114
107115 for ( path, template, accept_fn) in <$names>:: ATTRIBUTES {
108- accepts. entry( * path) . or_default( ) . push( ( * template, Box :: new( |cx, args| {
109- STATE_OBJECT . with_borrow_mut( |s| {
110- accept_fn( s, cx, args)
116+ accepts. entry( * path) . or_default( ) . push( GroupTypeInnerAccept {
117+ template: * template,
118+ accept_fn: Box :: new( |cx, args| {
119+ STATE_OBJECT . with_borrow_mut( |s| {
120+ accept_fn( s, cx, args)
121+ } )
111122 } )
112- } ) ) ) ;
123+ } ) ;
113124 }
114125
115126 finalizes. push( Box :: new( |cx| {
@@ -119,7 +130,7 @@ macro_rules! attribute_parsers {
119130 }
120131 ) *
121132
122- ( accepts, finalizes)
133+ GroupTypeInner { accepters : accepts, finalizers : finalizes }
123134 } ) ;
124135 } ;
125136}
@@ -215,7 +226,7 @@ pub trait Stage: Sized + 'static + Sealed {
215226 type Id : Copy ;
216227 const SHOULD_EMIT_LINTS : bool ;
217228
218- fn parsers ( ) -> & ' static group_type ! ( Self ) ;
229+ fn parsers ( ) -> & ' static GroupType < Self > ;
219230
220231 fn emit_err < ' sess > (
221232 & self ,
@@ -230,7 +241,7 @@ impl Stage for Early {
230241 type Id = NodeId ;
231242 const SHOULD_EMIT_LINTS : bool = false ;
232243
233- fn parsers ( ) -> & ' static group_type ! ( Self ) {
244+ fn parsers ( ) -> & ' static GroupType < Self > {
234245 & early:: ATTRIBUTE_PARSERS
235246 }
236247 fn emit_err < ' sess > (
@@ -252,7 +263,7 @@ impl Stage for Late {
252263 type Id = HirId ;
253264 const SHOULD_EMIT_LINTS : bool = true ;
254265
255- fn parsers ( ) -> & ' static group_type ! ( Self ) {
266+ fn parsers ( ) -> & ' static GroupType < Self > {
256267 & late:: ATTRIBUTE_PARSERS
257268 }
258269 fn emit_err < ' sess > (
@@ -811,8 +822,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
811822 let args = parser. args ( ) ;
812823 let parts = path. segments ( ) . map ( |i| i. name ) . collect :: < Vec < _ > > ( ) ;
813824
814- if let Some ( accepts) = S :: parsers ( ) . 0 . get ( parts. as_slice ( ) ) {
815- for ( template , accept) in accepts {
825+ if let Some ( accepts) = S :: parsers ( ) . accepters . get ( parts. as_slice ( ) ) {
826+ for accept in accepts {
816827 let mut cx: AcceptContext < ' _ , ' sess , S > = AcceptContext {
817828 shared : SharedContext {
818829 cx : self ,
@@ -821,11 +832,11 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
821832 emit_lint : & mut emit_lint,
822833 } ,
823834 attr_span : lower_span ( attr. span ) ,
824- template,
835+ template : & accept . template ,
825836 attr_path : path. get_attribute_path ( ) ,
826837 } ;
827838
828- accept ( & mut cx, args)
839+ ( accept. accept_fn ) ( & mut cx, args)
829840 }
830841 } else {
831842 // If we're here, we must be compiling a tool attribute... Or someone
@@ -856,7 +867,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
856867 }
857868
858869 let mut parsed_attributes = Vec :: new ( ) ;
859- for f in & S :: parsers ( ) . 1 {
870+ for f in & S :: parsers ( ) . finalizers {
860871 if let Some ( attr) = f ( & mut FinalizeContext {
861872 shared : SharedContext {
862873 cx : self ,
@@ -877,7 +888,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
877888
878889 /// Returns whether there is a parser for an attribute with this name
879890 pub fn is_parsed_attribute ( path : & [ Symbol ] ) -> bool {
880- Late :: parsers ( ) . 0 . contains_key ( path)
891+ Late :: parsers ( ) . accepters . contains_key ( path)
881892 }
882893
883894 fn lower_attr_args ( & self , args : & ast:: AttrArgs , lower_span : impl Fn ( Span ) -> Span ) -> AttrArgs {
0 commit comments