about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-05-26 23:56:25 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-05-27 00:01:04 +0000
commit15d5074a34976ad562acab0bc9c4a10754525b0a (patch)
tree6e8dc3cd66ad918f90e226867e2ed830f55f58c4 /src/libsyntax
parentd3a0e1783c8e3ef336a684908fb08a0e8c0364d8 (diff)
Process `cfg_attr` attributes on non-optional expressions
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/config.rs66
-rw-r--r--src/libsyntax/test.rs9
2 files changed, 37 insertions, 38 deletions
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 62c922a4dbf..e1c17ca43d3 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -19,9 +19,15 @@ use ptr::P;
 use util::small_vector::SmallVector;
 
 pub trait CfgFolder: fold::Folder {
-    fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T>;
+    fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool;
+    fn process_attrs<T: HasAttrs>(&mut self, node: T) -> T { node }
     fn visit_stmt_or_expr_attrs(&mut self, _attrs: &[ast::Attribute]) {}
-    fn visit_unconfigurable_expr(&mut self, _expr: &ast::Expr) {}
+    fn visit_unremovable_expr(&mut self, _expr: &ast::Expr) {}
+
+    fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
+        let node = self.process_attrs(node);
+        if self.in_cfg(node.attrs()) { Some(node) } else { None }
+    }
 }
 
 /// A folder that strips out items that do not belong in the current
@@ -32,30 +38,6 @@ pub struct StripUnconfigured<'a> {
 }
 
 impl<'a> StripUnconfigured<'a> {
-    // Determine if an item should be translated in the current crate
-    // configuration based on the item's attributes
-    fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool {
-        attrs.iter().all(|attr| {
-            let mis = match attr.node.value.node {
-                ast::MetaItemKind::List(_, ref mis) if is_cfg(&attr) => mis,
-                _ => return true
-            };
-
-            if mis.len() != 1 {
-                self.diag.emit_error(|diagnostic| {
-                    diagnostic.span_err(attr.span, "expected 1 cfg-pattern");
-                });
-                return true;
-            }
-
-            attr::cfg_matches(self.config, &mis[0], &mut self.diag)
-        })
-    }
-
-    fn process_cfg_attrs(&mut self, attrs: Vec<ast::Attribute>) -> Vec<ast::Attribute> {
-        attrs.into_iter().filter_map(|attr| self.process_cfg_attr(attr)).collect()
-    }
-
     fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
         if !attr.check_name("cfg_attr") {
             return Some(attr);
@@ -92,9 +74,30 @@ impl<'a> StripUnconfigured<'a> {
 }
 
 impl<'a> CfgFolder for StripUnconfigured<'a> {
-    fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
-        let node = node.map_attrs(|attrs| self.process_cfg_attrs(attrs));
-        if self.in_cfg(node.attrs()) { Some(node) } else { None }
+    // Determine if an item should be translated in the current crate
+    // configuration based on the item's attributes
+    fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool {
+        attrs.iter().all(|attr| {
+            let mis = match attr.node.value.node {
+                ast::MetaItemKind::List(_, ref mis) if is_cfg(&attr) => mis,
+                _ => return true
+            };
+
+            if mis.len() != 1 {
+                self.diag.emit_error(|diagnostic| {
+                    diagnostic.span_err(attr.span, "expected 1 cfg-pattern");
+                });
+                return true;
+            }
+
+            attr::cfg_matches(self.config, &mis[0], &mut self.diag)
+        })
+    }
+
+    fn process_attrs<T: HasAttrs>(&mut self, node: T) -> T {
+        node.map_attrs(|attrs| {
+            attrs.into_iter().filter_map(|attr| self.process_cfg_attr(attr)).collect()
+        })
     }
 
     fn visit_stmt_or_expr_attrs(&mut self, attrs: &[ast::Attribute]) {
@@ -104,7 +107,7 @@ impl<'a> CfgFolder for StripUnconfigured<'a> {
         }
     }
 
-    fn visit_unconfigurable_expr(&mut self, expr: &ast::Expr) {
+    fn visit_unremovable_expr(&mut self, expr: &ast::Expr) {
         if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(a)) {
             let msg = "removing an expression is not supported in this position";
             self.diag.diag.span_err(attr.span, msg);
@@ -195,7 +198,8 @@ impl<T: CfgFolder> fold::Folder for T {
         //
         // NB: This is intentionally not part of the fold_expr() function
         //     in order for fold_opt_expr() to be able to avoid this check
-        self.visit_unconfigurable_expr(&expr);
+        self.visit_unremovable_expr(&expr);
+        let expr = self.process_attrs(expr);
         fold_expr(self, expr)
     }
 
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index 84c7250fac6..45f349eff31 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -317,13 +317,8 @@ fn strip_test_functions(krate: ast::Crate) -> ast::Crate {
     // #[test] functions
     struct StripTests;
     impl config::CfgFolder for StripTests {
-        fn configure<T: attr::HasAttrs>(&mut self, node: T) -> Option<T> {
-            let strip_node = {
-                let attrs = node.attrs();
-                attr::contains_name(attrs, "test") || attr::contains_name(attrs, "bench")
-            };
-
-            if strip_node { None } else { Some(node) }
+        fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool {
+            !attr::contains_name(attrs, "test") && !attr::contains_name(attrs, "bench")
         }
     }