Borrow Checker 5 @WaffleLapkin @BoxyUwU

Warning: this quiz is still "work-in-progress", some questions might not have good explanations (or any at all), formatting/structure/titles/etc are not final, and so on. You might want to return here on a later date.

use std::collections::HashMap;

fn get_or_insert_1234(map: &mut HashMap<u32, u64>) -> &mut u64 {
    if let Some(v) = map.get_mut(&0) {
        return v;
    }

    map.insert(0, 1234);
    map.get_mut(&0).unwrap()
}

fn main() {}
Solution
error[E0499]: cannot borrow `*map` as mutable more than once at a time
 --> examples/borrowck_5.rs:8:5
  |
3 | fn get_or_insert_1234(map: &mut HashMap<u32, u64>) -> &mut u64 {
  |                            - let's call the lifetime of this reference `'1`
4 |     if let Some(v) = map.get_mut(&0) {
  |                      --- first mutable borrow occurs here
5 |         return v;
  |                - returning this value requires that `*map` is borrowed for `'1`
...
8 |     map.insert(0, 1234);
  |     ^^^ second mutable borrow occurs here

error[E0499]: cannot borrow `*map` as mutable more than once at a time
 --> examples/borrowck_5.rs:9:5
  |
3 | fn get_or_insert_1234(map: &mut HashMap<u32, u64>) -> &mut u64 {
  |                            - let's call the lifetime of this reference `'1`
4 |     if let Some(v) = map.get_mut(&0) {
  |                      --- first mutable borrow occurs here
5 |         return v;
  |                - returning this value requires that `*map` is borrowed for `'1`
...
9 |     map.get_mut(&0).unwrap()
  |     ^^^ second mutable borrow occurs here

For more information about this error, try `rustc --explain E0499`.
error: could not compile `code` (example "borrowck_5") due to 2 previous errors

This error is the limitation of the current borrow checker. Because v is returned from the function, the lifetime of the reference returned from the first get_mut is inferred to be "until the end of the function". The current borrow checker does not understand that the None variant does not contain the lifetime, so after the if the reference does not need to be kept alive (there is no reference).

This is a very famous example which is fixed by the next implementation of the borrow checker, polonius.