Closed
Description
A recursive macro can easily cause long useless error messages:
#![feature(macro_rules)]
macro_rules! go {
() => { fn main() { undefined } };
($_x:tt $($rest: tt)*) => {
go!($($rest)*)
}
}
go!(1 2 3 4 5 6 7 8 9 10)
<anon>:4:25: 4:34 error: unresolved name `undefined`.
<anon>:4 () => { fn main() { undefined } };
^~~~~~~~~
<anon>:3:1: 8:2 note: in expansion of go!
<anon>:6:9: 6:23 note: expansion site
<anon>:3:1: 8:2 note: in expansion of go!
<anon>:6:9: 6:23 note: expansion site
<anon>:3:1: 8:2 note: in expansion of go!
<anon>:6:9: 6:23 note: expansion site
<anon>:3:1: 8:2 note: in expansion of go!
<anon>:6:9: 6:23 note: expansion site
<anon>:3:1: 8:2 note: in expansion of go!
<anon>:6:9: 6:23 note: expansion site
<anon>:3:1: 8:2 note: in expansion of go!
<anon>:6:9: 6:23 note: expansion site
<anon>:3:1: 8:2 note: in expansion of go!
<anon>:6:9: 6:23 note: expansion site
<anon>:3:1: 8:2 note: in expansion of go!
<anon>:6:9: 6:23 note: expansion site
<anon>:3:1: 8:2 note: in expansion of go!
<anon>:6:9: 6:23 note: expansion site
<anon>:3:1: 8:2 note: in expansion of go!
<anon>:6:9: 6:23 note: expansion site
<anon>:3:1: 8:2 note: in expansion of go!
<anon>:10:1: 10:26 note: expansion site
error: aborting due to previous error
We could detect the repeating backtrace and replace it with:
<anon>:4:25: 4:34 error: unresolved name `undefined`.
<anon>:4 () => { fn main() { undefined } };
^~~~~~~~~
<anon>:3:1: 8:2 note: in expansion of go!
<anon>:6:9: 6:23 note: expansion site
[... 8 repeats ...]
<anon>:3:1: 8:2 note: in expansion of go!
<anon>:6:9: 6:23 note: expansion site
<anon>:3:1: 8:2 note: in expansion of go!
<anon>:10:1: 10:26 note: expansion site
error: aborting due to previous error
In the best case, this would detect sequences of mutually recursive macro invocations of any length, but 1 is almost certainly the most common case, and if not that, then 2. It should also only elide the identical frames.