Borrow checker limitation?

I'm trying to code something that looks like the following code, but I get an errors saying that self is already borrowed when I'm calling the second method.

I don't understand what happen here, the code seams correct. Also is there any workaround for this?

(playground)

struct Foo;

impl Foo {
    fn get_mut(&mut self) -> Option<&mut str> {
        if let Some(x) = self.find_1_mut() {
            return Some(x);
        }
        
        if let Some(x) = self.find_2_mut() { // Error: `self` already borrowed
            return Some(x);
        }
        
        None
    }

    fn find_1_mut(&mut self) -> Option<&mut str> {
        todo!();
    }
    
    fn find_2_mut(&mut self) -> Option<&mut str> {
        todo!();
    }
}

Yes, this is a known limitation. Here are a handful of historical references (including several known workarounds):

It is the primary motivation for the standard library acquiring methods like slice::get_disjoint_mut() and HashMap::get_disjoint_mut().

2 Likes

If you don't need both returns to be active at the same time, this isn't a partial borrowing or disjoint &mut problem. It's a conditional return of a borrow problem.

The next borrow checker is expected to accept your code, without changing the APIs.

8 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.