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.