How to improve this borrowck error


#1

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”