HashMap entry() method unexpected behaviour

I’ve just started learning Rust and have come across a seemingly bizarre behaviour of HashMap’s entry() method. In the below example, the method takes a mutable reference and returns the Entry enum. I am not even capturing and persisting the returned value. But the borrow checker seems to think a mutable reference to "s" is still in scope when the next iteration begins.

let mut window: HashMap<&String, i32> = HashMap::new();
let mut s = "help_me".to_string();
loop {
    let p = &mut s;        // ERROR

This shows snippet panics with error:

Line 27, Char 26: cannot borrow `s` as mutable more than once at a time (solution.rs)
27 |             window.entry(&mut s);
   |                          ^^^^^^ `s` was mutably borrowed here in the previous iteration of the loop

Can someone please explain this behaviour to me?

>Solution :

The map’s key type is &String. Let’s call the lifetime &'a String.

The entry() method may need insert the key into the map (this is the entire idea of the entry API). Therefore, it takes the same type as the key, that is, &'a String.

As you borrow s, you need the borrow to last for 'a so you can get &'a String from it. So, you borrow it mutably for 'a.

But the next time the loop is executing, while 'a is still active (because the map is still alive), you borrow s again, again for 'a, while it is already mutably borrowed for 'a so you cannot borrow it during that time. This is the error.

You probably want a map of String (not &String), or, even if you do want references, you can instead of doing window.entry(&mut s); to do window.entry(&s); and then it will work because you can borrow a value for a shared reference multiple times.

Leave a Reply