Reputation: 3368
I have the following setup where I am trying to create a Dummy
future which is intended to modify the values in-place inside the future obtained from f: FnMut(&mut i32) -> Fut
. I am passing the generic function fun
to substitute it, but I am getting different lifetimes.
#![allow(unused_variables)]
pub struct Dummy<Fut, F> {
f: F,
futures: futures::stream::FuturesUnordered<Fut>
}
impl<Fut, F> Dummy<Fut, F>
where
F: FnMut(&mut i32) -> Fut,
Fut: futures::Future<Output = ()>,
{
fn new(f: F) -> Self {
Self {
f,
futures: futures::stream::FuturesUnordered::new()
}
}
}
impl<Fut, F> futures::Future for Dummy<Fut, F>
where
F: FnMut(&mut i32) -> Fut,
Fut: futures::Future<Output = ()>
{
type Output = ();
fn poll(self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>) -> core::task::Poll<()> {
// logic emitted
core::task::Poll::Ready(())
}
}
fn fun<'a>(f: &'a mut i32) -> impl futures::Future<Output = ()> + 'a {
async move {
*f += 1;
}
}
#[tokio::main]
async fn main() {
Dummy::new(fun).await;
}
which gives the compile-error:
error[E0308]: mismatched types
--> src/main.rs:45:20
|
45 | Dummy::new(fun).await;
| ^^^^^^ one type is more general than the other
|
= note: expected trait `for<'r> FnOnce<(&'r mut i32,)>`
found trait `for<'a> FnOnce<(&'a mut i32,)>`
= note: the lifetime requirement is introduced here
error[E0308]: mismatched types
--> src/main.rs:45:20
|
45 | Dummy::new(fun).await;
| ^^^^^^ one type is more general than the other
|
= note: expected trait `for<'r> FnOnce<(&'r mut i32,)>`
found trait `for<'a> FnOnce<(&'a mut i32,)>`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to 4 previous errors
Is it possible to annotate the impl
in a way that removes these mismatched types error? I could annotate everything with 'static
, as I have done here: playground link. But I was trying to avoid this solution since I want to mutually borrow dependent data in the future poll
method.
Upvotes: 1
Views: 70
Reputation: 155246
The signature of fun()
connects the lifetime of the reference with the lifetime of the future it returns. You need to specify the same kind of connection on the Future
implementation of Dummy
:
impl<'a, Fut, F> futures::Future for Dummy<Fut, F>
where
F: FnMut(&'a mut i32) -> Fut,
Fut: futures::Future<Output = ()> + 'a,
Upvotes: 2