@@ -19,13 +19,31 @@ use ptr::P;
19
19
20
20
use util:: small_vector:: SmallVector ;
21
21
22
+ pub trait CfgFolder : fold:: Folder {
23
+ fn in_cfg ( & mut self , attrs : & [ ast:: Attribute ] ) -> bool ;
24
+ fn visit_unconfigurable_expr ( & mut self , _expr : & ast:: Expr ) { }
25
+ }
26
+
22
27
/// A folder that strips out items that do not belong in the current
23
28
/// configuration.
24
29
struct Context < ' a , F > where F : FnMut ( & [ ast:: Attribute ] ) -> bool {
25
30
in_cfg : F ,
26
31
diagnostic : & ' a Handler ,
27
32
}
28
33
34
+ impl < ' a , F : FnMut ( & [ ast:: Attribute ] ) -> bool > CfgFolder for Context < ' a , F > {
35
+ fn in_cfg ( & mut self , attrs : & [ ast:: Attribute ] ) -> bool {
36
+ ( self . in_cfg ) ( attrs)
37
+ }
38
+
39
+ fn visit_unconfigurable_expr ( & mut self , expr : & ast:: Expr ) {
40
+ if let Some ( attr) = expr. attrs ( ) . iter ( ) . find ( |a| is_cfg ( a) ) {
41
+ let msg = "removing an expression is not supported in this position" ;
42
+ self . diagnostic . span_err ( attr. span , msg) ;
43
+ }
44
+ }
45
+ }
46
+
29
47
// Support conditional compilation by transforming the AST, stripping out
30
48
// any items that do not belong in the current configuration
31
49
pub fn strip_unconfigured_items ( diagnostic : & Handler , krate : ast:: Crate ,
@@ -48,12 +66,12 @@ pub fn strip_unconfigured_items(diagnostic: &Handler, krate: ast::Crate,
48
66
} )
49
67
}
50
68
51
- impl < ' a , F > fold:: Folder for Context < ' a , F > where F : FnMut ( & [ ast :: Attribute ] ) -> bool {
69
+ impl < T : CfgFolder > fold:: Folder for T {
52
70
fn fold_foreign_mod ( & mut self , foreign_mod : ast:: ForeignMod ) -> ast:: ForeignMod {
53
71
ast:: ForeignMod {
54
72
abi : foreign_mod. abi ,
55
73
items : foreign_mod. items . into_iter ( ) . filter ( |item| {
56
- ( self . in_cfg ) ( & item. attrs )
74
+ self . in_cfg ( & item. attrs )
57
75
} ) . collect ( ) ,
58
76
}
59
77
}
@@ -62,12 +80,12 @@ impl<'a, F> fold::Folder for Context<'a, F> where F: FnMut(&[ast::Attribute]) ->
62
80
let fold_struct = |this : & mut Self , vdata| match vdata {
63
81
ast:: VariantData :: Struct ( fields, id) => {
64
82
ast:: VariantData :: Struct ( fields. into_iter ( ) . filter ( |m| {
65
- ( this. in_cfg ) ( & m. attrs )
83
+ this. in_cfg ( & m. attrs )
66
84
} ) . collect ( ) , id)
67
85
}
68
86
ast:: VariantData :: Tuple ( fields, id) => {
69
87
ast:: VariantData :: Tuple ( fields. into_iter ( ) . filter ( |m| {
70
- ( this. in_cfg ) ( & m. attrs )
88
+ this. in_cfg ( & m. attrs )
71
89
} ) . collect ( ) , id)
72
90
}
73
91
ast:: VariantData :: Unit ( id) => ast:: VariantData :: Unit ( id)
@@ -76,13 +94,13 @@ impl<'a, F> fold::Folder for Context<'a, F> where F: FnMut(&[ast::Attribute]) ->
76
94
let item = match item {
77
95
ast:: ItemKind :: Impl ( u, o, a, b, c, impl_items) => {
78
96
let impl_items = impl_items. into_iter ( )
79
- . filter ( |ii| ( self . in_cfg ) ( & ii. attrs ) )
97
+ . filter ( |ii| self . in_cfg ( & ii. attrs ) )
80
98
. collect ( ) ;
81
99
ast:: ItemKind :: Impl ( u, o, a, b, c, impl_items)
82
100
}
83
101
ast:: ItemKind :: Trait ( u, a, b, methods) => {
84
102
let methods = methods. into_iter ( )
85
- . filter ( |ti| ( self . in_cfg ) ( & ti. attrs ) )
103
+ . filter ( |ti| self . in_cfg ( & ti. attrs ) )
86
104
. collect ( ) ;
87
105
ast:: ItemKind :: Trait ( u, a, b, methods)
88
106
}
@@ -91,7 +109,7 @@ impl<'a, F> fold::Folder for Context<'a, F> where F: FnMut(&[ast::Attribute]) ->
91
109
}
92
110
ast:: ItemKind :: Enum ( def, generics) => {
93
111
let variants = def. variants . into_iter ( ) . filter_map ( |v| {
94
- if !( self . in_cfg ) ( & v. node . attrs ) {
112
+ if !self . in_cfg ( & v. node . attrs ) {
95
113
None
96
114
} else {
97
115
Some ( Spanned {
@@ -123,23 +141,20 @@ impl<'a, F> fold::Folder for Context<'a, F> where F: FnMut(&[ast::Attribute]) ->
123
141
//
124
142
// NB: This is intentionally not part of the fold_expr() function
125
143
// in order for fold_opt_expr() to be able to avoid this check
126
- if let Some ( attr) = expr. attrs ( ) . iter ( ) . find ( |a| is_cfg ( a) ) {
127
- self . diagnostic . span_err ( attr. span ,
128
- "removing an expression is not supported in this position" ) ;
129
- }
144
+ self . visit_unconfigurable_expr ( & expr) ;
130
145
fold_expr ( self , expr)
131
146
}
132
147
133
148
fn fold_opt_expr ( & mut self , expr : P < ast:: Expr > ) -> Option < P < ast:: Expr > > {
134
- if ( self . in_cfg ) ( expr. attrs ( ) ) {
149
+ if self . in_cfg ( expr. attrs ( ) ) {
135
150
Some ( fold_expr ( self , expr) )
136
151
} else {
137
152
None
138
153
}
139
154
}
140
155
141
156
fn fold_stmt ( & mut self , stmt : ast:: Stmt ) -> SmallVector < ast:: Stmt > {
142
- if ( self . in_cfg ) ( stmt. node . attrs ( ) ) {
157
+ if self . in_cfg ( stmt. node . attrs ( ) ) {
143
158
fold:: noop_fold_stmt ( stmt, self )
144
159
} else {
145
160
SmallVector :: zero ( )
@@ -151,7 +166,7 @@ impl<'a, F> fold::Folder for Context<'a, F> where F: FnMut(&[ast::Attribute]) ->
151
166
}
152
167
153
168
fn fold_item ( & mut self , item : P < ast:: Item > ) -> SmallVector < P < ast:: Item > > {
154
- if ( self . in_cfg ) ( & item. attrs ) {
169
+ if self . in_cfg ( & item. attrs ) {
155
170
SmallVector :: one ( item. map ( |i| self . fold_item_simple ( i) ) )
156
171
} else {
157
172
SmallVector :: zero ( )
@@ -170,23 +185,21 @@ pub fn strip_items<'a, F>(diagnostic: &'a Handler,
170
185
ctxt. fold_crate ( krate)
171
186
}
172
187
173
- fn fold_expr < F > ( cx : & mut Context < F > , expr : P < ast:: Expr > ) -> P < ast:: Expr > where
174
- F : FnMut ( & [ ast:: Attribute ] ) -> bool
175
- {
188
+ fn fold_expr < F : CfgFolder > ( folder : & mut F , expr : P < ast:: Expr > ) -> P < ast:: Expr > {
176
189
expr. map ( |ast:: Expr { id, span, node, attrs} | {
177
190
fold:: noop_fold_expr ( ast:: Expr {
178
191
id : id,
179
192
node : match node {
180
193
ast:: ExprKind :: Match ( m, arms) => {
181
194
ast:: ExprKind :: Match ( m, arms. into_iter ( )
182
- . filter ( |a| ( cx . in_cfg ) ( & a. attrs ) )
195
+ . filter ( |a| folder . in_cfg ( & a. attrs ) )
183
196
. collect ( ) )
184
197
}
185
198
_ => node
186
199
} ,
187
200
span : span,
188
201
attrs : attrs,
189
- } , cx )
202
+ } , folder )
190
203
} )
191
204
}
192
205
0 commit comments