@@ -39,50 +39,10 @@ pub(crate) fn cfg_eval(
3939 let features = Some ( features) ;
4040 CfgEval ( StripUnconfigured { sess, features, config_tokens : true , lint_node_id } )
4141 . configure_annotatable ( annotatable)
42- // Since the item itself has already been configured by the `InvocationCollector`,
43- // we know that fold result vector will contain exactly one element.
44- . unwrap ( )
4542}
4643
4744struct CfgEval < ' a > ( StripUnconfigured < ' a > ) ;
4845
49- fn flat_map_annotatable (
50- vis : & mut impl MutVisitor ,
51- annotatable : Annotatable ,
52- ) -> Option < Annotatable > {
53- match annotatable {
54- Annotatable :: Item ( item) => vis. flat_map_item ( item) . pop ( ) . map ( Annotatable :: Item ) ,
55- Annotatable :: AssocItem ( item, ctxt) => {
56- Some ( Annotatable :: AssocItem ( vis. flat_map_assoc_item ( item, ctxt) . pop ( ) ?, ctxt) )
57- }
58- Annotatable :: ForeignItem ( item) => {
59- vis. flat_map_foreign_item ( item) . pop ( ) . map ( Annotatable :: ForeignItem )
60- }
61- Annotatable :: Stmt ( stmt) => {
62- vis. flat_map_stmt ( stmt. into_inner ( ) ) . pop ( ) . map ( P ) . map ( Annotatable :: Stmt )
63- }
64- Annotatable :: Expr ( mut expr) => {
65- vis. visit_expr ( & mut expr) ;
66- Some ( Annotatable :: Expr ( expr) )
67- }
68- Annotatable :: Arm ( arm) => vis. flat_map_arm ( arm) . pop ( ) . map ( Annotatable :: Arm ) ,
69- Annotatable :: ExprField ( field) => {
70- vis. flat_map_expr_field ( field) . pop ( ) . map ( Annotatable :: ExprField )
71- }
72- Annotatable :: PatField ( fp) => vis. flat_map_pat_field ( fp) . pop ( ) . map ( Annotatable :: PatField ) ,
73- Annotatable :: GenericParam ( param) => {
74- vis. flat_map_generic_param ( param) . pop ( ) . map ( Annotatable :: GenericParam )
75- }
76- Annotatable :: Param ( param) => vis. flat_map_param ( param) . pop ( ) . map ( Annotatable :: Param ) ,
77- Annotatable :: FieldDef ( sf) => vis. flat_map_field_def ( sf) . pop ( ) . map ( Annotatable :: FieldDef ) ,
78- Annotatable :: Variant ( v) => vis. flat_map_variant ( v) . pop ( ) . map ( Annotatable :: Variant ) ,
79- Annotatable :: Crate ( mut krate) => {
80- vis. visit_crate ( & mut krate) ;
81- Some ( Annotatable :: Crate ( krate) )
82- }
83- }
84- }
85-
8646fn has_cfg_or_cfg_attr ( annotatable : & Annotatable ) -> bool {
8747 struct CfgFinder ;
8848
@@ -106,14 +66,7 @@ fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool {
10666 Annotatable :: ForeignItem ( item) => CfgFinder . visit_foreign_item ( item) ,
10767 Annotatable :: Stmt ( stmt) => CfgFinder . visit_stmt ( stmt) ,
10868 Annotatable :: Expr ( expr) => CfgFinder . visit_expr ( expr) ,
109- Annotatable :: Arm ( arm) => CfgFinder . visit_arm ( arm) ,
110- Annotatable :: ExprField ( field) => CfgFinder . visit_expr_field ( field) ,
111- Annotatable :: PatField ( field) => CfgFinder . visit_pat_field ( field) ,
112- Annotatable :: GenericParam ( param) => CfgFinder . visit_generic_param ( param) ,
113- Annotatable :: Param ( param) => CfgFinder . visit_param ( param) ,
114- Annotatable :: FieldDef ( field) => CfgFinder . visit_field_def ( field) ,
115- Annotatable :: Variant ( variant) => CfgFinder . visit_variant ( variant) ,
116- Annotatable :: Crate ( krate) => CfgFinder . visit_crate ( krate) ,
69+ _ => unreachable ! ( ) ,
11770 } ;
11871 res. is_break ( )
11972}
@@ -123,11 +76,11 @@ impl CfgEval<'_> {
12376 self . 0 . configure ( node)
12477 }
12578
126- fn configure_annotatable ( & mut self , mut annotatable : Annotatable ) -> Option < Annotatable > {
79+ fn configure_annotatable ( mut self , annotatable : Annotatable ) -> Annotatable {
12780 // Tokenizing and re-parsing the `Annotatable` can have a significant
12881 // performance impact, so try to avoid it if possible
12982 if !has_cfg_or_cfg_attr ( & annotatable) {
130- return Some ( annotatable) ;
83+ return annotatable;
13184 }
13285
13386 // The majority of parsed attribute targets will never need to have early cfg-expansion
@@ -140,39 +93,6 @@ impl CfgEval<'_> {
14093 // the location of `#[cfg]` and `#[cfg_attr]` in the token stream. The tokenization
14194 // process is lossless, so this process is invisible to proc-macros.
14295
143- let parse_annotatable_with: for <' a > fn ( & mut Parser < ' a > ) -> PResult < ' a , _ > =
144- match annotatable {
145- Annotatable :: Item ( _) => {
146- |parser| Ok ( Annotatable :: Item ( parser. parse_item ( ForceCollect :: Yes ) ?. unwrap ( ) ) )
147- }
148- Annotatable :: AssocItem ( _, AssocCtxt :: Trait ) => |parser| {
149- Ok ( Annotatable :: AssocItem (
150- parser. parse_trait_item ( ForceCollect :: Yes ) ?. unwrap ( ) . unwrap ( ) ,
151- AssocCtxt :: Trait ,
152- ) )
153- } ,
154- Annotatable :: AssocItem ( _, AssocCtxt :: Impl ) => |parser| {
155- Ok ( Annotatable :: AssocItem (
156- parser. parse_impl_item ( ForceCollect :: Yes ) ?. unwrap ( ) . unwrap ( ) ,
157- AssocCtxt :: Impl ,
158- ) )
159- } ,
160- Annotatable :: ForeignItem ( _) => |parser| {
161- Ok ( Annotatable :: ForeignItem (
162- parser. parse_foreign_item ( ForceCollect :: Yes ) ?. unwrap ( ) . unwrap ( ) ,
163- ) )
164- } ,
165- Annotatable :: Stmt ( _) => |parser| {
166- Ok ( Annotatable :: Stmt ( P ( parser
167- . parse_stmt_without_recovery ( false , ForceCollect :: Yes ) ?
168- . unwrap ( ) ) ) )
169- } ,
170- Annotatable :: Expr ( _) => {
171- |parser| Ok ( Annotatable :: Expr ( parser. parse_expr_force_collect ( ) ?) )
172- }
173- _ => unreachable ! ( ) ,
174- } ;
175-
17696 // 'Flatten' all nonterminals (i.e. `TokenKind::Interpolated`)
17797 // to `None`-delimited groups containing the corresponding tokens. This
17898 // is normally delayed until the proc-macro server actually needs to
@@ -191,19 +111,56 @@ impl CfgEval<'_> {
191111 // Re-parse the tokens, setting the `capture_cfg` flag to save extra information
192112 // to the captured `AttrTokenStream` (specifically, we capture
193113 // `AttrTokenTree::AttrsTarget` for all occurrences of `#[cfg]` and `#[cfg_attr]`)
114+ //
115+ // After that we have our re-parsed `AttrTokenStream`, recursively configuring
116+ // our attribute target will correctly configure the tokens as well.
194117 let mut parser = Parser :: new ( & self . 0 . sess . psess , orig_tokens, None ) ;
195118 parser. capture_cfg = true ;
196- match parse_annotatable_with ( & mut parser) {
197- Ok ( a) => annotatable = a,
119+ let res: PResult < ' _ , Annotatable > = try {
120+ match annotatable {
121+ Annotatable :: Item ( _) => {
122+ let item = parser. parse_item ( ForceCollect :: Yes ) ?. unwrap ( ) ;
123+ Annotatable :: Item ( self . flat_map_item ( item) . pop ( ) . unwrap ( ) )
124+ }
125+ Annotatable :: AssocItem ( _, AssocCtxt :: Trait ) => {
126+ let item = parser. parse_trait_item ( ForceCollect :: Yes ) ?. unwrap ( ) . unwrap ( ) ;
127+ Annotatable :: AssocItem (
128+ self . flat_map_assoc_item ( item, AssocCtxt :: Trait ) . pop ( ) . unwrap ( ) ,
129+ AssocCtxt :: Trait ,
130+ )
131+ }
132+ Annotatable :: AssocItem ( _, AssocCtxt :: Impl ) => {
133+ let item = parser. parse_impl_item ( ForceCollect :: Yes ) ?. unwrap ( ) . unwrap ( ) ;
134+ Annotatable :: AssocItem (
135+ self . flat_map_assoc_item ( item, AssocCtxt :: Impl ) . pop ( ) . unwrap ( ) ,
136+ AssocCtxt :: Impl ,
137+ )
138+ }
139+ Annotatable :: ForeignItem ( _) => {
140+ let item = parser. parse_foreign_item ( ForceCollect :: Yes ) ?. unwrap ( ) . unwrap ( ) ;
141+ Annotatable :: ForeignItem ( self . flat_map_foreign_item ( item) . pop ( ) . unwrap ( ) )
142+ }
143+ Annotatable :: Stmt ( _) => {
144+ let stmt =
145+ parser. parse_stmt_without_recovery ( false , ForceCollect :: Yes ) ?. unwrap ( ) ;
146+ Annotatable :: Stmt ( P ( self . flat_map_stmt ( stmt) . pop ( ) . unwrap ( ) ) )
147+ }
148+ Annotatable :: Expr ( _) => {
149+ let mut expr = parser. parse_expr_force_collect ( ) ?;
150+ self . visit_expr ( & mut expr) ;
151+ Annotatable :: Expr ( expr)
152+ }
153+ _ => unreachable ! ( ) ,
154+ }
155+ } ;
156+
157+ match res {
158+ Ok ( ann) => ann,
198159 Err ( err) => {
199160 err. emit ( ) ;
200- return Some ( annotatable) ;
161+ annotatable
201162 }
202163 }
203-
204- // Now that we have our re-parsed `AttrTokenStream`, recursively configuring
205- // our attribute target will correctly configure the tokens as well.
206- flat_map_annotatable ( self , annotatable)
207164 }
208165}
209166
0 commit comments