Description
UPDATED DESCRIPTION:
We now allow the original problem, but some corner cases are still unhandled. See comments below.
ORIGINAL DESCRIPTION:
Where clauses right now require predicates to contain type parameters, as in:
trait Foo {
fn foo(&self);
}
struct Bar<T> {
x: T,
}
impl<T> Foo for Bar<T> where T: Foo {
fn foo(&self) {
self.x.foo()
}
}
But we cannot add constraints on non-generic types:
struct Baz { x: i32 }
impl Foo for Baz where i32: Foo {
fn foo(&self) {
self.x.foo()
}
}
Will error out with:
test.rs:15:1: 19:2 error: cannot bound type `i32`, where clause bounds may only be attached to types involving type parameters
test.rs:15 impl Foo for Baz where i32: Foo {
test.rs:16 fn foo(&self) {
test.rs:17 self.x.foo()
test.rs:18 }
test.rs:19 }
In hand written code this usually won't come up, but this would be really helpful for a code generator like macro_rules!
or #[derive]
, especially when dealing with associated types. Currently the only way to know if a type is generic or not is to manually walk it and see if any of the type paths start with the same name as a type parameter. If so, add that type to the predicate list. Instead, it would be much simpler if we could just add all the types listed in a field or enum to the predicate list and let the type checker report an error if one of those types doesn't implement the trait.