Description
The following fails:
trait A {
type C;
}
trait B<M>: A {}
impl<T: A, M: Into<T::C>> B<M> for T {}
// equivalent; also errors:
// impl<C, T: A<C=C>, M: Into<C>> B<M> for T {}
struct S {}
impl A for S {
type C = u32;
}
// error[E0119]: conflicting implementations of trait `B<()>` for type `S`
impl B<()> for S {}
Note that due to the bounds such a conflict is impossible unless (): Into<u32>
, which cannot happen...
... actually, this may simply be the compiler giving a lot of leeway for additional implementations in std
.
... replacing u32
and/or ()
with local private types does not change the error:
struct X;
struct Y;
trait A {
type C;
}
trait B<M>: A {}
impl<T: A, M: Into<T::C>> B<M> for T {}
struct S {}
impl A for S {
type C = X;
}
impl B<Y> for S {}
Introducing a local Into
trait slightly changes the error:
trait Into<Y> {}
// ...
This version has the same error but now includes an (incorrect) explanation:
note: downstream crates may implement trait
Into<_>
for type()
Variant
Here's a variant:
trait A<C> {}
trait B<C, M>: A<C> {}
impl<C, T: A<C>, M: Into<C>> B<C, M> for T {}
struct S {}
impl A<u32> for S {}
impl B<u32, ()> for S {}
This results in the same error, except that:
-
there is a valid explanation:
note: upstream crates may add a new impl of trait
std::convert::From<()>
for typeu32
in future versions -
introducing a local private
trait Into<Y> {}
fixes it -
introducing a local private type to replace
u32
or()
fixes it