@@ -19,43 +19,37 @@ use ptr::P;
19
19
20
20
use util:: small_vector:: SmallVector ;
21
21
22
- pub trait CfgFolder : fold:: Folder {
23
- // Check if a node with the given attributes is in this configuration.
24
- fn in_cfg ( & mut self , attrs : & [ ast:: Attribute ] ) -> bool ;
25
-
26
- // Update a node before checking if it is in this configuration (used to implement `cfg_attr`).
27
- fn process_attrs < T : HasAttrs > ( & mut self , node : T ) -> T { node }
28
-
29
- // Visit attributes on expression and statements (but not attributes on items in blocks).
30
- fn visit_stmt_or_expr_attrs ( & mut self , _attrs : & [ ast:: Attribute ] ) { }
31
-
32
- // Visit unremovable (non-optional) expressions -- c.f. `fold_expr` vs `fold_opt_expr`.
33
- fn visit_unremovable_expr ( & mut self , _expr : & ast:: Expr ) { }
34
-
35
- fn configure < T : HasAttrs > ( & mut self , node : T ) -> Option < T > {
36
- let node = self . process_attrs ( node) ;
37
- if self . in_cfg ( node. attrs ( ) ) { Some ( node) } else { None }
38
- }
39
- }
40
-
41
- /// A folder that strips out items that do not belong in the current
42
- /// configuration.
22
+ /// A folder that strips out items that do not belong in the current configuration.
43
23
pub struct StripUnconfigured < ' a > {
44
24
diag : CfgDiagReal < ' a , ' a > ,
25
+ should_test : bool ,
45
26
config : & ' a ast:: CrateConfig ,
46
27
}
47
28
48
29
impl < ' a > StripUnconfigured < ' a > {
49
30
pub fn new ( config : & ' a ast:: CrateConfig ,
31
+ should_test : bool ,
50
32
diagnostic : & ' a Handler ,
51
33
feature_gated_cfgs : & ' a mut Vec < GatedCfgAttr > )
52
34
-> Self {
53
35
StripUnconfigured {
54
36
config : config,
37
+ should_test : should_test,
55
38
diag : CfgDiagReal { diag : diagnostic, feature_gated_cfgs : feature_gated_cfgs } ,
56
39
}
57
40
}
58
41
42
+ fn configure < T : HasAttrs > ( & mut self , node : T ) -> Option < T > {
43
+ let node = self . process_cfg_attrs ( node) ;
44
+ if self . in_cfg ( node. attrs ( ) ) { Some ( node) } else { None }
45
+ }
46
+
47
+ fn process_cfg_attrs < T : HasAttrs > ( & mut self , node : T ) -> T {
48
+ node. map_attrs ( |attrs| {
49
+ attrs. into_iter ( ) . filter_map ( |attr| self . process_cfg_attr ( attr) ) . collect ( )
50
+ } )
51
+ }
52
+
59
53
fn process_cfg_attr ( & mut self , attr : ast:: Attribute ) -> Option < ast:: Attribute > {
60
54
if !attr. check_name ( "cfg_attr" ) {
61
55
return Some ( attr) ;
@@ -89,13 +83,15 @@ impl<'a> StripUnconfigured<'a> {
89
83
None
90
84
}
91
85
}
92
- }
93
86
94
- impl < ' a > CfgFolder for StripUnconfigured < ' a > {
95
- // Determine if an item should be translated in the current crate
96
- // configuration based on the item's attributes
87
+ // Determine if a node with the given attributes should be included in this configuation.
97
88
fn in_cfg ( & mut self , attrs : & [ ast:: Attribute ] ) -> bool {
98
89
attrs. iter ( ) . all ( |attr| {
90
+ // When not compiling with --test we should not compile the #[test] functions
91
+ if !self . should_test && is_test_or_bench ( attr) {
92
+ return false ;
93
+ }
94
+
99
95
let mis = match attr. node . value . node {
100
96
ast:: MetaItemKind :: List ( _, ref mis) if is_cfg ( & attr) => mis,
101
97
_ => return true
@@ -112,21 +108,17 @@ impl<'a> CfgFolder for StripUnconfigured<'a> {
112
108
} )
113
109
}
114
110
115
- fn process_attrs < T : HasAttrs > ( & mut self , node : T ) -> T {
116
- node. map_attrs ( |attrs| {
117
- attrs. into_iter ( ) . filter_map ( |attr| self . process_cfg_attr ( attr) ) . collect ( )
118
- } )
119
- }
120
-
111
+ // Visit attributes on expression and statements (but not attributes on items in blocks).
121
112
fn visit_stmt_or_expr_attrs ( & mut self , attrs : & [ ast:: Attribute ] ) {
122
113
// flag the offending attributes
123
114
for attr in attrs. iter ( ) {
124
115
self . diag . feature_gated_cfgs . push ( GatedCfgAttr :: GatedAttr ( attr. span ) ) ;
125
116
}
126
117
}
127
118
119
+ // Visit unremovable (non-optional) expressions -- c.f. `fold_expr` vs `fold_opt_expr`.
128
120
fn visit_unremovable_expr ( & mut self , expr : & ast:: Expr ) {
129
- if let Some ( attr) = expr. attrs ( ) . iter ( ) . find ( |a| is_cfg ( a) ) {
121
+ if let Some ( attr) = expr. attrs ( ) . iter ( ) . find ( |a| is_cfg ( a) || is_test_or_bench ( a ) ) {
130
122
let msg = "removing an expression is not supported in this position" ;
131
123
self . diag . diag . span_err ( attr. span , msg) ;
132
124
}
@@ -135,15 +127,15 @@ impl<'a> CfgFolder for StripUnconfigured<'a> {
135
127
136
128
// Support conditional compilation by transforming the AST, stripping out
137
129
// any items that do not belong in the current configuration
138
- pub fn strip_unconfigured_items ( diagnostic : & Handler , krate : ast:: Crate ,
130
+ pub fn strip_unconfigured_items ( diagnostic : & Handler , krate : ast:: Crate , should_test : bool ,
139
131
feature_gated_cfgs : & mut Vec < GatedCfgAttr > )
140
132
-> ast:: Crate
141
133
{
142
134
let config = & krate. config . clone ( ) ;
143
- StripUnconfigured :: new ( config, diagnostic, feature_gated_cfgs) . fold_crate ( krate)
135
+ StripUnconfigured :: new ( config, should_test , diagnostic, feature_gated_cfgs) . fold_crate ( krate)
144
136
}
145
137
146
- impl < T : CfgFolder > fold:: Folder for T {
138
+ impl < ' a > fold:: Folder for StripUnconfigured < ' a > {
147
139
fn fold_foreign_mod ( & mut self , foreign_mod : ast:: ForeignMod ) -> ast:: ForeignMod {
148
140
ast:: ForeignMod {
149
141
abi : foreign_mod. abi ,
@@ -204,7 +196,7 @@ impl<T: CfgFolder> fold::Folder for T {
204
196
// NB: This is intentionally not part of the fold_expr() function
205
197
// in order for fold_opt_expr() to be able to avoid this check
206
198
self . visit_unremovable_expr ( & expr) ;
207
- let expr = self . process_attrs ( expr) ;
199
+ let expr = self . process_cfg_attrs ( expr) ;
208
200
fold_expr ( self , expr)
209
201
}
210
202
@@ -256,7 +248,7 @@ impl<T: CfgFolder> fold::Folder for T {
256
248
}
257
249
}
258
250
259
- fn fold_expr < F : CfgFolder > ( folder : & mut F , expr : P < ast:: Expr > ) -> P < ast:: Expr > {
251
+ fn fold_expr ( folder : & mut StripUnconfigured , expr : P < ast:: Expr > ) -> P < ast:: Expr > {
260
252
expr. map ( |ast:: Expr { id, span, node, attrs} | {
261
253
fold:: noop_fold_expr ( ast:: Expr {
262
254
id : id,
@@ -278,6 +270,10 @@ fn is_cfg(attr: &ast::Attribute) -> bool {
278
270
attr. check_name ( "cfg" )
279
271
}
280
272
273
+ fn is_test_or_bench ( attr : & ast:: Attribute ) -> bool {
274
+ attr. check_name ( "test" ) || attr. check_name ( "bench" )
275
+ }
276
+
281
277
pub trait CfgDiag {
282
278
fn emit_error < F > ( & mut self , f : F ) where F : FnMut ( & Handler ) ;
283
279
fn flag_gated < F > ( & mut self , f : F ) where F : FnMut ( & mut Vec < GatedCfgAttr > ) ;
0 commit comments