Consider the following Rust program
struct Foo {
bar: Vec<i32>,
baz: i32
}
impl Foo {
fn get_an_iter(&self) -> impl Iterator<Item=&i32> {
self.bar.iter()
}
fn do_mut_stuff_works(&mut self) {
for num in self.bar.iter() {
self.baz += num;
}
}
fn do_mut_stuff_does_not_work(&mut self) {
for num in self.get_an_iter() {
self.baz += num;
}
}
}
In do_mut_stuff_works
I am iterating over the vector bar
and change the field baz
. To do this, the method needs to take &mut self
.
Now if I move the creation of the iterator from inline to a method get_an_iter
, and try to iterate over that in do_mut_stuff_does_not_work
, the borrow checker complains.
How is it that, when using get_an_iter
, the immutable borrow stays alive for the whole loop such that my mutable borrow at self.baz += num
fails, but when I just create the iterator inside the method, with for num in self.bar.iter()
, the borrow checker is happy?
The full compiler output is:
Compiling playground v0.0.1 (/playground)
error[E0502]: cannot borrow `self.baz` as mutable because it is also borrowed as immutable
--> src/lib.rs:20:13
|
19 | for num in self.get_an_iter() {
| ------------------
| |
| immutable borrow occurs here
| immutable borrow later used here
20 | self.baz += num;
| ^^^^^^^^^^^^^^^ mutable borrow occurs here
For more information about this error, try `rustc --explain E0502`.
error: could not compile `playground` (lib) due to 1 previous error