-
Notifications
You must be signed in to change notification settings - Fork 14k
Propagate macro backtraces more often, improve formatting diagnostics #24003
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
r? @pcwalton (rust_highfive has picked a reviewer for you, use r? to override) |
|
It occurs to me that #23459 actually had a much better motivating example than |
|
Great! Could you add some tests for these? E.g. for the macro_rules! foo { //~ NODE in expansion of
() => {
1.fake(); //~ ERROR does not implement any method
}
}
fn main() {
foo!(); //~ NOTE expansion site
}Similarly one could have |
|
Yes, I can add some tests. |
|
I added new tests:
|
|
I've noticed that the backtraces introduced with this PR can appear repeatedly: The second two backtraces are obnoxious. I suspect the fix is for I'm also wondering about the first Also: |
I agree.
We haven't been very good about using |
src/libsyntax/diagnostic.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, could you add a brief comment about this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's some code a few lines up doing the same sort of sp.expn_id to COMMAND_LINE_EXPN comparison:
// We cannot check equality directly with COMMAND_LINE_SP
// since PartialEq is manually implemented to ignore the ExpnId
let ss = if sp.expn_id == COMMAND_LINE_EXPN {
...
I'll factor out the sp.expn_id == COMMAND_LINE_EXPN to a local variable and put the comment there.
|
Looks good, r=me with one little comment. |
|
☔ The latest upstream changes (presumably #23857) made this pull request unmergeable. Please resolve the merge conflicts. |
|
There seems to be a general problem where we don't output macro backtraces until after the expansion phase. The macro_rules! format_template {
($tmp:tt) => (format!($tmp, a=123, b=456))
}
fn main() {
format_template!("{a}{b}");
format_template!("{a}");
format_template!("{a}{b}");
format_template!("{a}");
} |
|
@huonw I rebased my changes, factored out a |
|
☔ The latest upstream changes (presumably #24328) made this pull request unmergeable. Please resolve the merge conflicts. |
* 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 rust-lang#23459
It was added in 2011-08-05 and reduced to a no-op ten days later.
|
@huonw I rebased my PR to account for @nikomatsakis's diagnostic improvements. I rewrote the |
|
@bors r+ |
|
📌 Commit ddbdf51 has been approved by |
* 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
In
noop_fold_expr, callnew_spanin these cases:ExprMethodCall's identifierExprField's identifierExprTupField's integerCalling
new_spanforExprMethodCall's identifier is necessary to printan acceptable diagnostic for
write!(&2, ""). We see this error: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_spanto add a backtrace tothis span. (Note that I'm call
new_spanafterbt.pop(), so the macrojust expanded isn't on the backtrace.)
The motivating example for this change is
println!("{}"). The formatstring 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