I have code like this (this is how #[async_trait]
is expanded):
trait BoolTrait {
fn check<'s: 'f, 'v: 'f, 'f>(&'s self, value: &'v i32) -> Pin<Box<dyn Future<Output = bool> + 'f>>;
}
Actually it says that Future ('f)
can contain refs to self ('s)
and v ('v)
, so lifetime of 's
and 'v
must be longer than Future 'f
lifetime.
Next, I want to make any closure with async body implement this trait:
impl<F, Fut> BoolTrait for F
where
F: Fn(&i32) -> Fut,
Fut: Future<Output = bool> {
fn check<'s: 'f, 'v: 'f, 'f>(&'s self, value: &'v i32) -> Pin<Box<dyn Future<Output=bool> + 'f>> {
Box::pin(self(value))
}
}
But this doesn't work:
error[E0309]: the parameter type `Fut` may not live long enough
|
16 | impl<F, Fut> BoolTrait for F
| --- help: consider adding an explicit lifetime bound...: `Fut: 'f`
...
21 | Box::pin(self(value))
| ^^^^^^^^^^^^^^^^^^^^^ ...so that the type `Fut` will meet its required lifetime bounds
Okay, let's try 'static
lifetime, just to make it compile (actually I think that my problem is here, but I don't know what correct lifetime should I use):
Fut: Future<Output = bool> + 'static
Let's check how it works:
async fn test<BT: BoolTrait>(bt: BT) {
let v = 42;
bt.check(&v).await;
}
fn main() {
block_on(test(|v: &i32| async { *v == 42 }));
}
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/lib.rs:13:39
|
13 | block_on(test(|v: &i32| async { *v == 42 }));
| ^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 13:23...
--> src/lib.rs:13:23
|
13 | block_on(test(|v: &i32| async { *v == 42 }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that the types are compatible
--> src/lib.rs:13:39
|
13 | block_on(test(|v: &i32| async { *v == 42 }));
| ^^^^^^^^^^^^
= note: expected `&&i32`
found `&&i32`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `impl futures::Future` will meet its required lifetime bounds
--> src/lib.rs:13:18
|
13 | block_on(test(|v: &i32| async { *v == 42 }));
| ^^^^
And this is where I am. Actually, I can fix it, by replacing value: &i32
param with value: i32
, but it's not I want, I want to use exactly reference.
If I correctly understand the error, the compiler says that Future lives shorter than ref to i32, because it contains ref to it, but in the trait impl I set 'static
.
It seems to me, that I need to specify somehow that the lifetime of Fut
must be shorter than the lifetime &i32
, in impl
.