The following code compiles successfully:
let mut v = vec![1];
let r = &mut v;
r.push(r.len());
while this one fails:
let mut v = vec![1];
let r = &mut v;
r.push(v.len());
with error:
error[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable
|
| let r = &mut v;
| ------ mutable borrow occurs here
| r.push(v.len());
| ^ immutable borrow occurs here
| r.push(r.len());
| - mutable borrow later used here
r
is used in the outer and inner calls? Or is it because it applies the RFC 2025, Two-Phase Borrows? Or something else?I suspect that in the first example there are no errors because the compiler does not create intermediate references and it uses the same reference: r
so that there are not multiple borrows.
However, if that is the case, why the following code fails to compile
let mut v = vec![1];
let r = &mut v;
r.push({r.push(0);1});
1st example:
let mut v = vec![1];
let r = &mut v;
r.push(r.len());
Without the 2-phase borrows the code will not compile because the outer call creates a reborrow of r
: &mut *r
, and the inner call a new immutable reborrow of the same value: &*r
.
With 2-phase borrows, the first reborrow is converted to &mut2 *r
and later activated when the second reborrow is out of scope.
2nd example:
let mut v = vec![1];
let r = &mut v;
r.push(v.len());
Even with the 2-phase borrows it does not compile.
The inner call causes a reborrow of v
: &mut v
that clashes with r
.
3rd example:
let mut v = vec![1];
let r = &mut v;
r.push({r.push(0);0});
Even with the 2-phase borrows it does not compile.
The inner call requires a &mut2
reborrows of *r
that is not allowed by the 2-phase borrows since the outer call already created a &mut2
reborrows of *r
.
References: