Description
macro_rules! m {
($my_type: ty) => {
impl $my_type for u8 {} // Hmmm.
// Not OK, this trick can't be used in any other position.
// trait Z: $my_type {}
}
}
trait Tr {}
m!(Tr); // OK
fn main() {}
This is a side effect of how impls are parsed - the trait in impl Trait for Type
is first parsed as a type, and then reinterpreted as a type if it has appropriate syntactic form (trait syntax is a subset of type syntax).
(Same trick was used for pub(path)
visibilities for some time, but then abandoned in favor of pub(in path)
.)
The reinterpretation trick in impl parsing can hardly be avoided, but this specific issue can be fixed because reinterpretation can be avoided if we see a ty
fragment after impl
.
The question is whether we should fix it or not - the issue seems benign even if it's probably unintended, an error is immediately reported if ty
doesn't fit into the trait syntax.
This trick is also similar to other cases like limited use of expr
fragment in range patterns (#42886), which are intended.
I would also be surprised if this was not exploited in practice.