Reputation: 42789
This code:
trait SayHello {
fn say_hello() { println!("hello") }
}
trait Foo {
type Hello: SayHello;
}
trait Bar: Foo {
type Hello: SayHello;
}
struct Generic<T>(T);
impl<T> Generic<T> where T: Bar<Hello = <T as Foo>::Hello> {
fn say_hello() {
T::Hello::say_hello()
}
}
returns this error:
error[E0221]: ambiguous associated type `Hello` in bounds of `T`
--> src/lib.rs:17:9
|
6 | type Hello: SayHello;
| --------------------- ambiguous `Hello` from `Foo`
...
10 | type Hello: SayHello;
| --------------------- ambiguous `Hello` from `Bar`
...
17 | T::Hello::say_hello()
| ^^^^^^^^^^^^^^^^^^^ ambiguous associated type `Hello`
|
help: use fully qualified syntax to disambiguate
|
17 | <T as Foo>::Hello()
| ^^^^^^^^^^^^^^^^^
help: use fully qualified syntax to disambiguate
|
17 | <T as Bar>::Hello()
| ^^^^^^^^^^^^^^^^^
But there shouldn't be any ambiguity. It's clearly stated that the Hello
associated type is the same in Foo
and bar
.
Upvotes: 2
Views: 1921
Reputation: 2618
If T
implements Bar
, it also has to implement Foo
, as per your bound on the trait. Therefore, T::Hello
in say_hello()
can both refer to <T as Foo>::Hello
or <T as Bar>::Hello
, which fixes your example.
It'd be possible to introduce another parameter H: SayHello
and set both Foo::Hello
and Bar::Hello
to H
. Dispatch to say_hello()
then works via H::say_hello()
, rather than T::Hello::say_hello()
.
struct Generic<T>(T);
impl<T, H> Generic<T> where T: Bar<Hello=H> + Foo<Hello=H>, H: SayHello {
fn say_hello() {
H::say_hello()
}
}
Upvotes: 4