Given two snippets, which tries to return reference to a member value from self, I really can't understand why the one with separate function doesn't compile.
This works (godbolt):
struct Foo {
a: bool,
b: u32,
}
impl Foo {
fn get(&mut self) -> &u32 {
if self.a {
return &self.b;
}
self.a = true;
self.b = 10;
return &self.b;
}
}
While this doesn't (godbolt):
struct Foo {
a: bool,
b: u32,
}
impl Foo {
fn try_get(&self) -> Option<&u32> {
if self.a {
return Some(&self.b);
}
return None;
}
fn get(&mut self) -> &u32 {
if let Some(val) = self.try_get() {
return val;
}
self.a = true;
self.b = 10;
return &self.b;
}
}
Error:
error[E0506]: cannot assign to `self.a` because it is borrowed
--> src/lib.rs:19:9
|
14 | fn get(&mut self) -> &u32 {
| - let's call the lifetime of this reference `'1`
15 | if let Some(val) = self.try_get() {
| -------------- borrow of `self.a` occurs here
16 | return val;
| --- returning this value requires that `*self` is borrowed for `'1`
...
19 | self.a = true;
| ^^^^^^^^^^^^^ assignment to borrowed `self.a` occurs here
As I understand, it can't see, that reference at the top will be released before mutable change, but why? It can prove it without the function, why can't it do it with?
Is there any way to make function call work?
For me this really looks like a bug