Stack trace-friendly debug info for macros


Currently, rustc, by default, annotates lines of code expanded from a macro with the location information of the macro invocation rather than the location info of the lines in the macro definition. The rationale is that this way debuggers skip over code expanded from standard-library macros, which gives a better debugging experience most of the time for standard-library macros.

There is a (soon to be made nightly-only) option, -Zdebug-macros, that changes the behavior to annotate code expanded from macros with the location info from the macro definition. This makes it possible to do proper stepping in code that’s expanded from a macro.

However, if the use case is not debugging but collecting crash/panic stacks either from CI or from a released product in the field, neither option is ideal. To get proper attribution for code that’s expanded from macros in general, the -Zdebug-macros behavior would be preferable. However, when a panic/crash is triggered by an assertion you’d like to know which assertion invocation was triggered as opposed to just finding out that some assertion in a method that asserts many things fired. Using -Zdebug-macros loses this information.

So one approach does not fit all macros. I think it would be desirable to have a debug info mode that generally behaves like -Zdebug-macros but then assertion-like macros get the behavior that’s currently the default. An obvious hack would be to special-case the assertion-like macros from the standard library or even all standard-library macros.

However, such special-casing could easily be deemed inelegant. Another option that comes to mind would be a way to annotate a macro as assertion-like so that crates could define their own assertion macros that build on the standard-library macros and have the line numbers for those work just like they work for the standard-library assertion macros.

Does this seem reasonable? Would this kind of change to rustc (and the language to the extent the annotation would need some name) be acceptable?

(To the extent the motivation of the current default behavior is stepping into standard-library macros, maybe the new behavior described above wouldn’t even need to be a mode but could be the default or only behavior if the non-assertion standard-library macros were annotated to get the assertion-like behavior i.e. location debug info from invocation rather than definition.)


This feels very similar to the problem where .unwrap() panics start their stack trace with implementation details of unwrap(): Better panic location reporting for `unwrap()` and friends

I don’t think it’s possible to solve both of these problems in general without some kind of explicit annotation, so I’m wondering if we can have a single attribute like #[hide_impl_in_panic_stacks] that “just works” for both macros and methods.


RFC posted