-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conflicting between impl <T: Base> T: Ext
and impl B: Ext
#3429
Comments
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:
To clarify, the strangeness here is that even though the type |
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 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:
|
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:
|
That is expected behavior. The problem is that one type could implement both |
De-duplicate SSE2 sll/srl/sra code
Minimized test case
(taken from bstrie's comment below)
Original bug report follows
I tried implementing of a trait
Eq
for a generic typeT: OrdEx
, but rustc says conflicting betweenimpl <T: OrdEx> T: Eq
andimpl Cmp: Eq
.extcmp.rs:
The text was updated successfully, but these errors were encountered: