Why does the compiler reject this code:
struct S<'a> {
i: i32,
r: &'a i32,
}
fn main() {
let mut s = S{i: 0, r: &0};
{
let m1 = &mut s;
m1.r = &m1.i;
}
let m2 = &mut s;
}
The error is: "cannot borrow s
as mutable more than once at a time" (first borrow: m1
, second borrow: m2
).
Why is the first borrow of s
still alive after m1
goes out of scope?
I read about borrow scope extension beyond the scope of the original borrower. However, this always seemed to involve another borrower outside the scope of the original borrower that "took over" the original borrow, e.g. this code fails with the exact same error, which is clear to me:
fn main() {
let mut s = 0;
let r: &mut i32;
{
let m1 = &mut s;
r = m1;
}
let m2 = &mut s;
}
In the first example, if I replace m1.r = &m1.i;
with m1.r = &dummy;
(dummy defined as some &i32) or with let dummy = &m1.i;
, the code compiles. The error occurs only if I store a reference to a field in another field of the borrowed struct. I don't see why this should extend the borrow beyond its scope.
My best guess as to what is wrong with the code is:
s.r
's original lifetime is the whole ofmain
,when I assign a reference to
m1.r
it has to be that original lifetime, but&m1.i
is only valid for as long asm1
lives.
But I might be wrong (the error message would be misleading then).