rusthashmapborrow-checkermutability

Simultaneous Mutable and Immutable HashMap gets


I'm working with a struct Node and node_map defined as

pub struct Node<'a> {
    id: i32,
    next: HashMap<String, &'a Node<'a>>,
}

let mut node_map = HashMap::<i32, LexerNode>::new();

I'm using the node_map as shown below

let Some(node) = node_map.get_mut(&node_id) else {
    return Err("Invalid node_id".to_string());
};

// some logic to get edge_pairs
for pair in edge_pairs {
    // some logic to get neighbour_id

    let Some(neighbour) = node_map.get(&neighbour_id) else {
        return Err("Invalid node_id".to_string());
    };

    node.next.insert(char.to_string(), neighbour);
}

I'm getting the error

cannot borrow node_map as immutable because it is also borrowed as mutable
immutable borrow occurs here [E0502]

which refers to the node.next.insert statement. I need node to be mutable (to be able to insert the new value) and neighbour to be immutable. It's giving this borrowing error. How do I fix this? I would prefer not using a clone since I want a reference to the nodes.


Solution

  • This cannot be done.

    Well, technically this can: if edge_pair is an array at least, you can use get_many_mut() (which is available on nightly and in hashbrown). If not, well, I don't know. But this doesn't matter.

    You are fighting the inevitable. You are trying to do it so that the node map will contain a reference that contain a reference that contain a reference... that eventually contain a reference to content stored in the node map.

    And this is outright impossible. Well, not outright, there are solutions. But the best solution is: don't. Clone your way out of trouble.

    See Why can't I store a value and a reference to that value in the same struct? for more about self-referential structs.