Cant infer type when using += on generic

Hi! I'm building a lib for multiplying matrices but i'm getting a very annoying error simply stating

summa += self.matris[i][k] * matris.matris[k][j];
^^ cannot infer type

This is my code

#[derive(Debug, Clone, Copy)]
    enum Egenskaper{
        Rektangel,
        Kvadrat
    }

    #[derive(Debug, Clone)]
    struct Matris<T> {
        matris:    Vec<Vec<T>>,
        form:      (usize, usize),
        egenskaper: Vec<Egenskaper>
    }

    // Statiska funktioner
    impl<T> Matris<T> where T: Copy + Num {
        fn new(ny_matris: &Vec<Vec<T>>) -> Self {
            Self {
                matris:    ny_matris.to_vec(),
                form:      (2,3),
                egenskaper: vec![Egenskaper::Rektangel]
            }
        }
    }
        fn multiplicera(&mut self, matris: &Matris<T>) -> Matris<f64> 
        where T: Copy + Clone + std::ops::Mul<Output=f64> + std::ops::AddAssign<f64>, {
            assert_eq!(self.form.1, matris.form.0);

            let (n, p) = (self.form.0, matris.form.1);
            let mut c = vec![vec![0.0; p]; n];
            
            for i in 0..n {
                for j in 0..p {
                    let mut summa = 0.0;
                    for k in 0..self.form.1 {
                        // Error here on +=
                        summa += self.matris[i][k] * matris.matris[k][j];
                    }
                    c[i][j] = summa;
                }
            }
            Matris::new(&c)
        }
    }

Please help!

I'm stumped. Even when using UFCS, the compiler won't accept this:

let x: f64 = <T as std::ops::Mul>::mul(self.matris[i][k], matris.matris[k][j]);
summa += x;
error[E0284]: type annotations needed: cannot satisfy `<T as Mul>::Output == f64`
  --> src/lib.rs:37:38
   |
37 |  let x: f64 = <T as std::ops::Mul>::mul(self.matris[i][k], matris.matris[k][j]);
   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<T as Mul>::Output == f64`

even though you clearly specify T: std::ops::Mul<Output=f64>

1 Like

Reduced example that doesn't work:

fn mul_multiple_bounds<T: core::ops::Mul<Output=f64> + core::ops::Mul<Output=T>>(a: T, b: T) -> f64 {
    mul_single_bound(a, b)
}

fn mul_single_bound<T: core::ops::Mul<Output=f64>>(a: T, b: T) -> f64 {
    unimplemented!()
}

Anyway, T: Num requires T: Mul<T, Output = T>, so it doesn't really help to be this generic here. You could just implement your function on Matris<f64>.

But the problem would still remain right?

Solved it with this by adding Into<f64> and doing the operation like this: summa += self.matris[i][k].into() * matris.matris[k][j].into();