Skip to content

Commit 05baf64

Browse files
committed
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.
1 parent 99c2a6b commit 05baf64

File tree

2 files changed

+61
-6
lines changed

2 files changed

+61
-6
lines changed

src/libsyntax/codemap.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,31 @@ impl CodeMap {
13041304
return a;
13051305
}
13061306

1307+
/// Check if the backtrace `subtrace` contains `suptrace` as a prefix.
1308+
pub fn more_specific_trace(&self,
1309+
mut subtrace: ExpnId,
1310+
suptrace: ExpnId)
1311+
-> bool {
1312+
loop {
1313+
if subtrace == suptrace {
1314+
return true;
1315+
}
1316+
1317+
let stop = self.with_expn_info(subtrace, |opt_expn_info| {
1318+
if let Some(expn_info) = opt_expn_info {
1319+
subtrace = expn_info.call_site.expn_id;
1320+
false
1321+
} else {
1322+
true
1323+
}
1324+
});
1325+
1326+
if stop {
1327+
return false;
1328+
}
1329+
}
1330+
}
1331+
13071332
pub fn record_expansion(&self, expn_info: ExpnInfo) -> ExpnId {
13081333
let mut expansions = self.expansions.borrow_mut();
13091334
expansions.push(expn_info);

src/libsyntax/ext/expand.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use visit::Visitor;
3333
use std_inject;
3434

3535
use std::collections::HashSet;
36-
36+
use std::env;
3737

3838
pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
3939
let expr_span = e.span;
@@ -1275,11 +1275,41 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
12751275
}
12761276

12771277
fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
1278-
/* this discards information in the case of macro-defining macros */
1279-
Span {
1280-
lo: sp.lo,
1281-
hi: sp.hi,
1282-
expn_id: cx.backtrace(),
1278+
debug!("new_span(sp={:?})", sp);
1279+
1280+
if cx.codemap().more_specific_trace(sp.expn_id, cx.backtrace()) {
1281+
// If the span we are looking at has a backtrace that has more
1282+
// detail than our current backtrace, then we keep that
1283+
// backtrace. Honestly, I have no idea if this makes sense,
1284+
// because I have no idea why we are stripping the backtrace
1285+
// below. But the reason I made this change is because, in
1286+
// deriving, we were generating attributes with a specific
1287+
// backtrace, which was essential for `#[structural_match]` to
1288+
// be properly supported, but these backtraces were being
1289+
// stripped and replaced with a null backtrace. Sort of
1290+
// unclear why this is the case. --nmatsakis
1291+
debug!("new_span: keeping trace from {:?} because it is more specific",
1292+
sp.expn_id);
1293+
sp
1294+
} else {
1295+
// This discards information in the case of macro-defining macros.
1296+
//
1297+
// The comment above was originally added in
1298+
// b7ec2488ff2f29681fe28691d20fd2c260a9e454 in Feb 2012. I
1299+
// *THINK* the reason we are doing this is because we want to
1300+
// replace the backtrace of the macro contents with the
1301+
// backtrace that contains the macro use. But it's pretty
1302+
// unclear to me. --nmatsakis
1303+
let sp1 = Span {
1304+
lo: sp.lo,
1305+
hi: sp.hi,
1306+
expn_id: cx.backtrace(),
1307+
};
1308+
debug!("new_span({:?}) = {:?}", sp, sp1);
1309+
if sp.expn_id.into_u32() == 0 && env::var_os("NDM").is_some() {
1310+
panic!("NDM");
1311+
}
1312+
sp1
12831313
}
12841314
}
12851315

0 commit comments

Comments
 (0)