Propagate macro backtraces more often, improve formatting diagnostics
* 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.
Addresses #23459
This commit is contained in:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user