From/Into for generic struct conversion

Hi, I am just new to Rust.
I am trying to implement a conversion between my custom struct Vec3

pub struct Vec3<T> (pub T, pub T, pub T);

basically I want a from/into trait that can conveniently convert between Vec3<f64> and Vec3<f32>, for example

Vec3(1.0f32, 2.0f32, 3.0f32).into()

will get something like

Vec3(1.0f64, 2.0f64, 3.0f64)

what I am doing now is

impl<U, T> From<Vec3<U>> for Vec3<T>
where
    U: Into<T>,
    T: Float,
{
    fn from(value: Vec3<U>) -> Vec3<T> {
        Vec3(value.x().into(), value.y().into(), value.z().into())
    }
}

However, I got the error

error[E0119]: conflicting implementations of trait `Into<_>` for type `vec3::Vec3<_>`
  --> src/vec3.rs:16:1
   |
16 | impl<T: Float, U: Float> Into<U> for Vec3<T>
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: conflicting implementation in crate `core`:
           - impl<T, U> Into<U> for T
             where U: From<T>

The conflict is that Vec3<f32> implements Into<Vec3<f32>> both via std (impl From<T> for T which results in impl Into<T> for T) and via your implementation. Conflicts aren't allowed ("coherence").

The From/Into/TryFrom/TryInto implementations in std are so generic, you often can't avoid such conflicts (or run into another coherence constraint called the orphan rules). The most direct response is to implement for concrete types instead (perhaps with the help of a macro).

2 Likes

Thanks!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.