Rust: Rustc doesn't report line numbers for type errors within proc macro async fn within macro_rules macro

Created on 21 Jan 2020  路  10Comments  路  Source: rust-lang/rust

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

Meta

rustc --version --verbose: Tested on Playground with stable 1.40.0 and nightly 1.42.0 (2020-01-20)

A-async-await A-diagnostics A-macros A-proc-macros AsyncAwait-OnDeck AsyncAwait-Triaged C-bug D-terse P-high T-compiler

Most helpful comment

Taking a look at this.

All 10 comments

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

cuviper picture cuviper  路  3Comments

drewcrawford picture drewcrawford  路  3Comments

pedrohjordao picture pedrohjordao  路  3Comments

wthrowe picture wthrowe  路  3Comments

Robbepop picture Robbepop  路  3Comments