How to fix lifetime issue?
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=4feff1b4a4c306f9514a98530d8f0daf
use async_trait::async_trait;
use std::future::Future;
use std::pin::Pin;
#[async_trait]
pub trait Handle {
type Context;
type Output;
async fn call(&self, cx: Pin<&mut Self::Context>) -> Self::Output;
}
#[async_trait]
impl<F, Fut> Handle for F
where
F: Send + Sync + 'static + Fn(Pin<&mut Context>) -> Fut,
Fut: Future<Output = Result> + Send + 'static,
Fut::Output: 'static,
Context: Send + 'static,
{
type Context = Context;
type Output = Result;
async fn call(&self, cx: Pin<&mut Self::Context>) -> Self::Output {
(*self)(cx).await
}
}
pub type Result = std::io::Result<()>;
pub struct Context {}
#[cfg(test)]
mod tests {
use super::*;
use futures::executor::block_on;
#[test]
fn it_works() {
block_on(async move {
async fn a(cx: Pin<&mut Context>) -> Result {
println!("exec fn a");
Ok(())
}
let mut cx = Context {};
let mut cx: Pin<&mut Context> = Pin::new(&mut cx);
let f: Box<dyn Handle<Context = Context, Output = Result>> = Box::new(a);
// let _ = f(cx).await;
// f.call(cx).await;
// a.call(cx).await;
});
}
}
Compiling playground v0.0.1 (/playground)
error[E0271]: type mismatch resolving `for<'r> <for<'_> fn(std::pin::Pin<&mut Context>) -> impl core::future::future::Future {tests::it_works::{{closure}}#0::a} as std::ops::FnOnce<(std::pin::Pin<&'r mut Context>,)>>::Output == _`
--> src/lib.rs:46:74
|
46 | let f: Box<dyn Handle<Context = Context, Output = Result>> = Box::new(a);
| ^^^^^^^^^^^ expected bound lifetime parameter, found concrete lifetime
|
= note: required because of the requirements on the impl of `Handle` for `for<'_> fn(std::pin::Pin<&mut Context>) -> impl core::future::future::Future {tests::it_works::{{closure}}#0::a}`
= note: required for the cast to the object type `dyn Handle<Context = Context, Output = std::result::Result<(), std::io::Error>>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0271`.
error: could not compile `playground`.
To learn more, run the command again with --verbose.