why are multiple mutable references to the same value through pointers legal in Rust

Viewed 131

I'm working on my understanding of Rust's ownership- and borrowing-model and am confused by the following:

let mut x: i32 = 1;
let ref_x = &mut x;
let refref_x = &mut *ref_x;
*refref_x = 2;
*ref_x = 3;

To my knowledge, I am effectively creating two separate mutable references to x. Why is this code legal when avoiding the indirection through pointers and just changing line 3 to

let refref_x = &mut x;

is obviously not? Am I misunderstanding central concepts or is the compiler adding some magic in the background?

1 Answers

To my knowledge, I am effectively creating two separate mutable references to x.

Nope, the second reference borrows from (and thus locks out) the first one, as you can see if you try to use the first one while the second one is still live:

let mut x: i32 = 1;
let ref1 = &mut x;
let ref2 = &mut *ref1;
*ref1 = 3; // <- can not assign because ref1 is borrowed (by the previous line)
*ref2 = 2;

ref2 is a reborrow of ref1. It's unsurprising that you'd be confused though as this is an ill-documented feature, though a pretty essential one.

Am I misunderstanding central concepts or is the compiler adding some magic in the background?

a bit of both, basically &[mut]* is a "special form" of the language, it doesn't dereference the value then re-reference it completely separately, instead it "reinterprets" the pointer.

Incidentally, this will likely lead to even more confusion the first time you encounter forced moves.

Related