I'm fighting with the borrow checker. I have two similar pieces of code, one working as I expect, and the other not.
The one that works as I expect:
mod case1 {
struct Foo {}
struct Bar1 {
x: Foo,
}
impl Bar1 {
fn f<'a>(&'a mut self) -> &'a Foo {
&self.x
}
}
// only for example
fn f1() {
let mut bar = Bar1 { x: Foo {} };
let y = bar.f(); // (1) 'bar' is borrowed by 'y'
let z = bar.f(); // error (as expected) : cannot borrow `bar` as mutable more
// than once at a time [E0499]
}
fn f2() {
let mut bar = Bar1 { x: Foo {} };
bar.f(); // (2) 'bar' is not borrowed after the call
let z = bar.f(); // ok (as expected)
}
}
The one that doesn't:
mod case2 {
struct Foo {}
struct Bar2<'b> {
x: &'b Foo,
}
impl<'b> Bar2<'b> {
fn f(&'b mut self) -> &'b Foo {
self.x
}
}
fn f4() {
let foo = Foo {};
let mut bar2 = Bar2 { x: &foo };
bar2.f(); // (3) 'bar2' is borrowed as mutable, but who borrowed it?
let z = bar2.f(); // error: cannot borrow `bar2` as mutable more than once at a time [E0499]
}
}
I hoped I could call Bar2::f
twice without irritating the compiler, as in case 1.
The question is in the comment (3): who borrowed bar2
, whereas there is no affectation?
Here's what I understand:
In case 1,
f2
call: the lifetime parameter'a
is the one of the receiving&Foo
value, so this lifetime is empty when there is no affectation, andbar
is not borrowed after theBar1::f
call;In case 2,
bar2
borrowsfoo
(as immutable), so the lifetime parameter'b
inBar2
struct is thefoo
reference lifetime, which ends at the end off4
body. CallingBar2::f
borrowsbar2
for that lifetime, namely to the end off4
.
But the question is still: who borrowed bar2
? Could it be Bar2::f
? How Bar2::f
would hold the borrowed ownership after the call? What am I missing here?
I'm using Rust 1.14.0-nightly (86affcdf6 2016-09-28) on x86_64-pc-windows-msvc.