The -Z macro-backtrace is not a flag for cargo, nor for the integration tests binary, but for rustc.
Hence:
The command
RUSTFLAGS=-Zmacro-backtrace cargo …
is the best way to achieve this.
If the cargo command is something as simple as check (or checking the unit tests), then you can run
cargo rustc -- -Zmacro-backtrace # --cfg test # (to check the unit tests)
This may be a bit faster to compiler since it won't change the RUSTFLAGS used to compile the dependencies, thus not invalidating the cached compilation artifacts for them.
An unstable flag
Finally, note that -Z macro-backtrace is an unstable feature.
If you are developing on a machine with no nightly available, but want really hard to be able to debug these macros, then you can use the super unstable RUSTC_BOOTSTRAP=1 to temporarily imbue your current cargo toolchain with unstable capabilities. But do not do this on production nor CI, of course.
Bonus: other macro debugging tips
There are several kinds of errors one can have when writing macros:
If you are dealing with a complex recursive macro
or even, just a chain of macro invocations, with a problematic invocation in the middle.
In that case, I suggest trace_macros! be used:
Write trace_macros!(true); before the problematic macro invocation (with an optional trace_macros!(false);after it, to reduce the noise from tracing unrelated macros).
If the macro expands to syntactically invalid / rejected-by-the-parser code:
trace_macros! can still be useful, although a big expansion will hardly be readable in that format;
You can use log_syntax! { … } to enscope the output of the macro:
call {e,}println!(…) on the output TokenStream{,2}.
The macro expands to semantically invalid code:
-Z macro-backtrace
can indeed be useful here to help you pin-point the problematic code inside the macro definition;
Otherwise, a good old expansion of the emitted code will be very welcome. Ideally, this is done through:
cargo expand
should it be installed, else:
# Should use `cargo +nightly`, but if you don't have it installed,
# you might get away with hackily forcing the nightly mode
# (don't use in production, only when dev-debugging!)
RUSTC_BOOTSTRAP=1 \
cargo rustc --profile=check -- -Z unpretty=expanded
In both cases replacing the macro invocation with the copy-pasted code may provide better-spanned / detailed error messages
When manually pasting the expanded code, the error disappears
This means your macro has one of the two following issues:
Hygiene: you may be trying to have caller-provided code refer to an internal-to-the-macro / macro-defined variable, or vice versa. This currently only applies to local variables (and, technically, to lifetimes and $crate);