Borrow Checker 4 @BoxyUwU @WaffleLapkin
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.
#[derive(Debug)]
struct Foo<'a>(&'a mut u32);
fn main() {
let mut data = 10;
let mut foo = Foo(&mut data);
mutate(&mut foo);
dbg!(foo);
}
fn mutate<'a>(f: &'a mut Foo<'a>) {
*f.0 += 1;
}
Solution
error[E0505]: cannot move out of `foo` because it is borrowed
--> examples/borrowck_4.rs:8:5
|
6 | let mut foo = Foo(&mut data);
| ------- binding `foo` declared here
7 | mutate(&mut foo);
| -------- borrow of `foo` occurs here
8 | dbg!(foo);
| ^^^^^^^^^
| |
| move out of `foo` occurs here
| borrow later used here
|
= note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider cloning the value if the performance cost is acceptable
|
7 | mutate(&mut foo).clone();
| ++++++++
For more information about this error, try `rustc --explain E0505`.
error: could not compile `code` (example "borrowck_4") due to 1 previous error
mutate
forces the lifetime of the reference to be the same as the lifetime of the foo
itself, so you effectively can't use it ever again — any reference will overlap with the one passed to mutate
.
To fix this you need to detach the lifetime of the reference from Foo
's lifetime:
fn mutate<'a, 'b>(f: &'a mut Foo<'b>) { ... }
Alternatively you can elide both lifetimes:
fn mutate(f: &mut Foo<'_>) { ... }