Use of ty macro non-terminal in trait bounds
2fc4b59
Opened by Stuart Glaser at
macro_rules! impl_somethingable {
($Base: ty, $Block:ty) => {
impl<'a, T> Somethingable for $Block where T: $Base {
}
}
}
impl_somethingable!(ATrait, A);
<anon>:15:52: 15:60 error: each predicate in a `where` clause must have at least one bound in it
<anon>:15 impl<'a, T> Somethingable for $Block where T: $Base {
^~~~~~~~
<anon>:15:56: 15:60 error: expected one of `,` or `{`, found `ATrait`
<anon>:15 impl<'a, T> Somethingable for $Block where T: $Base {
^~~~
The solution is to use $ident instead of $ty, but this is non-obvious to the user, especially since it's perfectly ok to have ATrait in that location.
Playpen: http://is.gd/AMUJDw
cc @huonw
Triage: still an issue.
Huon Wilson at 2015-11-18 06:49:29
Current output, still doesn't point at the possibility of changing
$Base:error: expected one of `(`, `,`, `?`, `for`, `{`, lifetime, or path, found `ATrait` --> src/main.rs:4:55 | 4 | impl<'a, T> Somethingable for $Block where T: $Base { | ^^^^^ expected one of 7 possible tokens here ... 9 | impl_somethingable!(ATrait, A); | ------------------------------- in this macro invocationEsteban Kuber at 2017-08-10 17:05:32
I removed <kbd>A-diagnostics</kbd> because I would like the original code using $:ty to work as written. Refusing to treat $:ty containing path as a trait bound is an unnecessary limitation.
David Tolnay at 2018-06-09 19:36:31
Also
identis not always a possible solution, like if I modify the example slightly:trait ATrait { type AType; } macro_rules! impl_somethingable { ($Base: ident, $Block:ty) => { impl<'a, T> Somethingable for $Block where T: $Base { } } } impl_somethingable!(ATrait<AType=u32>, A);diwic at 2018-06-17 08:30:49