I have the following Rust program which passes a closure to a function generic in a lifetime 'a
and a closure of type F
, which calls the closure with a reference to some local data:
fn other_function<'a, F>(f: F)
where F: Fn(&'a u32)
{
let the_value = 0;
f(&the_value);
}
fn main() {
other_function(|_| { /* do nothing */ });
}
This fails to compile, with the following messages:
<anon>:5:8: 5:17 error: `the_value` does not live long enough
<anon>:5 f(&the_value);
^~~~~~~~~
<anon>:3:1: 6:2 note: reference must be valid for the lifetime 'a as defined on the block at 3:0...
<anon>:3 {
<anon>:4 let the_value = 0;
<anon>:5 f(&the_value);
<anon>:6 }
<anon>:4:23: 6:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 4:22
<anon>:4 let the_value = 0;
<anon>:5 f(&the_value);
<anon>:6 }
error: aborting due to previous error
playpen: application terminated with error code 101
My minimal example might be a bit too minimal now, since for this example a valid solution is to remove 'a,
and 'a
. However, I have a similar situation in a more complicated program in which explicit lifetimes seem required.
Is there a way of specifying lifetimes manually, such that the above program gets accepted by the compiler?
The problem is that the caller of other_function
gets to pick the lifetime that will fill in 'a
, but you want other_function
to do it. You could use a bit of syntax called higher ranked trait bounds:
fn other_function<F>(f: F)
where F: for <'a> Fn(&'a u32)
{
let the_value = 0;
f(&the_value);
}
fn main() {
other_function(|_| { /* do nothing */ });
}
As you pointed out, in this case, it makes more sense to omit the 'a
completely. It's possible that your case needs something more complicated, but with your example nothing else makes sense. The caller cannot possibly specify any lifetime that will be compatible with a stack-allocated variable inside the method you are calling.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With