Hi!
I encountered a problem, which I know has currently no solution, but I wanted help understanding why it's not allowed. I have a struct Vector
, which is a 2D vector, and a trait Scalar
, which is implemented on e.g. f32
. I want to be able to multiply a scalar by a vector, by implementing std::ops::Mul<Vector>
on Scalar
:
struct Vector {
pub x: f32,
pub y: f32,
}
impl Vector {
fn new(x: f32, y: f32) -> Self {
Vector { x, y }
}
}
trait Scalar {
fn to_float(self) -> f32;
}
// Vector-by-Scalar. This works
impl<T: Scalar> std::ops::Mul<T> for Vector
{
type Output = Vector;
fn mul(self, rhs: T) -> Vector {
let rhs = rhs.to_float();
Vector::new(self.x * rhs, self.y * rhs)
}
}
// Scalar-by-Vector. This is not permitted
impl<T: Scalar> std::ops::Mul<Vector> for T
{
type Output = Vector;
fn mul(self, rhs: Vector) -> Vector {
let lhs = self.to_float();
Vector::new(lhs * rhs.x, lhs * rhs.y)
}
}
When checking, I'm getting the following error:
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
--> src/main.rs:28:1
|
28 | impl<T: Scalar> std::ops::Mul<Vector> for T
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
|
= note: only traits defined in the current crate can be implemented for a type parameter
Now, I found a thread that tells me I can't implement, say, Display
on Scalar
, and I understand why: Display
is defined outside the local crate. However, here, I want to implement Mul<Vector>
, which is a generic trait parameterized by a local struct. In a sense, Mul<Vector>
is itself akin to a local trait, right? Then, why is this not authorized?
Thank you very much for your time!