The following error goes away if I do as rustc tells me to, and change the bound to
where F: Fn() -> () + 'static
pub struct Struct(Box<dyn Fn() -> ()>);
pub fn example<F>(f: F)
where
F: Fn() -> ()
{
Struct(Box::new(|| ())); // ok
Struct(Box::new(f)); // error: The parameter type `F` may not live long eneough
// help: consider adding an explicit lifetime bound: `F: 'static`
}
However, I just don't understand what 'static means here. It doesn't seem to mean that the closure itself lives forever.
At least, it doesn't seem like the closure lives forever. If I have the closure own some data, that data gets dropped at some point, which makes me suspect the closure is dropped:
pub struct Struct(Box<dyn Fn() -> ()>);
#[derive(Debug)]
struct DropMe;
impl Drop for DropMe {
fn drop(&mut self) {
println!("dropped");
}
}
/// prints:
/// "got DropMe"
/// "got DropMe"
/// "dropped"
/// "end of program"
pub fn main() {
let d = DropMe;
example(move || {
println!("got {:?}", d);
});
println!("end of program")
}
pub fn example<F>(f: F)
where
F: Fn() -> () + 'static
{
let s = Struct(Box::new(f));
s.0();
s.0();
}
Is 'static
an upper bound on the lifetime of the closure rather than a lower bound? 'static
makes sense as an upper bound, then example
would be saying "give me a function that I can hold on to as long as I want", which in practice can be less than the 'static
lifetime.
How can I tell when + 'lifetime
adds 'lifetime
as an upper bound vs. a lower bound?
The Rustonomicon chapter on subtyping+variance doesn't seem to cover this, and I couldn't find the information I was looking for in the Rust Book or Rust Reference.
main
and callee isexample
.example
asks for an arg with a'static
lifetime. You wrote that, from the caller's POV, the lifetime is a lower bound. If that's the case, then the second example shouldn't compile, but it does.f
's lifetime ends before the static lifetime: the closure isdrop
ed before "end of program" is printed. What I think is happening is that'static
is an upper bound. The compiler picks a lifetime that ends just beforeprintln!("end of program")
. – Inclined