From 99c2a6b335d953eca64e631f3e9946b1cc6643e1 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 11 Mar 2016 13:27:42 -0500 Subject: modify #[deriving(Eq)] to emit #[structural_match] to careful use of the span from deriving, we can permit it in stable code if it derives from deriving (not-even-a-pun intended) --- src/libsyntax/feature_gate.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 299b7d8b9ba..8e7f4876ee2 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -109,6 +109,8 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option, Status // to bootstrap fix for #5723. ("issue_5723_bootstrap", "1.0.0", None, Accepted), + ("structural_match", "1.8.0", Some(31434), Active), + // A way to temporarily opt out of opt in copy. This will *never* be accepted. ("opt_out_copy", "1.0.0", None, Removed), @@ -304,6 +306,11 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGat ("link_args", Normal, Ungated), ("macro_escape", Normal, Ungated), + // RFC #1445. + ("structural_match", Whitelisted, Gated("structural_match", + "the semantics of constant patterns is \ + not yet settled")), + // Not used any more, but we can't feature gate it ("no_stack_check", Normal, Ungated), @@ -676,7 +683,7 @@ impl<'a> Context<'a> { fn gate_feature(&self, feature: &str, span: Span, explain: &str) { let has_feature = self.has_feature(feature); debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", feature, span, has_feature); - if !has_feature { + if !has_feature && !self.cm.span_allows_unstable(span) { emit_feature_err(self.span_handler, feature, span, GateIssue::Language, explain); } } -- cgit 1.4.1-3-g733a5 From 05baf645e47a0ed3893f2413696e56be180249ff Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 11 Mar 2016 13:29:06 -0500 Subject: do not overwrite spans as eagerly this was required to preserve the span from the #[structural_match] attribute -- but honestly I am not 100% sure if it makes sense. --- src/libsyntax/codemap.rs | 25 +++++++++++++++++++++++++ src/libsyntax/ext/expand.rs | 42 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 61 insertions(+), 6 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 804ca6705ec..f771ee95bd1 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -1304,6 +1304,31 @@ impl CodeMap { return a; } + /// Check if the backtrace `subtrace` contains `suptrace` as a prefix. + pub fn more_specific_trace(&self, + mut subtrace: ExpnId, + suptrace: ExpnId) + -> bool { + loop { + if subtrace == suptrace { + return true; + } + + let stop = self.with_expn_info(subtrace, |opt_expn_info| { + if let Some(expn_info) = opt_expn_info { + subtrace = expn_info.call_site.expn_id; + false + } else { + true + } + }); + + if stop { + return false; + } + } + } + pub fn record_expansion(&self, expn_info: ExpnInfo) -> ExpnId { let mut expansions = self.expansions.borrow_mut(); expansions.push(expn_info); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 5bfdab791d6..8550617560d 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -33,7 +33,7 @@ use visit::Visitor; use std_inject; use std::collections::HashSet; - +use std::env; pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { let expr_span = e.span; @@ -1275,11 +1275,41 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } fn new_span(cx: &ExtCtxt, sp: Span) -> Span { - /* this discards information in the case of macro-defining macros */ - Span { - lo: sp.lo, - hi: sp.hi, - expn_id: cx.backtrace(), + 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 } } -- cgit 1.4.1-3-g733a5