I was writing code that basically summed to something like this:
struct Thing<'a> {
thingy: Option<&'a str>,
}
impl<'a> Thing<'a> {
fn thingy(&mut self, thingy: &'a str) {
self.thingy = Some(thingy);
}
}
fn perform<F>(f: F)
where F: FnOnce() + Send + Sync + 'static
{
f()
}
fn main() {
let mut thing = Thing { thingy: None };
perform(move || {
let thingy = "hello world".to_string();
thing.thingy(&thingy);
});
}
Since I'm using move
, I expected thing
to be moved inside the closure, but I was surprised that it wasn't, and I got this error instead:
error[E0597]: `thingy` does not live long enough
--> src/main.rs:22:22
|
18 | let mut thing = Thing { thingy: None };
| --------- lifetime `'1` appears in the type of `thing`
...
22 | thing.thingy(&thingy);
| -------------^^^^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `thingy` is borrowed for `'1`
23 | });
| - `thingy` dropped here while still borrowed
This can be fixed by manually moving thing inside the closure like so:
fn main() {
let thing = Thing { thingy: None };
perform(move || {
let mut thing = thing;
let thingy = "hello world".to_string();
thing.thingy(&thingy);
});
}
Yet, I am puzzled, isn't that what move
is for? Why is rust borrowing thing, despite the closure being move
?