about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/config.rs19
-rw-r--r--src/libsyntax/ext/expand.rs34
2 files changed, 45 insertions, 8 deletions
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index e1c17ca43d3..77f20934d80 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -38,6 +38,16 @@ pub struct StripUnconfigured<'a> {
 }
 
 impl<'a> StripUnconfigured<'a> {
+    pub fn new(config: &'a ast::CrateConfig,
+               diagnostic: &'a Handler,
+               feature_gated_cfgs: &'a mut Vec<GatedCfgAttr>)
+               -> Self {
+        StripUnconfigured {
+            config: config,
+            diag: CfgDiagReal { diag: diagnostic, feature_gated_cfgs: feature_gated_cfgs },
+        }
+    }
+
     fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
         if !attr.check_name("cfg_attr") {
             return Some(attr);
@@ -121,13 +131,8 @@ pub fn strip_unconfigured_items(diagnostic: &Handler, krate: ast::Crate,
                                 feature_gated_cfgs: &mut Vec<GatedCfgAttr>)
                                 -> ast::Crate
 {
-    StripUnconfigured {
-        config: &krate.config.clone(),
-        diag: CfgDiagReal {
-            diag: diagnostic,
-            feature_gated_cfgs: feature_gated_cfgs,
-        },
-    }.fold_crate(krate)
+    let config = &krate.config.clone();
+    StripUnconfigured::new(config, diagnostic, feature_gated_cfgs).fold_crate(krate)
 }
 
 impl<T: CfgFolder> fold::Folder for T {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index d66515ed7d6..95d03b5018d 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -19,6 +19,7 @@ use attr;
 use attr::{AttrMetaMethods, WithAttrs, ThinAttributesExt};
 use codemap;
 use codemap::{Span, Spanned, ExpnInfo, ExpnId, NameAndSpan, MacroBang, MacroAttribute};
+use config::StripUnconfigured;
 use ext::base::*;
 use feature_gate::{self, Features};
 use fold;
@@ -76,6 +77,17 @@ impl_macro_generable! {
         "statement", .make_stmts,      lift .fold_stmt,      |_span| SmallVector::zero();
 }
 
+impl MacroGenerable for Option<P<ast::Expr>> {
+    fn kind_name() -> &'static str { "expression" }
+    fn dummy(_span: Span) -> Self { None }
+    fn make_with<'a>(result: Box<MacResult + 'a>) -> Option<Self> {
+        result.make_expr().map(Some)
+    }
+    fn fold_with<F: Folder>(self, folder: &mut F) -> Self {
+        self.and_then(|expr| folder.fold_opt_expr(expr))
+    }
+}
+
 pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
     return e.and_then(|ast::Expr {id, node, span, attrs}| match node {
 
@@ -322,7 +334,8 @@ fn expand_mac_invoc<T>(mac: ast::Mac, ident: Option<Ident>, attrs: Vec<ast::Attr
     };
 
     let marked = expanded.fold_with(&mut Marker { mark: mark, expn_id: Some(fld.cx.backtrace()) });
-    let fully_expanded = marked.fold_with(fld);
+    let configured = marked.fold_with(&mut fld.strip_unconfigured());
+    let fully_expanded = configured.fold_with(fld);
     fld.cx.bt_pop();
     fully_expanded
 }
@@ -987,6 +1000,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
     pub fn new(cx: &'a mut ExtCtxt<'b>) -> MacroExpander<'a, 'b> {
         MacroExpander { cx: cx }
     }
+
+    fn strip_unconfigured(&mut self) -> StripUnconfigured {
+        StripUnconfigured::new(&self.cx.cfg,
+                               &self.cx.parse_sess.span_diagnostic,
+                               self.cx.feature_gated_cfgs)
+    }
 }
 
 impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
@@ -999,6 +1018,19 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
         expand_expr(expr, self)
     }
 
+    fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
+        match expr.node {
+            ast::ExprKind::Mac(_) => {}
+            _ => return Some(expand_expr(expr, self)),
+        }
+
+        expr.and_then(|ast::Expr {node, span, attrs, ..}| match node {
+            ast::ExprKind::Mac(mac) =>
+                expand_mac_invoc(mac, None, attrs.into_attr_vec(), span, self),
+            _ => unreachable!(),
+        })
+    }
+
     fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
         expand_pat(pat, self)
     }