You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the following, we have a Child trait to represent a "parent-child" relationship between two types. Alice is a child of () and Bob is a child of Alice. Then, we have a trait Foo that we want to implement for Alice, and for all types that are children of a Foo (so Alice and Bob should both implement Foo):
#![feature(specialization)]traitChild{typeParent;}structAlice;implChildforAlice{typeParent = ();}structBob;implChildforBob{typeParent = Alice;}traitFoo{fnfoo(&self);}implFooforAlice{fnfoo(&self){println!("Alice foo!");}}// Implement for all children with parents that implement `Foo`impl<T>FooforTwhereT:Child,T::Parent:Foo{defaultfnfoo(&self){println!("Descendant foo!");}}fnmain(){Alice.foo();Bob.foo();}
The program should print "Alice foo!" and "Descendant foo!"
Actual output
The program fails to compile:
error[E0119]: conflicting implementations of trait `Foo` for type `Alice`:
--> <anon>:28:1
|
23 | impl Foo for Alice {
| - first implementation here
...
28 | impl<T> Foo for T
| ^ conflicting implementation for `Alice`
error: aborting due to previous error
There are two workarounds I've found to fix the error above.
The first is to just remove the T::Parent: Foo clause (which works in this case, but not so much for my actual usecase).
The second workaround is to introduce another trait, FooChild, which is implemented for all types where Self::Parent: Foo. We can then use FooChild in the where clause instead:
traitFooChild{}impl<T>FooChildforTwhereT:Child,T::Parent:Foo{}// Implement for all children with parents that implement `Foo`impl<T>FooforT// where T: Child, T::Parent: FoowhereT:FooChild{defaultfnfoo(&self){println!("Descendant foo!");}}// ...
The original example exhibits conflicting implementations even without specialization (because () doesn't implement Foo, the generic impl doesn't apply to Alice), which makes me think this is related to or a duplicate of #23341.
(Originally reported in this comment in #31844)
In the following, we have a
Child
trait to represent a "parent-child" relationship between two types.Alice
is a child of()
andBob
is a child ofAlice
. Then, we have a traitFoo
that we want to implement forAlice
, and for all types that are children of aFoo
(soAlice
andBob
should both implementFoo
):(playpen)
Expected output
The program should print "Alice foo!" and "Descendant foo!"
Actual output
The program fails to compile:
Version info
Other notes
There are two workarounds I've found to fix the error above.
The first is to just remove the
T::Parent: Foo
clause (which works in this case, but not so much for my actual usecase).The second workaround is to introduce another trait,
FooChild
, which is implemented for all types whereSelf::Parent: Foo
. We can then useFooChild
in thewhere
clause instead:(playpen)
Interestingly, the second workaround doesn't work when
Child
is moved into a separate crate (example repo)The text was updated successfully, but these errors were encountered: