This code compiles (playground link):
use std::collections::HashMap;
fn main() {
let mut h = HashMap::<char, Vec<i32>>::new();
h.insert('a', vec![0]);
let first_borrow = h.get_mut(&'a').unwrap();
first_borrow.push(1);
let second_borrow = h.get_mut(&'a').unwrap();
second_borrow.push(2);
}
Changing the order of the code using the borrows (the push()
calls)...
let first_borrow = h.get_mut(&'a').unwrap();
let second_borrow = h.get_mut(&'a').unwrap();
first_borrow.push(1);
second_borrow.push(2);
...makes it not compile:
error[E0499]: cannot borrow `h` as mutable more than once at a time
--> src/main.rs:8:25
|
7 | let first_borrow = h.get_mut(&'a').unwrap();
| - first mutable borrow occurs here
8 | let second_borrow = h.get_mut(&'a').unwrap();
| ^ second mutable borrow occurs here
9 | first_borrow.push(1);
| ------------ first borrow later used here
Moreover, using first_borrow
past the instantiation of second_borrow
also doesn't compile:
let first_borrow = h.get_mut(&'a').unwrap();
first_borrow.push(1);
let second_borrow = h.get_mut(&'a').unwrap();
second_borrow.push(2);
// ...
first_borrow.push(1);
This is surprising given what the documentation seems to say about scopes. In the code that compiles, why don't we have two mutable borrows there, too?
In the example that compiles, does Rust see that, after let second_borrow = ...
, there's no more mention of first_borrow
anywhere, so it unborrows the mutable borrow of first_borrow
and thus retains a single borrow across the whole scope of main()
?!