rustdereference

Why can't I auto deref when reading from a mutable reference?


I got this question from Rustling:

fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
    for element in v.iter_mut() {
        *element = *element * 2;
    }

    v
}

vec_loop multiplies the elements in v by 2 in place. But I'm not sure why I can't write it like this:

*element = element * 2;

I got the compiler error:

error[E0369]: cannot multiply `&mut i32` by `{integer}`
  --> exercises/vecs/vecs2.rs:14:28
   |
14 |         *element = element * 2;
   |                    ------- ^ - {integer}
   |                    |
   |                    &mut i32
   |
help: `*` can be used on `i32` if you dereference the left-hand side
   |
14 |         *element = *element * 2;
   |                    +

As far as I know, a &i32 reference can be auto dereferenced for reading. Why can't &mut i32?

For example, another function from the same Rustling:

fn vec_map(v: &Vec<i32>) -> Vec<i32> {
    v.iter().map(|element| {
        element * 2
    }).collect()
}

In this case the auto defer works. No need to write *element * 2


Solution

  • There is an implementation of Mul for &i32 * i32 which is why the second example works. However &i32 and &mut i32 are distinct types and while the latter can be coerced into the former, coercions are not applied when deducing trait implementations like for Mul.

    So because there is no implementation for &mut i32 * i32, you must explicitly dereference or reborrow the element: *element * 2 or &*element * 2.