Issue
This Content is from Stack Overflow. Question asked by rubo
The folliwing code fails to compile:
#[derive(Default)]
struct Foo {
values: Vec<i32>,
}
impl Foo {
fn len(&self) -> usize {
todo!()
}
fn set(&mut self) {
self.values[self.len()] = 0;
}
}
error[E0502]: cannot borrow `*self` as immutable because it is also borrowed as mutable
--> src/lib.rs:12:21
|
12 | self.values[self.len()] = 0;
| ------------^^^^^^^^^^-
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| mutable borrow later used here
There is a number of ways to fix this error, the most perplexing for me is this:
fn set(&mut self) {
self.set_len(self.len());
}
fn set_len(&mut self, index: usize) {
self.values[index] = 0;
}
Why does the first case fail to compile, while the second compiles? It seems to me that in both cases self
is borrowed twice in a single expression – one time mutably, and one time immutably. Is there a subtle reason for this that I am unable to see, or is it a borrow checker quirk?
Solution
It’s a borrow checker quirk. There’s a special rule implemented to solve the "call mutable method where an argument is the result of another method" issue.
There’s no special rule for "access a member and do something with that where the result of a method is needed". The member is borrowed first, and then the whole object can’t be borrowed for the method call anymore.
This Question was asked in StackOverflow by rubo and Answered by Sebastian Redl It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.