I reached this error in this example and I'm trying to understand what's happening.
use futures::future::{BoxFuture, FutureExt};
use std::sync::Arc;
use futures::lock::Mutex;
struct Message {}
struct Client {}
enum Error {
ConnectionClosed,
}
#[derive(Default)]
struct MyType{}
impl Client {
fn send_and_expect<'a, R: 'a + Default + Send>(
client: Arc<Mutex<Self>>,
message: &'a Message,
) -> BoxFuture<'a, Result<R, Error>> {
async move { Ok(R::default()) }.boxed()
}
pub fn connection_retrier<'a, R: 'a + Default + Send>(
client: Arc<Mutex<Self>>,
f: for<'b> fn(Arc<Mutex<Self>>, &'b Message) -> BoxFuture<'b, Result<R, Error>>,
f_m: &'a Message,
) -> BoxFuture<'a, Result<R, Error>>
{
async move {Ok(R::default())}.boxed()
}
async fn send_with_retry<'a>(
client: Arc<Mutex<Self>>,
message: &'a Message,
) -> Result<MyType, Error> {
let client = Arc::new(Mutex::new(Client{}));
Self::connection_retrier::<MyType>(client, Self::send_and_expect, message)
.await
}
}
Error:
error[E0308]: mismatched types
--> src/lib.rs:36:52
|
36 | Self::connection_retrier::<MyType>(client, Self::send_and_expect, message)
| ^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected fn pointer `for<'b> fn(Arc<_>, &'b Message) -> Pin<Box<(dyn futures::Future<Output = std::result::Result<MyType, Error>> + std::marker::Send + 'b)>>`
found fn pointer `fn(Arc<_>, &Message) -> Pin<Box<dyn futures::Future<Output = std::result::Result<MyType, Error>> + std::marker::Send>>`
Well, connection_retrier
requres a function f: for<'b> fn(Arc<Mutex<Self>>, &'b Message) -> BoxFuture<'b, Result<R, Error>>,
. The one I passed seems to fit the signature.
The way I view for<'b> fn...
is: I accept a function f
for any lifetime 'b
presented. So, for the particular lifetime 'a
, send_and_expect
seems to fit everything.
The only suspicion I have is for the lifetime of R
being fixed at 'a
in connection_retrier
so the f
with its for<'b>
is not free to give any lifetime for its R
. I think the lifetime of the R
in f
should be 'b
. Is it possible to force f
to have R
with lifetime 'b
?
Something like this:
f: for<'b> fn<RR: 'b>(Arc<Mutex<Self>>, &'b Message) -> BoxFuture<'b, Result<RR, Error>>,