I've been reading the section Unique immutable borrows in captures
of the book The Rust Reference and can't figure out why the code is illegal:
let mut b = false;
let x = &mut b;
{
let mut c = || { *x = true; };
// The following line is an error:
// let y = &x;
c();
}
let z = &x;
The book's explanation points out that type of variable y
is & &mut
which might not be unique
.
I'm confused about why & &mut
can't guarantee uniqueness? I mean, both x
and y
are immutable and there is only one place that can change, which is the value of variable b.
I guess the reason(not sure) is:
let mut b = false;
let x = &mut b; // There is a guarantee that the value of `*x` is can't change because there no mutable reference.
let y = &x; // There is a guarantee that the value of `*y` and `**y` is can't change, but I don't know that rust needs to guarantee `**y` is can't change.
The fact the variable x
is not declared as mutable
doesn't implies that it's not a mutable borrow and is actually a mutable borrow.
As an example, this is valid code and does in fact modify b
:
let mut b = false;
let x = &mut b;
*x = true;
println!("{x}"); // true
So in the example you provided, x
is borrow as mutable by the closure as it modifies the value it containes by doing *x = true
. While this closures is in scope, the variable x
will be borrowed.
So step by step :
let mut b = false; // Creates the variable b as mutable.
let x = &mut b; // x borrows b as mutable.
{
// c is created, using x to modify b thus borrowing x as mutable
let mut c = || { *x = true; };
// This tries to borrow x but it is still borrowed as mutable by c which is not allowed
let y = &x;
c();
} // c goes out of scope freeing the borrow of x
let z = &x; // x not being borrowed by anyone here, it can be borrowed
Hoping this helps making it clearer