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.