struct Tmp(Vec<u32>);
impl Tmp {
fn test(&mut self) -> &mut u32 {
{
let opt = self.0.iter_mut().find(|x| **x == 12);
if let Some(val) = opt {
return val;
}
// opt it dropped and reference released
}
&mut self.0[0]
}
}
fn main() {}
error:
error[E0499]: cannot borrow `self.0` as mutable more than once at a time
--> src/main.rs:13:14
|
6 | let opt = self.0.iter_mut().find(|x| **x == 12);
| ------ first mutable borrow occurs here
...
13 | &mut self.0[0]
| ^^^^^^ second mutable borrow occurs here
14 | }
| - first borrow ends here
I am not 100% sure: in your inner block code, the return which jumps out of that control block, making the opt ends in function statement block instead. Since opt is a ref to an item in self.0, which is effectively a borrow of self.0, the compiler complains.
This below code will compile:
struct Tmp(Vec<u32>);
impl Tmp {
fn test(&mut self) -> &mut u32 {
{
let pos = self.0.iter_mut().position(|&mut x| x == 12);
if let Some(index) = pos {
return &mut self.0[index];
}
}
return &mut self.0[0];
}
}
fn main() {}
It compiles if you comment out return. This suggests the conflict is caused by the return type. It's equivalent to:
fn test<'self>(&'self mut self) -> &'self mut u32
so I guess the borrow checker does reasoning backwards, that if return val; is borrowed for the life for 'self lifetime, then opt is borrowed for entire 'self too, and self.0 is borrowed for the entire function too.