How to resolve borrow mutable more than once

struct Tree {
    pub key: String,
    pub children: Vec<Tree>
}

impl Tree {
    pub fn find(&mut self, key: &str) -> &mut Self {
        let result = self.children.iter_mut().find(|k| k.key.eq(key));
        
        match result {
            Some(value) => value,
            None => {
                let new = Tree {
                    key: key.to_owned(),
                    children: vec![],
                };
                self.children.push(new);
                let len = self.children.len();
                &mut self.children[len - 1]
            }
        }
    }
}

fn main() {
    let mut t = Tree {
        key: String::new(),
        children: vec![]
    };
    
    let _new = t.find("a");
}

In my understanding, if the find method returns None, there should be no actual reference to self, and an error is reported here, borrow mutable more than once. How to fix

You are right, and this is a well-known limitation of the current borrow checker. It is being worked on, and the next-generation borrow checker will allow this kind of code.

In the meantime, there are multiple solutions:

  1. The easy one: Use indices instead of references
  2. The proper one (that also improves asymptotic complexity): use a map instead of a vector, which has an Entry API specifically tailored to convenient get-or-insert and similar operations. This is only possible if the order of children does not matter (which I assume it doesn't, given that they have explicit keys).
4 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.