When using a macro to generate an async fn with a proc macro inside it, if the generated function includes a type error, rustc will not report any line number information. This makes finding and debugging type errors in large async applications extremely difficult.
I tried this code:
async fn foo() {}
macro_rules! gen_test {
($before:expr) => {
#[tokio::test]
async fn test_foo() {
$before;
let x: () = foo();
}
}
}
gen_test!(dbg!(4));
I expected to see this happen:
Error including line number information (you will get this output if you just comment out the $beforeline in the test fn)
error[E0308]: mismatched types
--> src/lib.rs:8:25
|
8 | let x: () = foo();
| ^^^^^
| |
| expected (), found opaque type
| help: consider using `.await` here: `foo().await`
...
13 | gen_test!(dbg!(4));
| ------------------- in this macro invocation
|
= note: expected type `()`
found type `impl std::future::Future`
Instead, this happened:
Error including no line number information
error[E0308]: mismatched types
|
= note: expected type `()`
found type `impl std::future::Future`
error: aborting due to previous error
rustc --version --verbose: Tested on Playground with stable 1.40.0 and nightly 1.42.0 (2020-01-20)
I can also add that incorrect line information is reported for panics, it's says src/main.rs:1:1 instead of the actual file and line.
thread 'tests::test_get_all_files_query_encoded' panicked at 'assertion failed: path.is_dir() || path.extension().unwrap() == "vwxp"', src\main.rs:1:1
cc @petrochenkov @eddyb
I'm seeing the same thing, at the trait/impl level. I have a macro that wraps async_trait (and can only be applied to trait defs or impls):
pub fn async_sync_trait(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as Args);
let mut item = parse_macro_input!(input as Item);
// Adds some methods
expand(&mut item, args.local);
if args.local {
TokenStream::from(quote! {
#[async_trait::async_trait(?Send)]
#item
})
} else {
TokenStream::from(quote! {
#[async_trait::async_trait]
#item
})
}
}
If I don't emit the #[async_trait::async_trait] attribute, line numbers work fine. If I don't use my macro at all and only use async_trait, line numbers work fine. The act of one macro emitting another seems to be the problem.
[triagebot] Can't say anything without investigating, won't investigate due to low priority.
I'm having this problem too. I made a repo with a minimal reproduction FWIW.
I'm not sure if this completely explains the problem, but in this repo I defined two trivial proc macro attributes, one which spits out the code unchanged (#[noop]), another which quotes the code and then spits that out unchanged ([#quoter]). I tried various combinations of these two macros, and all of them preserve line numbers for type errors except when applying noop and then quoter. Here is the line that demonstrates the combination that causes line numbers to be erased: https://github.com/maackle/nested-proc-macro-mcve/blob/master/app/src/main.rs#L21
@petrochenkov It's P-high now, I posted a small repro in another issue: https://github.com/rust-lang/rust/issues/51635#issuecomment-622385097 That doesn't need anything async to show this behavior, so it might just be more general.
Taking a look at this.
triage: visited as part of general query of unassigned P-high non-ICE issues. But it looks like @nellshamrell is taking a look at this, so I'm marking as assigned to nell for now.
Hello all - looking at my list of things to do, I realized I'm not going to be able to get to this in the immediate future. Taking my name off the issue for now so someone else can pick it up if they have time before I do.
This looks like another instance of https://github.com/rust-lang/rust/issues/43081
Most helpful comment
Taking a look at this.