I can impl `Mul<T> for Matrix`, but how can I impl `Mul<Matrix> for T`?

Recently I am working on a research project which need me to implement tensor calculations manually in Rust, but here's a problem I came across. Take matrices for example, assume that we have declared a Matrix<T> struct to have it multiplied by a scalar value T, it's easy to work out with this line of code:

impl<T> Mul<T> for Matrix<T> 
where
    T: Mul<Output = T> { ... }

It's easy and after that we can do matrix * scalar because the rhs value have the type T while the lhs is a matrix. This is great and to finish the commutative law, our next idea should be scalar * matrix. It's still easy to come out with this:

impl<T> Mul<Matrix<T>> for T
where
    T: Mul<Output = T> { ... }

However this is where problems are. Due to the orphan rule, we cannot implement an external trait Mul for full-match type parameter T, because if we can do so, multiple external crates can implement one single trait in different ways and there could be a conflict which is not that easy to debug. So this piece of code would result in a compile error:

error[E0210]: type parameter `T` must be used as the type parameter for some local type
(e.g., `MyStruct<T>`)
   --> file_name.rs:LL:CC
   |
LL | impl<T> Mul<Matrix<T>> 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

This error still occurs even if a where clause is attached to type T. In this case, our work would unfortunately stop here only to find we cannot do scalar * matrix for every type T. It's enough though, to implement Mul<Matrix<T>> for only some certain types e.g. f32, but if we want to do everything gracefully, it should be a way we would finish the commutative law for matrices and scalar values. This issue is somehow similar to what we met with tensors and scalars in our research.

So how should I write code to impl<T> Mul<Matrix<T>> for T gracefully? Or is it common to finish the implementation for only some certain types? I would be grateful for all helpful ideas, thanks!

This should go on the user.rust-lang.org forum. internals is mean for the design of the Rust language and compiler work. General questions about Rust should go on users where you will find a lot more people looking to answer all your questions

1 Like