Description
We take particular care to make sure that compilation errors associated with the items to which our attribute macros are applied are comprehensible. To that end we have tests to check the output of a variety of expected illegal programs to make sure developers could reasonably be expected to understand and correct those errors. In 1.46.0 we noticed a change in that behavior. While there were some beneficial changes to the way errors qualify structs, traits, etc. there seems to be a regression where 1.46.0 shows less information than in 1.45.0
I've put together a small repo that demonstrates the problem: https://github.com/ahl/span_regression
The first example is this macro:
#[proc_macro_attribute]
pub fn identity(
_attr: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
item
}
Now consider this test program:
struct Thing {
x: i32,
y: i32,
}
#[identity]
fn doit() -> Thing {
Thing {
"howdy".to_string(),
}
}
Under 1.45.0 one of the errors produced looks like this:
error[E0063]: missing fields `x`, `y` in initializer of `Thing`
--> examples/test.rs:10:5
|
10 | Thing {
| ^^^^^ missing `x`, `y`
Under 1.46.0 that has changed to this:
error[E0063]: missing fields `x`, `y` in initializer of `Thing`
Note that under 1.46.0 no code is underlined.
Now consider a slightly more complicated macro:
#[proc_macro_attribute]
pub fn nested(
_attr: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
let mut ret = proc_macro::TokenStream::new();
let pre = vec![
proc_macro::TokenTree::Ident(proc_macro::Ident::new("fn", proc_macro::Span::call_site())),
proc_macro::TokenTree::Ident(proc_macro::Ident::new("foo", proc_macro::Span::call_site())),
proc_macro::TokenTree::Group(proc_macro::Group::new(
proc_macro::Delimiter::Parenthesis,
proc_macro::TokenStream::new(),
)),
proc_macro::TokenTree::Group(proc_macro::Group::new(proc_macro::Delimiter::Brace, item)),
];
ret.extend(pre);
ret
}
(Note I had been using quote!
but wanted to make sure that wasn't causing the problem)
With a similar example as above on 1.45.0:
error: expected identifier, found `"yo"`
--> examples/test.rs:20:9
|
19 | Thing {
| ----- while parsing this struct
20 | "yo".to_string(),
| ^^^^ expected identifier
With 1.46.0:
error[E0308]: mismatched types
--> examples/test.rs:17:1
|
17 | #[nested]
| ^^^^^^^^^
| |
| expected struct `Thing`, found `()`
| expected `Thing` because of return type
Rather than pointing to the offending code, the rustc error now points (unhelpfully) to the macro itself.
The general improvements made to error reporting in 1.46.0 (simpler naming, reduced duplicate errors) is greatly appreciated. This was one small regression I saw amongst the otherwise monotonic improvements.