Rust disallows disjoint mutable borrows in a mutating method

30 views Asked by At

Consider the following abstract example (minimized from meaningful code):

struct Cucumber {
    vine: usize,
}

impl Cucumber {
    fn iter_mut(&mut self) -> impl Iterator<Item = &mut usize> {
        Some(&mut self.vine).into_iter()
    }
    
    fn find_vine(&mut self) -> Option<&mut usize> {
        {
            let vines = self.iter_mut();
            for v in vines {
                if *v > 0 {
                    return Some(v);
                }
            }
        }
        self.vine = 1;
        None
    }
}

fn main() {
    let mut c = Cucumber { vine: 0 };
    assert_eq!(c.find_vine(), None);
}

The compiler complains thus:

   Compiling playground v0.0.1 (/playground)
error[E0506]: cannot assign to `self.vine` because it is borrowed
  --> src/main.rs:19:9
   |
10 |     fn find_vine(&mut self) -> Option<&mut usize> {
   |                  - let's call the lifetime of this reference `'1`
11 |         {
12 |             let vines = self.iter_mut();
   |                         ---- `self.vine` is borrowed here
...
15 |                     return Some(v);
   |                            ------- returning this value requires that `*self` is borrowed for `'1`
...
19 |         self.vine = 1;
   |         ^^^^^^^^^^^^^ `self.vine` is assigned to here but it was already borrowed

For more information about this error, try `rustc --explain E0506`.
error: could not compile `playground` (bin "playground") due to previous error

But, to my intuition, the borrow vines is already not live at the point where we assign to self.vine. Could anyone hint, please, what is the problem here and is there a way to fix it without changing much the semantics of the code?

0

There are 0 answers