Borrow Checker 3 @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.
fn foo(a: &mut u32) -> u32 {
let mut b = || &mut *a;
*b() = 12;
*b() = 73;
*a
}
fn main() {
foo(&mut 292);
}
Solution
error: captured variable cannot escape `FnMut` closure body
--> examples/borrowck_3.rs:2:20
|
1 | fn foo(a: &mut u32) -> u32 {
| - variable defined here
2 | let mut b = || &mut *a;
| - ^^^^^^-
| | | |
| | | variable captured here
| | returns a reference to a captured variable which escapes the closure body
| inferred to be a `FnMut` closure
|
= note: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape
error: could not compile `code` (example "borrowck_3") due to 1 previous error
The closure assigned to b
can only return a reference with one specific lifetime (because it has no lifetimes in arguments).
So both calls to b
return a unique (mutable) reference with the same lifetime, which is an error, because all unique references must be disjoint.
If you inline calls to b
it would work though:
fn foo(a: &mut u32) -> u32 {
let mut b = || &mut *a;
*(&mut *a) = 12;
*(&mut *a) = 73;
*a
}
This is fine because reborrows return different lifetimes, allowing them to be disjoint.