Rust borrow checker multiple mutable reference in modifying element in linked list in a loop

Viewed 93

I'm trying to build some sort of linked list, each node has a keyword and vectors of the same node. In that for loop, i will traverse the linked list to get the vector, either already exist if keyword is the same, or create a new vector. I find it impossible to *not * violate the double mut reference error since I'll need to do iter_mut(), push() on the same path. Anyone has general idea on how to approach this?

pub struct Knowledge {
    pub title: String,
}

pub struct Entry {
    pub keyword: String,
    pub next: Vec<Box<KnowledgeEntry>>
}

pub enum KnowledgeEntry {
    Normal(Knowledge),
    Entry(Entry)
}

impl KnowledgeEntry {
    pub fn get_entry_mut (&mut self) -> Option<&mut Vec<Box<KnowledgeEntry>>> {
        match self {
            KnowledgeEntry::Entry(e) => {
                Some(&mut e.next)
            }
            KnowledgeEntry::Normal(k) => {None}
        }
    }
}

fn main () {
    let mut entry = Entry{keyword: "".to_owned(), next: vec![]};
    let mut current_container = &mut entry.next;
    let new_knowledge = Knowledge{title: "title1".to_owned()};
    // new knowledge to be insert in these hierarchy.
    let remaining_comp: Vec<_> = vec!["hier1", "hier2", "hier3"];
    // each loop will set current_container, either created from new, or found in the vector.
    for comp in remaining_comp.iter() {
        // true will be replace with body checking with keyword.
        let mut _result = current_container.iter_mut().find(|en| {true});
        if let Some(mut _res) = _result {
            // found the container. Set the current container
            if let KnowledgeEntry::Entry(ref mut entry) = &mut **_res {
                current_container = &mut entry.next;
            } else {
                break;
            }
        } else {
            // can't find the resulting container. Create a new vector, and move the container.
            let new_container: Vec<Box<KnowledgeEntry>> = vec![];
            let mut _temp = KnowledgeEntry::Entry(Entry {
                keyword: (*comp).to_string(),
                next: new_container
            });
            current_container.push(Box::new(_temp));
            let last_var = current_container.last_mut().unwrap();
            // get_entry_mut() to retrieve `_temp` that we have just moved.
            current_container = (**last_var).get_entry_mut().unwrap();
        }
    }
// found the container correspond to "hier1" -> "hier2" -> "hier3", add the entry.    
current_container.push(Box::new(KnowledgeEntry::Normal(new_knowledge)));
}

Playground

Produces the following errors:

error[E0499]: cannot borrow `*current_container` as mutable more than once at a time
  --> src/main.rs:50:13
   |
35 |         let mut _result = current_container.iter_mut().find(|en| {true});
   |                           ----------------- first mutable borrow occurs here
...
50 |             current_container.push(Box::new(_temp));
   |             ^^^^^^^^^^^^^^^^^
   |             |
   |             second mutable borrow occurs here
   |             first borrow later used here

error[E0499]: cannot borrow `*current_container` as mutable more than once at a time
  --> src/main.rs:51:28
   |
35 |         let mut _result = current_container.iter_mut().find(|en| {true});
   |                           ----------------- first mutable borrow occurs here
...
51 |             let last_var = current_container.last_mut().unwrap();
   |                            ^^^^^^^^^^^^^^^^^
   |                            |
   |                            second mutable borrow occurs here
   |                            first borrow later used here

error[E0499]: cannot borrow `*current_container` as mutable more than once at a time
  --> src/main.rs:57:1
   |
35 |         let mut _result = current_container.iter_mut().find(|en| {true});
   |                           ----------------- first mutable borrow occurs here
...
57 | current_container.push(Box::new(KnowledgeEntry::Normal(new_knowledge)));
   | ^^^^^^^^^^^^^^^^^
   | |
   | second mutable borrow occurs here
   | first borrow later used here
0 Answers
Related