about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-09-07 22:24:01 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-09-07 22:41:35 +0000
commitd76bf3ed80b0f6d6fb44704f98df1067353de300 (patch)
treea785aa274d0341fedce7c62f0b50275c75af6840 /src/libsyntax
parent3af0c6572eebd2c7fad72e8ba37eac71b8abc8bc (diff)
downloadrust-d76bf3ed80b0f6d6fb44704f98df1067353de300.tar.gz
rust-d76bf3ed80b0f6d6fb44704f98df1067353de300.zip
Strip unconfigured nodes in the `InvocationCollector` fold.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/config.rs12
-rw-r--r--src/libsyntax/ext/expand.rs73
-rw-r--r--src/libsyntax/lib.rs1
3 files changed, 67 insertions, 19 deletions
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 07604bffa1c..3f5b294cc04 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -70,7 +70,7 @@ macro_rules! configure {
 }
 
 impl<'a> StripUnconfigured<'a> {
-    fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
+    pub fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
         let node = self.process_cfg_attrs(node);
         if self.in_cfg(node.attrs()) { Some(node) } else { None }
     }
@@ -166,7 +166,7 @@ impl<'a> StripUnconfigured<'a> {
         }
     }
 
-    fn configure_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod {
+    pub fn configure_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod {
         ast::ForeignMod {
             abi: foreign_mod.abi,
             items: foreign_mod.items.into_iter().filter_map(|item| self.configure(item)).collect(),
@@ -187,7 +187,7 @@ impl<'a> StripUnconfigured<'a> {
         }
     }
 
-    fn configure_item_kind(&mut self, item: ast::ItemKind) -> ast::ItemKind {
+    pub fn configure_item_kind(&mut self, item: ast::ItemKind) -> ast::ItemKind {
         match item {
             ast::ItemKind::Struct(def, generics) => {
                 ast::ItemKind::Struct(self.configure_variant_data(def), generics)
@@ -217,7 +217,7 @@ impl<'a> StripUnconfigured<'a> {
         }
     }
 
-    fn configure_expr_kind(&mut self, expr_kind: ast::ExprKind) -> ast::ExprKind {
+    pub fn configure_expr_kind(&mut self, expr_kind: ast::ExprKind) -> ast::ExprKind {
         if let ast::ExprKind::Match(m, arms) = expr_kind {
             let arms = arms.into_iter().filter_map(|a| self.configure(a)).collect();
             ast::ExprKind::Match(m, arms)
@@ -226,7 +226,7 @@ impl<'a> StripUnconfigured<'a> {
         }
     }
 
-    fn configure_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
+    pub fn configure_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
         self.visit_stmt_or_expr_attrs(expr.attrs());
 
         // If an expr is valid to cfg away it will have been removed by the
@@ -244,7 +244,7 @@ impl<'a> StripUnconfigured<'a> {
         self.process_cfg_attrs(expr)
     }
 
-    fn configure_stmt(&mut self, stmt: ast::Stmt) -> Option<ast::Stmt> {
+    pub fn configure_stmt(&mut self, stmt: ast::Stmt) -> Option<ast::Stmt> {
         self.visit_stmt_or_expr_attrs(stmt.attrs());
         self.configure(stmt)
     }
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 0986d32ff56..68aca3ee32f 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -208,14 +208,23 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
     }
 
     fn collect_invocations(&mut self, expansion: Expansion) -> (Expansion, Vec<Invocation>) {
-        let expansion = expansion.fold_with(&mut StripUnconfigured {
-            config: &self.cx.cfg,
-            should_test: self.cx.ecfg.should_test,
-            sess: self.cx.parse_sess,
-            features: self.cx.ecfg.features,
-        });
-        let mut collector = InvocationCollector { cx: self.cx, invocations: Vec::new() };
-        (expansion.fold_with(&mut collector), collector.invocations)
+        let crate_config = mem::replace(&mut self.cx.cfg, Vec::new());
+        let result = {
+            let mut collector = InvocationCollector {
+                cfg: StripUnconfigured {
+                    config: &crate_config,
+                    should_test: self.cx.ecfg.should_test,
+                    sess: self.cx.parse_sess,
+                    features: self.cx.ecfg.features,
+                },
+                cx: self.cx,
+                invocations: Vec::new(),
+            };
+            (expansion.fold_with(&mut collector), collector.invocations)
+        };
+
+        self.cx.cfg = crate_config;
+        result
     }
 
     fn expand_invoc(&mut self, invoc: Invocation) -> Expansion {
@@ -403,9 +412,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
 
 struct InvocationCollector<'a, 'b: 'a> {
     cx: &'a mut ExtCtxt<'b>,
+    cfg: StripUnconfigured<'a>,
     invocations: Vec<Invocation>,
 }
 
+macro_rules! fully_configure {
+    ($this:ident, $node:ident, $noop_fold:ident) => {
+        match $noop_fold($node, &mut $this.cfg).pop() {
+            Some(node) => node,
+            None => return SmallVector::zero(),
+        }
+    }
+}
+
 impl<'a, 'b> InvocationCollector<'a, 'b> {
     fn collect(&mut self, expansion_kind: ExpansionKind, kind: InvocationKind) -> Expansion {
         let mark = Mark::fresh();
@@ -475,11 +494,17 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
         }
         false
     }
+
+    fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
+        self.cfg.configure(node)
+    }
 }
 
 impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
     fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
-        let expr = expr.unwrap();
+        let mut expr = self.cfg.configure_expr(expr).unwrap();
+        expr.node = self.cfg.configure_expr_kind(expr.node);
+
         if let ast::ExprKind::Mac(mac) = expr.node {
             self.collect_bang(mac, expr.attrs.into(), expr.span, ExpansionKind::Expr).make_expr()
         } else {
@@ -488,7 +513,9 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
     }
 
     fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
-        let expr = expr.unwrap();
+        let mut expr = configure!(self, expr).unwrap();
+        expr.node = self.cfg.configure_expr_kind(expr.node);
+
         if let ast::ExprKind::Mac(mac) = expr.node {
             self.collect_bang(mac, expr.attrs.into(), expr.span, ExpansionKind::OptExpr)
                 .make_opt_expr()
@@ -511,6 +538,11 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
     }
 
     fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
+        let stmt = match self.cfg.configure_stmt(stmt) {
+            Some(stmt) => stmt,
+            None => return SmallVector::zero(),
+        };
+
         let (mac, style, attrs) = match stmt.node {
             StmtKind::Mac(mac) => mac.unwrap(),
             _ => return noop_fold_stmt(stmt, self),
@@ -540,9 +572,11 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
     }
 
     fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
+        let item = configure!(self, item);
+
         let (item, attr) = self.classify_item(item);
         if let Some(attr) = attr {
-            let item = Annotatable::Item(item);
+            let item = Annotatable::Item(fully_configure!(self, item, noop_fold_item));
             return self.collect_attr(attr, item, ExpansionKind::Items).make_items();
         }
 
@@ -610,9 +644,12 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
     }
 
     fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVector<ast::TraitItem> {
+        let item = configure!(self, item);
+
         let (item, attr) = self.classify_item(item);
         if let Some(attr) = attr {
-            let item = Annotatable::TraitItem(P(item));
+            let item =
+                Annotatable::TraitItem(P(fully_configure!(self, item, noop_fold_trait_item)));
             return self.collect_attr(attr, item, ExpansionKind::TraitItems).make_trait_items()
         }
 
@@ -626,9 +663,11 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
     }
 
     fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVector<ast::ImplItem> {
+        let item = configure!(self, item);
+
         let (item, attr) = self.classify_item(item);
         if let Some(attr) = attr {
-            let item = Annotatable::ImplItem(P(item));
+            let item = Annotatable::ImplItem(P(fully_configure!(self, item, noop_fold_impl_item)));
             return self.collect_attr(attr, item, ExpansionKind::ImplItems).make_impl_items();
         }
 
@@ -653,6 +692,14 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
             _ => unreachable!(),
         }
     }
+
+    fn fold_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod {
+        noop_fold_foreign_mod(self.cfg.configure_foreign_mod(foreign_mod), self)
+    }
+
+    fn fold_item_kind(&mut self, item: ast::ItemKind) -> ast::ItemKind {
+        noop_fold_item_kind(self.cfg.configure_item_kind(item), self)
+    }
 }
 
 pub struct ExpansionConfig<'feat> {
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 42201231247..4a2c9aff2d2 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -104,6 +104,7 @@ pub mod abi;
 pub mod ast;
 pub mod attr;
 pub mod codemap;
+#[macro_use]
 pub mod config;
 pub mod entry;
 pub mod feature_gate;