unconstrained type parameter error

Viewed 7059

I'm trying to interface glium with cgmath. Following this answer, I have implemented a ToArray trait to convert instances of cgmath::Matrix4 into a format usable by glium:

pub trait ToArray {
    type Output;
    fn to_array(&self) -> Self::Output;
}

impl<S: cgmath::BaseNum> ToArray for cgmath::Matrix4<S> {
    type Output = [[S; 4]; 4];
    fn to_array(&self) -> Self::Output {
        (*self).into()
    }
}

Since I don't always use Matrix4 directly, I need a similar implementation for cgmath transform types. For example for cgmath::Decomposed:

impl<S: cgmath::BaseFloat, R: cgmath::Rotation3<S>> ToArray
    for cgmath::Decomposed<cgmath::Vector3<S>, R> {
    type Output = [[S; 4]; 4];
    fn to_array(&self) -> Self::Output {
        cgmath::Matrix4::<S>::from(*self).into()
    }
}

This works, but I'd like to avoid duplicating the code for all transform types, so I thought I would define a generic implementation for anything that can be converted to a Matrix4:

impl<S: cgmath::BaseFloat, T: Into<cgmath::Matrix4<S>>> ToArray for T {
    type Output = [[S; 4]; 4];
    fn to_array(&self) -> Self::Output {
        cgmath::Matrix4::<S>::from(*self).into()
    }
}

Unfortunately, this doesn't work:

error[E0207]: the type parameter `S` is not constrained by the impl trait, self type, or predicates
  --> src/main.rs:23:6
   |
23 | impl<S: cgmath::BaseFloat, T: Into<cgmath::Matrix4<S>>> ToArray for T {
   |      ^ unconstrained type parameter

I have two questions:

  • Why doesn't the above code work? From reading the rustc --explain output, I would expect the T: Into<cgmath::Matrix4<S>> to act as a valid constraint on S as well as T.
  • How can I write a generic implementation for anything that can be converted into a Matrix4?
1 Answers
Related