Reputation: 43
Consider the following minimal example:
type Task<'a> = Box<dyn std::future::Future<Output = ()> + 'a>;
type Context<'s> = &'s str;
trait MyTrait {
fn compute<'a>(&'a self, ctx: Context<'a>) -> Task<'a>
where
Self: 'a;
}
impl<F: for<'b> Fn(Context<'b>) -> Task<'b>> MyTrait for F {
fn compute<'a>(&'a self, ctx: Context<'a>) -> Task<'a>
where
Self: 'a,
{
(self)(ctx)
}
}
fn bla<'op>(input: &'op usize) -> impl MyTrait + 'op {
let v: Box<dyn for<'b> Fn(Context<'b>) -> Task<'b> + 'op> = Box::new(move |ctx| {
Box::new(async move {
println!("{}", &ctx[*input..]);
()
})
});
v
}
The compiler generated error message is:
error: lifetime may not live long enough
--> src/main.rs:22:9
|
20 | fn bla<'op>(input: &'op usize) -> impl MyTrait + 'op {
| --- lifetime `'op` defined here
21 | let v: Box<dyn for<'b> Fn(Context<'b>) -> Task<'b> + 'op> = Box::new(move |ctx| {
22 | / Box::new(async move {
23 | | println!("{}", &ctx[*input..]);
24 | | ()
25 | | })
| |__________^ returning this value requires that `'op` must outlive `'static`
I don't understand why 'op
must outlive 'static
. The lifetime of the returned Task
is bound by 'b
which in turn is shorter than the Self
of the boxed closure, and thus of 'op
.
I also tried to model the lifetime of the trait object more explicitly, but got the same error message from this:
type Task<'a> = Box<dyn std::future::Future<Output = ()> + 'a>;
type Context<'s> = &'s str;
trait MyTrait<'l> {
fn compute<'a>(&'l self, ctx: Context<'a>) -> Task<'l>
where
'l: 'a;
}
impl<'c, F: 'c + for<'b> Fn(Context<'b>) -> Task<'b>> MyTrait<'c> for F {
fn compute<'a>(&'c self, ctx: Context<'a>) -> Task<'c>
where
'c: 'a,
{
(self)(ctx)
}
}
fn bla<'op>(input: &'op usize) -> impl MyTrait<'op> + 'op {
let v: Box<dyn for<'b> Fn(Context<'b>) -> Task<'b> + 'op> = Box::new(move |ctx| {
Box::new(async move {
println!("{}", &ctx[*input..]);
()
})
});
v
}
Edit: I guess another more open way of asking this question would be: How to I constrain the lifetime of a HRTB by an outer lifetime?
Upvotes: 1
Views: 277
Reputation: 71340
I don't understand why
'op
must outlive'static
. The lifetime of the returnedTask
is bound by'b
which in turn is shorter than theSelf
of the boxed closure, and thus of'op
.
Who said? The only thing the compiler knows about it is that it is required to be true for any lifetime (HRTB). Any lifetime includes 'static
, and therefore the compiler requires 'op: 'b
which implies 'op: 'static
.
Upvotes: 1