I am not a heavy macro user, so it always takes me a while to wrap my mind around the interactions between macros and scoping. For example, I recently scratched my head on an elaborate variation of this mistake:
macro_rules! scoped {
($GenericType:ident) => {
mod inner {
type BoolInstance = $GenericType<bool>;
}
}
}
/* ...somewhere in a different code module... */
type MyVec<T> = Vec<T>;
scoped!(MyVec);
Which produces the following error message:
error[E0412]: cannot find type `MyVec` in this scope
--> src/main.rs:10:9
|
10 | scoped!(MyVec);
| ^^^^^ not found in this scope
error: aborting due to previous error
Most likely a heavier macro user would have instantly figured out that a super:: is needed before the $GenericType in the macro definition. But in this particular case, I found myself wishing that the compiler could point out that the error is in the expanded code, and not in the way I call the macro.
After all, a manually inlined variant of the above…
type MyVec<T> = Vec<T>;
mod inner {
type BoolInstance = MyVec<bool>;
}
…produces a much more helpful error message:
error[E0412]: cannot find type `MyVec` in this scope
--> src/main.rs:4:25
|
4 | type BoolInstance = MyVec<bool>;
| ^^^^^ not found in this scope
help: possible candidate is found in another module, you can import it into scope
|
4 | use MyVec;
|
error: aborting due to previous error
So I guess my wish would be that when there is a problem in a macro instantiation, rustc could at least display both the macro call site and the expanded code. As an example of prior art, GCC does a variant of the above for C/++ macros ("<points out error in expanded code> ...in expansion of macro... <points out macro call site>").