Hi all,
I am writing some linear algebra toy code and encountered the following compile error.
At a high level, I want to implement a routine that multiplies f32
to a generic vector type V
.
However, the trait bound I added for f32 * &V
operation seems to let the compiler "forget" that f32 * f32
is legal and leads to the following compilation error for the function not_working()
.
I did manage to find a walk around by putting the floating point multiplication in a seperate function. But I really want to understand why this happens.
PS:
I know that in this specific use case, I could instead do
for<'a> &'a V: core::ops::Mul<f32, Output=V>
and use
v * (a * b)
instead of
a * b * v
But since commutativity is not implied by Mul
(correct me if I got this wrong), this alternate approach may not always work.
fn not_working<V>(a: f32, b: f32, v: &V) -> V where
f32: for<'a> core::ops::Mul<&'a V, Output=V>,
{
a * b * v
}
#[inline(always)]
fn mul_f32(x: f32, y: f32) -> f32 { x * y }
fn working<V>(a: f32, b: f32, v: &V) -> V where
f32: for<'a> core::ops::Mul<&'a V, Output=V>,
{
mul_f32(a, b) * v
}
fn main() {}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:13:9
|
13 | a * b * v
| ^ expected `&V`, found `f32`
|
= note: expected reference `&V`
found type `f32`
error[E0369]: cannot multiply `V` by `&V`
--> src/main.rs:13:11
|
13 | a * b * v
| ----- ^ - &V
| |
| V
|
help: consider further restricting type parameter `V`
|
11 | f32: for<'a> core::ops::Mul<&'a V, Output=V>, V: std::ops::Mul<Output = &V>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Some errors have detailed explanations: E0308, E0369.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `playground` due to 2 previous errors