Reputation: 107
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.
Upvotes: 0
Views: 109
Reputation: 71
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
Upvotes: 1
Reputation: 27552
The closure is the first borrow and y
would be the second, therefore x
would be borrowed multiple times, that however cannot be allowed because the closure modifies the value pointed to by x
.
In other words, the closure holds an exclusive borrow (even if it's not mutable in this case) to x
, nothing outside can take an additional borrow.
Upvotes: 0