How do I locate an error in an expanded macro?

Hi :slight_smile:

I'm trying to debug a function-like proc-macro, and I'm getting "error[E0782]: expected a type, found a trait" inside the macro expansion. How can I see where in the expanded macro this is happening?

Running cargo expand just dumps out everything (which, in my case, is a lot), but since the original error message contains no clue as to where in that giant pile of code the compiler expected a type instead of a trait, I don't know where to look.

I also tried RUSTFLAGS="-Zmacro-backtrace" cargo +nightly check as recommended by the error message, but that yields the same output as the original cargo check command.

Can you share some code?

Have you tried compiling the output of cargo expand? That should give you informations about where in the macro expansion the error is.

A quick-and-dirty approach that often works well is to copy/paste the generated code and compile it. Often, just copying it triggers the IDE's code awareness. (EDIT: @SkiFire13 beat me to it :slight_smile: )

Using rust-analyzer, you can select a single macro call and run “Inline macro” to replace the macro call with its expansion. This way, you get code that in most cases, will produce the same error when compiled because it’s in the same context. (Not all cases will work because macro hygiene can produce outcomes that cannot be expressed in plain code.)

Hmm.

>cat src\main.rs
macro_rules! foo {
    () => { bar!() }
}

macro_rules! bar {
    () => { some_error }
}

fn main() {
    foo!();
}
> set RUSTFLAGS=-Zmacro-backtrace
> cargo +nightly build
   Compiling rust-scratch v0.1.0 (D:\code\personal\rust-scratch)
error[E0425]: cannot find value `some_error` in this scope
  --> src\main.rs:6:13
   |
1  | / macro_rules! foo {
2  | |     () => { bar!() }
   | |             ------ in this macro invocation (#2)
3  | | }
   | |_- in this expansion of `foo!` (#1)
4  |
5  | / macro_rules! bar {
6  | |     () => { some_error }
   | |             ^^^^^^^^^^ not found in this scope
7  | | }
   | |_- in this expansion of `bar!` (#2)
...
10 |       foo!();
   |       ------ in this macro invocation (#1)

For more information about this error, try `rustc --explain E0425`.
error: could not compile `rust-scratch` (bin "rust-scratch") due to 1 previous error

Not sure why it wouldn't work for you?

OP said they have a proc macro, while your example shows a declarative macro.

2 Likes

Huh, does it just not work at all for proc macros? (Probably shouldn't suggest it in that case)