3

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?

s1gsegv
  • 77
  • 3

1 Answers1

7

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.

Masklinn
  • 34,759
  • 3
  • 38
  • 57
  • 1
    Note that the linked Github issue complains about missing documentation for _implicit_ reborrows, not explicit ones. This doesn't make much of a difference, though, since neither implicit nor explicit reborrows are documented in the Rust reference. – Sven Marnach Sep 20 '21 at 08:16
  • 1
    @SvenMarnach my reading of the linked issue is that it complains about reborrowing's documentation in general, and mentions implicit reborrowing specifically because there is *some* documentation for it: "There is also some documentation on implicit borrowing, but again, this is sparse" the "*also*" bit would be unnecessary if the issue was only about implicit reborrowing I think. – Masklinn Sep 20 '21 at 10:49