From 1aa34e0b5fbdfcd8b176f97c748ee9be0e3c8eeb Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 16 May 2016 10:09:23 +0000 Subject: [PATCH] Strip unconfigured items during macro expansion --- src/librustc_driver/driver.rs | 9 --------- src/libsyntax/config.rs | 19 ++++++++++++------- src/libsyntax/ext/expand.rs | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 1f3df1ff6f2..48b86d862f5 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -720,16 +720,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, ret }); - // JBC: make CFG processing part of expansion to avoid this problem: - - // strip again, in case expansion added anything with a #[cfg]. krate = sess.track_errors(|| { - let krate = time(time_passes, "configuration 2", || { - syntax::config::strip_unconfigured_items(sess.diagnostic(), - krate, - &mut feature_gated_cfgs) - }); - time(time_passes, "gated configuration checking", || { let features = sess.features.borrow(); feature_gated_cfgs.sort(); 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) + -> Self { + StripUnconfigured { + config: config, + diag: CfgDiagReal { diag: diagnostic, feature_gated_cfgs: feature_gated_cfgs }, + } + } + fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Option { 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) -> 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 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> { + fn kind_name() -> &'static str { "expression" } + fn dummy(_span: Span) -> Self { None } + fn make_with<'a>(result: Box) -> Option { + result.make_expr().map(Some) + } + fn fold_with(self, folder: &mut F) -> Self { + self.and_then(|expr| folder.fold_opt_expr(expr)) + } +} + pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { return e.and_then(|ast::Expr {id, node, span, attrs}| match node { @@ -322,7 +334,8 @@ fn expand_mac_invoc(mac: ast::Mac, ident: Option, attrs: Vec 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) -> Option> { + 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) -> P { expand_pat(pat, self) }