I'm having trouble with Rust lifetimes. Here's a code sample:
use std::sync::Mutex
struct Bar<'a> {
handler: Mutex<Option<Box<dyn 'a + Fn()>>>
}
impl<'a> Bar<'a> {
fn new() -> Bar<'a> {
Bar {handler: Mutex::new(None)}
}
fn baz(&'a self) {
let mut handler = self.handler.lock().unwrap();
*handler = Some(Box::new(|| self.doprint()));
}
fn doprint(&self) {
println!("hello from Bar");
}
fn runhandler(&self) {
let handler = self.handler.lock().unwrap();
if let Some(handler) = handler.as_ref() {
handler();
}
}
}
fn lala() {
let bar = Bar::new();
bar.baz();
}
The purpose is so it's possible to register a handler function, which is itself able to call methods of Bar
. The handler's lifetime is set so that the function needs to exist as long as Bar
does.
This produces the following error:
error[E0597]: `bar` does not live long enough
--> src/chain/rpc_db.rs:68:5
|
68 | bar.baz();
| ^^^^^^^^^ borrowed value does not live long enough
69 | }
| -
| |
| `bar` dropped here while still borrowed
| borrow might be used here, when `bar` is dropped and runs the destructor for type `Bar<'_>`
I'm not sure why this error is happening given that the 'a
lifetime is the lifetime of bar
, so it should get dropped at the same time as bar
. Although bar
is borrowed for the baz
call with an 'a
lifetime, that call ends before the end of the function, so shouldn't interfere with the destructor. I know it's possible to solve this problem with Arc
s but there's probably a better way.
Here's a more minimal example that fails with the same error:
use std::sync::Mutex
struct Bar<'a> {
handler: Mutex<Option<Box<dyn 'a + Fn()>>>
}
impl<'a> Bar<'a> {
fn new() -> Bar<'a> {
Bar {handler: Mutex::new(None)}
}
fn baz(&'a self) {
}
}
fn lala() {
let bar = Bar::new();
bar.baz();
}