@@ -19,43 +19,37 @@ use ptr::P;
1919
2020use util:: small_vector:: SmallVector ;
2121
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.
4323pub struct StripUnconfigured < ' a > {
4424 diag : CfgDiagReal < ' a , ' a > ,
25+ should_test : bool ,
4526 config : & ' a ast:: CrateConfig ,
4627}
4728
4829impl < ' a > StripUnconfigured < ' a > {
4930 pub fn new ( config : & ' a ast:: CrateConfig ,
31+ should_test : bool ,
5032 diagnostic : & ' a Handler ,
5133 feature_gated_cfgs : & ' a mut Vec < GatedCfgAttr > )
5234 -> Self {
5335 StripUnconfigured {
5436 config : config,
37+ should_test : should_test,
5538 diag : CfgDiagReal { diag : diagnostic, feature_gated_cfgs : feature_gated_cfgs } ,
5639 }
5740 }
5841
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+
5953 fn process_cfg_attr ( & mut self , attr : ast:: Attribute ) -> Option < ast:: Attribute > {
6054 if !attr. check_name ( "cfg_attr" ) {
6155 return Some ( attr) ;
@@ -89,13 +83,15 @@ impl<'a> StripUnconfigured<'a> {
8983 None
9084 }
9185 }
92- }
9386
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.
9788 fn in_cfg ( & mut self , attrs : & [ ast:: Attribute ] ) -> bool {
9889 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+
9995 let mis = match attr. node . value . node {
10096 ast:: MetaItemKind :: List ( _, ref mis) if is_cfg ( & attr) => mis,
10197 _ => return true
@@ -112,21 +108,17 @@ impl<'a> CfgFolder for StripUnconfigured<'a> {
112108 } )
113109 }
114110
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).
121112 fn visit_stmt_or_expr_attrs ( & mut self , attrs : & [ ast:: Attribute ] ) {
122113 // flag the offending attributes
123114 for attr in attrs. iter ( ) {
124115 self . diag . feature_gated_cfgs . push ( GatedCfgAttr :: GatedAttr ( attr. span ) ) ;
125116 }
126117 }
127118
119+ // Visit unremovable (non-optional) expressions -- c.f. `fold_expr` vs `fold_opt_expr`.
128120 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 ) ) {
130122 let msg = "removing an expression is not supported in this position" ;
131123 self . diag . diag . span_err ( attr. span , msg) ;
132124 }
@@ -135,15 +127,15 @@ impl<'a> CfgFolder for StripUnconfigured<'a> {
135127
136128// Support conditional compilation by transforming the AST, stripping out
137129// 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 ,
139131 feature_gated_cfgs : & mut Vec < GatedCfgAttr > )
140132 -> ast:: Crate
141133{
142134 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)
144136}
145137
146- impl < T : CfgFolder > fold:: Folder for T {
138+ impl < ' a > fold:: Folder for StripUnconfigured < ' a > {
147139 fn fold_foreign_mod ( & mut self , foreign_mod : ast:: ForeignMod ) -> ast:: ForeignMod {
148140 ast:: ForeignMod {
149141 abi : foreign_mod. abi ,
@@ -204,7 +196,7 @@ impl<T: CfgFolder> fold::Folder for T {
204196 // NB: This is intentionally not part of the fold_expr() function
205197 // in order for fold_opt_expr() to be able to avoid this check
206198 self . visit_unremovable_expr ( & expr) ;
207- let expr = self . process_attrs ( expr) ;
199+ let expr = self . process_cfg_attrs ( expr) ;
208200 fold_expr ( self , expr)
209201 }
210202
@@ -256,7 +248,7 @@ impl<T: CfgFolder> fold::Folder for T {
256248 }
257249}
258250
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 > {
260252 expr. map ( |ast:: Expr { id, span, node, attrs} | {
261253 fold:: noop_fold_expr ( ast:: Expr {
262254 id : id,
@@ -278,6 +270,10 @@ fn is_cfg(attr: &ast::Attribute) -> bool {
278270 attr. check_name ( "cfg" )
279271}
280272
273+ fn is_test_or_bench ( attr : & ast:: Attribute ) -> bool {
274+ attr. check_name ( "test" ) || attr. check_name ( "bench" )
275+ }
276+
281277pub trait CfgDiag {
282278 fn emit_error < F > ( & mut self , f : F ) where F : FnMut ( & Handler ) ;
283279 fn flag_gated < F > ( & mut self , f : F ) where F : FnMut ( & mut Vec < GatedCfgAttr > ) ;
0 commit comments