Search code examples
templatesrusttype-conversion

Can I implement a generic From<> trait for a generic type for any other implementation than from itself?


I made a generic Vector struct, used with different T types :

struct Vector<T> {
    data: [T; 3],
}

I already implemented some generic traits for mathematical operands (Eq, Index, std::ops::Add...) and it works fine.

But now, I am struggling with implementing a From trait so I can easily convert, for instance, a Vector into a Vector.

impl<T, U> From<Vector<U>> for Vector<T> {
    fn from(item: Vector<U>) -> Self {
        // [...]
    }
}

Regardless of this from function's implementation, I get the following error:

error[E0119]: conflicting implementations of trait `From<Vector<_>>` for type `Vector<_>`
 --> <source>:5:1
  |
5 | impl<T, U> From<Vector<U>> for Vector<T> {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: conflicting implementation in crate `core`:
          - impl<T> From<T> for T;

If I understand correctly, it is because by default, for any type, From<Vector<T>> for Vector<T> is already declared. And my implementation conflicts with it if T and U are identical types.

So is there a way to use my implementation for any different types T and U, but not use it for identical types T and U ?


Solution

  • You cannot write this implementation.

    Even if you were the owner of From you could not write this bound, as it conflicts with impl<T> From<T> for T where T == U. In fact, some people want the standard library to write this impl for collections (for example, Option<T>), and despite the standard library being the owner of From it cannot provide this impl.

    You can provide a method to do that, instead of a trait implementation.