@@ -39,50 +39,10 @@ pub(crate) fn cfg_eval(
39
39
let features = Some ( features) ;
40
40
CfgEval ( StripUnconfigured { sess, features, config_tokens : true , lint_node_id } )
41
41
. 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 ( )
45
42
}
46
43
47
44
struct CfgEval < ' a > ( StripUnconfigured < ' a > ) ;
48
45
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
-
86
46
fn has_cfg_or_cfg_attr ( annotatable : & Annotatable ) -> bool {
87
47
struct CfgFinder ;
88
48
@@ -106,14 +66,7 @@ fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool {
106
66
Annotatable :: ForeignItem ( item) => CfgFinder . visit_foreign_item ( item) ,
107
67
Annotatable :: Stmt ( stmt) => CfgFinder . visit_stmt ( stmt) ,
108
68
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 ! ( ) ,
117
70
} ;
118
71
res. is_break ( )
119
72
}
@@ -123,11 +76,11 @@ impl CfgEval<'_> {
123
76
self . 0 . configure ( node)
124
77
}
125
78
126
- fn configure_annotatable ( & mut self , mut annotatable : Annotatable ) -> Option < Annotatable > {
79
+ fn configure_annotatable ( mut self , annotatable : Annotatable ) -> Annotatable {
127
80
// Tokenizing and re-parsing the `Annotatable` can have a significant
128
81
// performance impact, so try to avoid it if possible
129
82
if !has_cfg_or_cfg_attr ( & annotatable) {
130
- return Some ( annotatable) ;
83
+ return annotatable;
131
84
}
132
85
133
86
// The majority of parsed attribute targets will never need to have early cfg-expansion
@@ -140,39 +93,6 @@ impl CfgEval<'_> {
140
93
// the location of `#[cfg]` and `#[cfg_attr]` in the token stream. The tokenization
141
94
// process is lossless, so this process is invisible to proc-macros.
142
95
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
-
176
96
// 'Flatten' all nonterminals (i.e. `TokenKind::Interpolated`)
177
97
// to `None`-delimited groups containing the corresponding tokens. This
178
98
// is normally delayed until the proc-macro server actually needs to
@@ -191,19 +111,56 @@ impl CfgEval<'_> {
191
111
// Re-parse the tokens, setting the `capture_cfg` flag to save extra information
192
112
// to the captured `AttrTokenStream` (specifically, we capture
193
113
// `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.
194
117
let mut parser = Parser :: new ( & self . 0 . sess . psess , orig_tokens, None ) ;
195
118
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,
198
159
Err ( err) => {
199
160
err. emit ( ) ;
200
- return Some ( annotatable) ;
161
+ annotatable
201
162
}
202
163
}
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)
207
164
}
208
165
}
209
166
0 commit comments