diff options
| author | bors <bors@rust-lang.org> | 2015-04-12 06:48:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-04-12 06:48:28 +0000 |
| commit | feeb23d42e0b1bc6f0466d4c6f035cfc3a4e9718 (patch) | |
| tree | 4acbbacbb3f8c2633b3bcfe79658f55db9a4f900 /src/libsyntax | |
| parent | 03f563a0e01bed68a44bf1fab946e0b6620bc153 (diff) | |
| parent | ddbdf51f394226bcae162ed2d5348126b32e7dbd (diff) | |
| download | rust-feeb23d42e0b1bc6f0466d4c6f035cfc3a4e9718.tar.gz rust-feeb23d42e0b1bc6f0466d4c6f035cfc3a4e9718.zip | |
Auto merge of #24003 - rprichard:span-fixes, r=huonw
* In `noop_fold_expr`, call `new_span` in these cases:
- `ExprMethodCall`'s identifier
- `ExprField`'s identifier
- `ExprTupField`'s integer
Calling `new_span` for `ExprMethodCall`'s identifier is necessary to print
an acceptable diagnostic for `write!(&2, "")`. We see this error:
```
<std macros>:2:20: 2:66 error: type `&mut _` does not implement any method in scope named `write_fmt`
<std macros>:2 ( & mut * $ dst ) . write_fmt ( format_args ! ( $ ( $ arg ) * ) ) )
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
With this change, we also see a macro expansion backtrace leading to
the `write!(&2, "")` call site.
* After fully expanding a macro, we replace the expansion expression's
span with the original span. Call `fld.new_span` to add a backtrace to
this span. (Note that I'm call `new_span` after `bt.pop()`, so the macro
just expanded isn't on the backtrace.)
The motivating example for this change is `println!("{}")`. The format
string literal is `concat!($fmt, "arg")` and is inside the libstd macro.
We need to see the backtrace to find the `println!` call site.
* Add a backtrace to the `format_args!` format expression span.
r? alexcrichton
Addresses #23459
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/codemap.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/diagnostic.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/format.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/log_syntax.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 8 |
7 files changed, 16 insertions, 23 deletions
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 7635c8eadc2..5bbf79d0477 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -871,7 +871,7 @@ impl CodeMap { F: FnOnce(Option<&ExpnInfo>) -> T, { match id { - NO_EXPANSION => f(None), + NO_EXPANSION | COMMAND_LINE_EXPN => f(None), ExpnId(i) => f(Some(&(*self.expansions.borrow())[i as usize])) } } diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index ed7bdcd898e..f3715d765e3 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -465,22 +465,21 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan, match rsp { FullSpan(_) => { try!(highlight_lines(dst, cm, sp, lvl, cm.span_to_lines(sp))); + try!(print_macro_backtrace(dst, cm, sp)); } EndSpan(_) => { try!(end_highlight_lines(dst, cm, sp, lvl, cm.span_to_lines(sp))); + try!(print_macro_backtrace(dst, cm, sp)); } Suggestion(_, ref suggestion) => { try!(highlight_suggestion(dst, cm, sp, suggestion)); + try!(print_macro_backtrace(dst, cm, sp)); } FileLine(..) => { // no source text in this case! } } - if sp != COMMAND_LINE_SP { - try!(print_macro_backtrace(dst, cm, sp)); - } - match code { Some(code) => match dst.registry.as_ref().and_then(|registry| registry.find_description(code)) { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 346fb3580e1..9994fad3e31 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -605,7 +605,6 @@ impl<'a> ExtCtxt<'a> { None => self.bug("missing top span") }) } - pub fn print_backtrace(&self) { } pub fn backtrace(&self) -> ExpnId { self.backtrace } pub fn original_span(&self) -> Span { let mut expn_id = self.backtrace; @@ -700,7 +699,6 @@ impl<'a> ExtCtxt<'a> { /// substitute; we never hit resolve/type-checking so the dummy /// value doesn't have to match anything) pub fn span_fatal(&self, sp: Span, msg: &str) -> ! { - self.print_backtrace(); panic!(self.parse_sess.span_diagnostic.span_fatal(sp, msg)); } @@ -710,35 +708,27 @@ impl<'a> ExtCtxt<'a> { /// Compilation will be stopped in the near future (at the end of /// the macro expansion phase). pub fn span_err(&self, sp: Span, msg: &str) { - self.print_backtrace(); self.parse_sess.span_diagnostic.span_err(sp, msg); } pub fn span_warn(&self, sp: Span, msg: &str) { - self.print_backtrace(); self.parse_sess.span_diagnostic.span_warn(sp, msg); } pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! { - self.print_backtrace(); self.parse_sess.span_diagnostic.span_unimpl(sp, msg); } pub fn span_bug(&self, sp: Span, msg: &str) -> ! { - self.print_backtrace(); self.parse_sess.span_diagnostic.span_bug(sp, msg); } pub fn span_note(&self, sp: Span, msg: &str) { - self.print_backtrace(); self.parse_sess.span_diagnostic.span_note(sp, msg); } pub fn span_help(&self, sp: Span, msg: &str) { - self.print_backtrace(); self.parse_sess.span_diagnostic.span_help(sp, msg); } pub fn fileline_help(&self, sp: Span, msg: &str) { - self.print_backtrace(); self.parse_sess.span_diagnostic.fileline_help(sp, msg); } pub fn bug(&self, msg: &str) -> ! { - self.print_backtrace(); self.parse_sess.span_diagnostic.handler().bug(msg); } pub fn trace_macros(&self) -> bool { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 5f4ec01791c..b65798b8a49 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -55,7 +55,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> { fully_expanded.map(|e| ast::Expr { id: ast::DUMMY_NODE_ID, node: e.node, - span: span, + span: fld.new_span(span), }) } diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 1d99a475b32..513bbf6c77b 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -17,6 +17,7 @@ use ext::base::*; use ext::base; use ext::build::AstBuilder; use fmt_macros as parse; +use fold::Folder; use parse::token::special_idents; use parse::token; use ptr::P; @@ -649,6 +650,10 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, names: HashMap<String, P<ast::Expr>>) -> P<ast::Expr> { let arg_types: Vec<_> = (0..args.len()).map(|_| None).collect(); + // Expand the format literal so that efmt.span will have a backtrace. This + // is essential for locating a bug when the format literal is generated in + // a macro. (e.g. println!("{}"), which uses concat!($fmt, "\n")). + let efmt = ecx.expander().fold_expr(efmt); let mut cx = Context { ecx: ecx, args: args, @@ -663,9 +668,8 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, pieces: Vec::new(), str_pieces: Vec::new(), all_pieces_simple: true, - fmtsp: sp, + fmtsp: efmt.span, }; - cx.fmtsp = efmt.span; let fmt = match expr_to_string(cx.ecx, efmt, "format argument must be a string literal.") { diff --git a/src/libsyntax/ext/log_syntax.rs b/src/libsyntax/ext/log_syntax.rs index 8173dd93f74..9869108952c 100644 --- a/src/libsyntax/ext/log_syntax.rs +++ b/src/libsyntax/ext/log_syntax.rs @@ -26,8 +26,6 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt, return base::DummyResult::any(sp); } - cx.print_backtrace(); - println!("{}", print::pprust::tts_to_string(tts)); // any so that `log_syntax` can be invoked as an expression and item. diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index d4451cc7b71..d7033ce7e48 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1176,7 +1176,7 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) -> } ExprMethodCall(i, tps, args) => { ExprMethodCall( - respan(i.span, folder.fold_ident(i.node)), + respan(folder.new_span(i.span), folder.fold_ident(i.node)), tps.move_map(|x| folder.fold_ty(x)), args.move_map(|x| folder.fold_expr(x))) } @@ -1246,11 +1246,13 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) -> } ExprField(el, ident) => { ExprField(folder.fold_expr(el), - respan(ident.span, folder.fold_ident(ident.node))) + respan(folder.new_span(ident.span), + folder.fold_ident(ident.node))) } ExprTupField(el, ident) => { ExprTupField(folder.fold_expr(el), - respan(ident.span, folder.fold_usize(ident.node))) + respan(folder.new_span(ident.span), + folder.fold_usize(ident.node))) } ExprIndex(el, er) => { ExprIndex(folder.fold_expr(el), folder.fold_expr(er)) |
