For learning purposes, I tried this solution, but it does not work:

```
use std::ops::Add;
fn inc<T: Add>(x:&mut T) {
*x += 1;
}
fn main() {
let mut x:i32 = 10;
let mut y:u8 = 1;
inc(&mut x);
inc(&mut y);
println!("{} {}", x, y);
}
```

Error message:

```
<anon>:4:5: 4:7 error: binary assignment operation `+=` cannot be applied to types `T` and `_` [E0368]
<anon>:4 *x += 1;
^~
<anon>:4:5: 4:7 help: see the detailed explanation for E0368
error: aborting due to previous error
```

What is the right way to do that?

# Best How To :

At present, `+=`

is only defined on the primitive integer types; generically, you will need to expand it to `*x = *x + 1;`

instead. This then reveals more problems:

```
<anon>:4:15: 4:16 error: mismatched types:
expected `T`,
found `_`
(expected type parameter,
found integral variable) [E0308]
<anon>:4 *x = *x + 1;
^
<anon>:4:10: 4:16 error: mismatched types:
expected `T`,
found `<T as core::ops::Add>::Output`
(expected type parameter,
found associated type) [E0308]
<anon>:4 *x = *x + 1;
^~~~~~
error: aborting due to 2 previous errors
```

Let’s look at the `Add`

trait’s definition:

```
pub trait Add<RHS = Self> {
/// The resulting type after applying the `+` operator
type Output;
/// The method for the `+` operator
fn add(self, rhs: RHS) -> Self::Output;
}
```

So `Self + RHS`

produces an object of type `<Self as Add<RHS>>::Output`

.

As you’re storing the value back in `*x`

, the result of the calculation must be a `T`

; thus we establish that the bound on `T`

will need to be not `Add`

but `Add<`*???*, Output = T>

.

What, then, will *???*

be? What is the type of `1`

? It’s not generic; it’s one of the ten known primitive integer types (`isize`

, `i8`

, `i16`

, `i32`

, `i64`

, `usize`

, `u8`

, `u16`

, `u32`

, `u64`

). This clearly won’t work, because the integral types don’t implement addition of lesser types—the default value for `RHS`

of `Self`

(that is, where `T: Add`

means `T: Add<Self>`

) is all you can count on, but `1`

cannot be of type `T`

.

The solution is to use a generic function that produces the value *1*. There is one unstable in `std::num::One`

, and a stable one in the `num`

crate from crates.io, `num::One`

. Using the former requires the Rust nightly, using the latter requires dropping the `std::`

, adding an `extern crate num;`

and adding `num`

to your Cargo.toml dependencies section.

We also need a `Copy`

bound to allow the `*x`

of `*x + 1`

to work.

Here’s the final result:

```
#![feature(zero_one)]
use std::ops::Add;
use std::num::One;
fn inc<T: Copy + One + Add<T, Output = T>>(x: &mut T) {
*x = *x + T::one();
}
fn main() {
let mut x: i32 = 10;
let mut y: u8 = 1;
inc(&mut x);
inc(&mut y);
println!("{} {}", x, y);
}
```