2
fn main() {
    let mut x = 42;
    let y = &x;
    *y = 5;
}

This does not compile. Why does it have to be a &mut to x? In my understanding, the reference (i.e. address where the value of x is stored) does not change, only the value stored on that address. And x is mut.

Does compile:

fn main() {
    let mut x = 42;
    let y = &mut x;
    *y = 5;
}
frankplow
  • 502
  • 1
  • 12
  • 1
    [DerefMut](https://doc.rust-lang.org/std/ops/trait.DerefMut.html) vs [Deref](https://doc.rust-lang.org/std/ops/trait.Deref.html) – Ömer Erden Oct 21 '22 at 10:32
  • Hint: How are you going to modify a non-`mut` reference? `&x` is read-only. `&mut x` can be mutated. – tadman Oct 21 '22 at 10:42
  • In your first example, `y` takes a shared borrow of `x`; it is a fundamental of Rust's memory safety model that values cannot be mutated while they are (non-exclusively) borrowed. In your second example, the borrow is exclusive. – eggyal Oct 21 '22 at 10:43
  • Maybe it helps if you consider that this compiles: `let x = 42; let y = &x`. Now, if something like `*y = 5` were allowed, what's to stop you from modifying a non-`mut` x? – user4815162342 Oct 21 '22 at 14:17

1 Answers1

1

The meaning of &mut is a reference through which a value can be mutated, rather than a reference which itself can be mutated. & denotes a reference through which a value cannot be mutated. A reference which itself can be mutated would be written something like let mut y = &x; (though in practice this is not common).

In my understanding ... the reference (i.e. address where the value of x is stored) ...

I think the confusion here stems from the fact that a reference is not quite the same thing as a memory address or pointer. It is more conceptual and makes more guarantees - such as the fact that the reference will always point to a valid object of the given type.

frankplow
  • 502
  • 1
  • 12