From 25c733360b1cddfc0b129680a9220d1d5097483d Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Tue, 17 May 2016 21:20:09 +0000 Subject: Update spans' `expn_id` during the marking fold --- src/libsyntax/ext/expand.rs | 76 ++++++++++++--------------------------------- 1 file changed, 20 insertions(+), 56 deletions(-) (limited to 'src/libsyntax/ext') diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 596faac3588..d66515ed7d6 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -18,7 +18,7 @@ use ext::build::AstBuilder; use attr; use attr::{AttrMetaMethods, WithAttrs, ThinAttributesExt}; use codemap; -use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute}; +use codemap::{Span, Spanned, ExpnInfo, ExpnId, NameAndSpan, MacroBang, MacroAttribute}; use ext::base::*; use feature_gate::{self, Features}; use fold; @@ -33,7 +33,6 @@ use visit::Visitor; use std_inject; use std::collections::HashSet; -use std::env; // A trait for AST nodes and AST node lists into which macro invocations may expand. trait MacroGenerable: Sized { @@ -160,10 +159,10 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { let new_node = ast::ExprKind::Closure(capture_clause, rewritten_fn_decl, rewritten_block, - fld.new_span(fn_decl_span)); + fn_decl_span); P(ast::Expr{ id:id, node: new_node, - span: fld.new_span(span), + span: span, attrs: fold_thin_attrs(attrs, fld) }) } @@ -322,7 +321,7 @@ fn expand_mac_invoc(mac: ast::Mac, ident: Option, attrs: Vec Folder for PatIdentRenamer<'a> { mtwt::apply_renames(self.renames, ident.ctxt)); let new_node = PatKind::Ident(binding_mode, - Spanned{span: self.new_span(sp), node: new_ident}, + Spanned{span: sp, node: new_ident}, sub.map(|p| self.fold_pat(p))); ast::Pat { id: id, node: new_node, - span: self.new_span(span) + span: span, } }, _ => unreachable!() @@ -774,7 +773,7 @@ fn expand_annotatable(a: Annotatable, } _ => unreachable!() }, - span: fld.new_span(ti.span) + span: ti.span, }) } _ => fold::noop_fold_trait_item(it.unwrap(), fld) @@ -914,7 +913,7 @@ fn expand_impl_item(ii: ast::ImplItem, fld: &mut MacroExpander) } _ => unreachable!() }, - span: fld.new_span(ii.span) + span: ii.span, }), ast::ImplItemKind::Macro(mac) => { expand_mac_invoc(mac, None, ii.attrs, ii.span, fld) @@ -1060,10 +1059,6 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { fn fold_ty(&mut self, ty: P) -> P { expand_type(ty, self) } - - fn new_span(&mut self, span: Span) -> Span { - new_span(self.cx, span) - } } impl<'a, 'b> MacroExpander<'a, 'b> { @@ -1081,45 +1076,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } -fn new_span(cx: &ExtCtxt, sp: Span) -> Span { - debug!("new_span(sp={:?})", sp); - - if cx.codemap().more_specific_trace(sp.expn_id, cx.backtrace()) { - // If the span we are looking at has a backtrace that has more - // detail than our current backtrace, then we keep that - // backtrace. Honestly, I have no idea if this makes sense, - // because I have no idea why we are stripping the backtrace - // below. But the reason I made this change is because, in - // deriving, we were generating attributes with a specific - // backtrace, which was essential for `#[structural_match]` to - // be properly supported, but these backtraces were being - // stripped and replaced with a null backtrace. Sort of - // unclear why this is the case. --nmatsakis - debug!("new_span: keeping trace from {:?} because it is more specific", - sp.expn_id); - sp - } else { - // This discards information in the case of macro-defining macros. - // - // The comment above was originally added in - // b7ec2488ff2f29681fe28691d20fd2c260a9e454 in Feb 2012. I - // *THINK* the reason we are doing this is because we want to - // replace the backtrace of the macro contents with the - // backtrace that contains the macro use. But it's pretty - // unclear to me. --nmatsakis - let sp1 = Span { - lo: sp.lo, - hi: sp.hi, - expn_id: cx.backtrace(), - }; - debug!("new_span({:?}) = {:?}", sp, sp1); - if sp.expn_id.into_u32() == 0 && env::var_os("NDM").is_some() { - panic!("NDM"); - } - sp1 - } -} - pub struct ExpansionConfig<'feat> { pub crate_name: String, pub features: Option<&'feat Features>, @@ -1206,8 +1162,9 @@ pub fn expand_crate(mut cx: ExtCtxt, // the ones defined here include: // Marker - add a mark to a context -// A Marker adds the given mark to the syntax context -struct Marker { mark: Mrk } +// A Marker adds the given mark to the syntax context and +// sets spans' `expn_id` to the given expn_id (unless it is `None`). +struct Marker { mark: Mrk, expn_id: Option } impl Folder for Marker { fn fold_ident(&mut self, id: Ident) -> Ident { @@ -1220,14 +1177,21 @@ impl Folder for Marker { tts: self.fold_tts(&node.tts), ctxt: mtwt::apply_mark(self.mark, node.ctxt), }, - span: span, + span: self.new_span(span), + } + } + + fn new_span(&mut self, mut span: Span) -> Span { + if let Some(expn_id) = self.expn_id { + span.expn_id = expn_id; } + span } } // apply a given mark to the given token trees. Used prior to expansion of a macro. fn mark_tts(tts: &[TokenTree], m: Mrk) -> Vec { - noop_fold_tts(tts, &mut Marker{mark:m}) + noop_fold_tts(tts, &mut Marker{mark:m, expn_id: None}) } /// Check that there are no macro invocations left in the AST: -- cgit 1.4.1-3-g733a5 From 1aa34e0b5fbdfcd8b176f97c748ee9be0e3c8eeb Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 16 May 2016 10:09:23 +0000 Subject: 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(-) (limited to 'src/libsyntax/ext') 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) } -- cgit 1.4.1-3-g733a5 From 0558df24af9d99894a8305a57303824d8b0c15ba Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Thu, 26 May 2016 23:48:45 +0000 Subject: Refactor `expand_expr` --- src/libsyntax/ext/expand.rs | 57 +++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 35 deletions(-) (limited to 'src/libsyntax/ext') diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 95d03b5018d..6cd5da9bc49 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -88,25 +88,24 @@ impl MacroGenerable for Option> { } } -pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { - return e.and_then(|ast::Expr {id, node, span, attrs}| match node { - +pub fn expand_expr(expr: ast::Expr, fld: &mut MacroExpander) -> P { + match expr.node { // expr_mac should really be expr_ext or something; it's the // entry-point for all syntax extensions. ast::ExprKind::Mac(mac) => { - expand_mac_invoc(mac, None, attrs.into_attr_vec(), span, fld) + expand_mac_invoc(mac, None, expr.attrs.into_attr_vec(), expr.span, fld) } ast::ExprKind::While(cond, body, opt_ident) => { let cond = fld.fold_expr(cond); let (body, opt_ident) = expand_loop_block(body, opt_ident, fld); - fld.cx.expr(span, ast::ExprKind::While(cond, body, opt_ident)) - .with_attrs(fold_thin_attrs(attrs, fld)) + fld.cx.expr(expr.span, ast::ExprKind::While(cond, body, opt_ident)) + .with_attrs(fold_thin_attrs(expr.attrs, fld)) } - ast::ExprKind::WhileLet(pat, expr, body, opt_ident) => { + ast::ExprKind::WhileLet(pat, cond, body, opt_ident) => { let pat = fld.fold_pat(pat); - let expr = fld.fold_expr(expr); + let cond = fld.fold_expr(cond); // Hygienic renaming of the body. let ((body, opt_ident), mut rewritten_pats) = @@ -118,14 +117,14 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { }); assert!(rewritten_pats.len() == 1); - let wl = ast::ExprKind::WhileLet(rewritten_pats.remove(0), expr, body, opt_ident); - fld.cx.expr(span, wl).with_attrs(fold_thin_attrs(attrs, fld)) + let wl = ast::ExprKind::WhileLet(rewritten_pats.remove(0), cond, body, opt_ident); + fld.cx.expr(expr.span, wl).with_attrs(fold_thin_attrs(expr.attrs, fld)) } ast::ExprKind::Loop(loop_block, opt_ident) => { let (loop_block, opt_ident) = expand_loop_block(loop_block, opt_ident, fld); - fld.cx.expr(span, ast::ExprKind::Loop(loop_block, opt_ident)) - .with_attrs(fold_thin_attrs(attrs, fld)) + fld.cx.expr(expr.span, ast::ExprKind::Loop(loop_block, opt_ident)) + .with_attrs(fold_thin_attrs(expr.attrs, fld)) } ast::ExprKind::ForLoop(pat, head, body, opt_ident) => { @@ -143,7 +142,7 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { let head = fld.fold_expr(head); let fl = ast::ExprKind::ForLoop(rewritten_pats.remove(0), head, body, opt_ident); - fld.cx.expr(span, fl).with_attrs(fold_thin_attrs(attrs, fld)) + fld.cx.expr(expr.span, fl).with_attrs(fold_thin_attrs(expr.attrs, fld)) } ast::ExprKind::IfLet(pat, sub_expr, body, else_opt) => { @@ -162,7 +161,7 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { let else_opt = else_opt.map(|else_opt| fld.fold_expr(else_opt)); let sub_expr = fld.fold_expr(sub_expr); let il = ast::ExprKind::IfLet(rewritten_pats.remove(0), sub_expr, body, else_opt); - fld.cx.expr(span, il).with_attrs(fold_thin_attrs(attrs, fld)) + fld.cx.expr(expr.span, il).with_attrs(fold_thin_attrs(expr.attrs, fld)) } ast::ExprKind::Closure(capture_clause, fn_decl, block, fn_decl_span) => { @@ -172,21 +171,14 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { rewritten_fn_decl, rewritten_block, fn_decl_span); - P(ast::Expr{ id:id, + P(ast::Expr{ id: expr.id, node: new_node, - span: span, - attrs: fold_thin_attrs(attrs, fld) }) + span: expr.span, + attrs: fold_thin_attrs(expr.attrs, fld) }) } - _ => { - P(noop_fold_expr(ast::Expr { - id: id, - node: node, - span: span, - attrs: attrs - }, fld)) - } - }); + _ => P(noop_fold_expr(expr, fld)), + } } /// Expand a macro invocation. Returns the result of expansion. @@ -1015,19 +1007,14 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { } fn fold_expr(&mut self, expr: P) -> P { - expand_expr(expr, self) + expr.and_then(|expr| 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 { + expr.and_then(|expr| match expr.node { ast::ExprKind::Mac(mac) => - expand_mac_invoc(mac, None, attrs.into_attr_vec(), span, self), - _ => unreachable!(), + expand_mac_invoc(mac, None, expr.attrs.into_attr_vec(), expr.span, self), + _ => Some(expand_expr(expr, self)), }) } -- cgit 1.4.1-3-g733a5