Repository navigation
Conflicting between impl <T: Base> T: Ext and impl B: Ext #3429
Description
Activity
I have run into this issue too. I think the problem is that rust allows you to use generics to declare multiple impls of a trait for the same type - but typeclass coherence says this shouldn't be allowed.
In general, support for impls for type parameters is sketchy. It's unclear if such constructs should be allowed at all (though they are unquestionably useful). But if we do decide to allow them, it's clear that we have to beef up our algorithms to deal with the complexities that they introduce. In this case, the bug is because coherence doesn't "go further" to check that all the bounds on the type parameters are met when deciding whether two implementations overlap. This is somewhat tricky---it would basically have to conclude that an implementation on all implements of Foo does not conflict with an implementation on the type A because the type A does not implement Foo. This check is only reasonable, of course, due to coherence itself.
Nominated for maturity milestone 1 (well-defined), since there's a question as to whether the code should be allowed.
accepted for well-defined milestone
sub-bug of #5527
Here's an updated, minimized, self-contained test case:
fn main() { let x = X; x.foobar(); } trait Foo { fn foobar(&self); } trait Bar { fn foobar(&self); } trait FooBase {} trait BarBase {} impl<T: FooBase> Foo for T { fn foobar(&self) {} } impl<T: BarBase> Bar for T { fn foobar(&self) {} } struct X; impl FooBase for X {}
Output:
con.rs:3:4: 3:15 error: multiple applicable methods in scope con.rs:3 x.foobar(); ^~~~~~~~~~~ con.rs:23:4: 23:23 note: candidate #1 is `__extensions__::foobar` con.rs:23 fn foobar(&self) {} ^~~~~~~~~~~~~~~~~~~ con.rs:19:4: 19:23 note: candidate #2 is `__extensions__::foobar` con.rs:19 fn foobar(&self) {} ^~~~~~~~~~~~~~~~~~~ con.rs:3:4: 3:15 error: failed to find an implementation of trait BarBase for X con.rs:3 x.foobar(); ^~~~~~~~~~~To clarify, the strangeness here is that even though the type
Xdoesn't implementBarBase(this is even noted in the error message), the impl ofBarfor all typesT: BarBaseconflicts with the impl ofFooBaseonX.visited for triage email 2013-07-22.
still a problem.
While investigating the test case posted by bstrie, I noticed this variant of the test has a different error message (but its cause may stem from the same origin). This test's goal was to break the
mainmethod into separate functions with type signatures to see if I could force rustc to notice the X -> FooBase -> Foo path.fn g<F:Foo>(f:&F) { f.foobar(); } fn f<FB:FooBase>(fb:&FB) { g(fb); } fn main() { let x = X; f(&x); } struct X; impl FooBase for X {} trait Foo { fn foobar(&self); } trait Bar { fn foobar(&self); } trait FooBase {} trait BarBase {} impl<T: FooBase> Foo for T { fn foobar(&self) {} } impl<T: BarBase> Bar for T { fn foobar(&self) {} }
error message:
% rustc /tmp/rusttmp/baz.rs /tmp/rusttmp/baz.rs:6:4: 6:5 error: failed to find an implementation of trait Foo for T /tmp/rusttmp/baz.rs:6 g(fb); ^I hit upon a similar behavior, I think, with the following code:
trait T1 { } trait T2 { } struct S1; impl T1 for S1 { } impl <S: T2> T1 for S { } fn main() {}
All these now pass thanks to the changes to the trait matching system. \o/
I think, there similar issue with rustc 1.12.1 (d4f3940 2016-10-19)
code:
trait X {} trait Y {} trait Z {} impl <T : Y> X for T {} impl <T : Z> X for T {}
fails with:
error[E0119]: conflicting implementations of trait `X`: --> src/lib.rs:5:1 | 4 | impl <T : Y> X for T {} | ----------------------- first implementation here 5 | impl <T : Z> X for T {} | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementationI think, there similar issue with rustc 1.12.1 (d4f3940 2016-10-19)
That is expected behavior. The problem is that one type could implement both
YandZ, in which case there would be two applicable impls (which we aim to avoid). We've been working on specialization (see rust-lang/rfcs#1210) which aims to allow overlapping impls in some situations, but it's still a work-in-progress.- added a commit that references this issue
on Apr 13, 2024
Minimized test case
(taken from bstrie's comment below)
Original bug report follows
I tried implementing of a trait
Eqfor a generic typeT: OrdEx, but rustc says conflicting betweenimpl <T: OrdEx> T: Eqandimpl Cmp: Eq.extcmp.rs: