I have a container type C<T> that holds an object of type T.
struct C<T> {
insides: T
}
Let's say I have two types A and B which can be converted between using the From trait:
struct A { }
struct B { }
impl From<A> for B {
fn from(a: A) -> B {
B { }
}
}
In my case it is natural that I should be able to easily put C<A> wherever C<B> is needed using this conversion. This can be done by extending From to the container type:
impl From<C<A>> for C<B> {
fn from(ca: C<A>) -> C<B> {
C { insides: B::from(ca.insides) }
}
}
fn foo(cb: C<B>) {}
fn main() {
let ca = C { insides: A {} };
foo(ca.into());
}
So far so good, this all compiles and works as expected.
But this is a rather natural pattern that is applicable to any pair of convertible types, not only to A and B. So one might want a blanket trait implementation:
impl<T, U> From<C<T>> for C<U> where U: From<T> {
fn from(t: C<T>) -> C<U> {
C { insides: U::from(t.insides) }
}
}
This doesn't work:
error[E0119]: conflicting implementations of trait `std::convert::From<C<_>>` for type `C<_>`
--> src/main.rs:19:1
|
19 | impl<T, U> From<C<T>> for C<U> where U: From<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T> From<T> for T;
For more information about this error, try `rustc --explain E0119`.
I understand the error: for any X if we specify the impl for T=X,U=X we get a conflict, because X: From<X> for all X. But this is a rather annoying edge case. Is there a way to work around this? Somehow specify a bound saying T != U, or any other way of telling Rust to use whatever blanket implementation there is in core for T=U and my impl for the rest?