The following code has a borrow bug, which the compiler has caught:
use std::collections::HashMap;
use std::borrow::Borrow;
fn A(a: &mut HashMap<String, usize>) {
let mut tmp: HashMap<&str, usize> = HashMap::new();
{
for (ref entry,_) in a.iter() {
tmp.insert(entry, 0);
}
}
let x = a.get_mut("hello");
}
Here is what the compiler says:
a.rs:13:13: 13:14 error: cannot borrow `*a` as mutable because it is also borrowed as immutable
a.rs:13 let x = a.get_mut("hello");
^
a.rs:8:30: 8:31 note: previous borrow of `*a` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `*a` until the borrow ends
a.rs:8 for (ref entry,_) in a.iter() {
^
note: in expansion of for loop expansion
a.rs:8:9: 10:10 note: expansion site
a.rs:15:2: 15:2 note: previous borrow ends here
a.rs:5 fn A(a: &mut HashMap<String, usize>) {
...
a.rs:15 }
^
It took me a while to understand this error (primarily because I focused too much on the actual text of the error, and not the code itself). So I'm wondering if there is a way it could be improved?
At first I thought that the borrow of a
would end once its block was closed (line 11). But because a reference to each item of a
persists in tmp
, the borrow of a
doesn't end until tmp
goes out of scope.
Is this pattern something the compiler could recognize and report on? Something like "borrow of a
does not end at block on line 11 due to reference on line XYZ"