Closed
Description
Consider the following example (from term-painter):
macro_rules! impl_format {
($symbol:expr, $fmt:ident) => {
impl<T: fmt::$fmt> fmt::$fmt for Painted<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
panic!()
}
}
}
}
impl_format!("{}", Display);
On the third line are two paths of the form fmt::$fmt
, after expansion, these are both fmt::Display
. The way spans for paths are calculated we take the start of fmt
and the end of Display
(see parse_path
in parser.rs), this means the span for the path is 9 lines long and pretty incoherent. Annoyingly, this span does not get an expansion id, and thus has no indication that it came from generated code. This is visible in error messages:
|
9 | impl<T: fmt::$fmt> fmt::$fmt for Painted<T> {
| _________________^ starting here...
10 | | fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
11 | | panic!()
12 | | }
13 | | }
14 | | }
15 | | }
16 | |
17 | | impl_format!("{}", Display);
| | -------------------------^--
| |_|________________________|
| | ...ending here
| in this macro invocation