How do I require a generic type implement an operation like Add, Sub, Mul, or Div in a generic function?

Let’s break down your example a bit:

fn cube<T: Mul>(x: T) -> T {
    let a = x * x;
    let b = a * x;
    b
}

What are the types of a and b? In this case, the type of a is <T as std::ops::Mul>::Output — sound familiar from the error message? Then, we are trying to multiply that type by x again, but there’s no guarantee that Output is able to be multiplied by anything!

Let’s do the simplest thing and say that T * T needs to result in a T:

fn cube<T: Mul<Output = T>>(x: T) -> T {
    x * x * x
}

Unfortunately, this gives two similar errors:

error[E0382]: use of moved value: `x`
 --> src/lib.rs:6:9
  |
6 |     x * x * x
  |     -   ^ value used here after move
  |     |
  |     value moved here
  |
  = note: move occurs because `x` has type `T`, which does not implement the `Copy` trait

Which is because the Mul trait takes arguments by value, so we add the Copy so we can duplicate the values.

I also switched to the where clause as I like it better and it is unwieldy to have that much inline:

fn cube<T>(x: T) -> T
where
    T: Mul<Output = T> + Copy
{
    x * x * x
}

See also:

Leave a Comment