I'm trying to figure out how to specify trait bounds that would satisfy any async fn
pointer, but currently i'm stumbling in limitation of type inference
Following code:
pub enum TaskResult {
Done
}
pub trait TaskHandler {
fn name(&self) -> Cow<'static, str>;
fn handle(&self, task: &String) -> Box<dyn Future<Output=TaskResult>>;
}
impl<R: 'static + Future<Output=TaskResult>, C: Fn(&String) -> R> TaskHandler for (&'static str, C) {
#[inline(always)]
fn name(&self) -> Cow<'static, str> {
self.0.into()
}
#[inline(always)]
fn handle(&self, task: &String) -> Box<dyn Future<Output=TaskResult>> {
Box::new((self.1)(task))
}
}
async fn test(task: &String) -> TaskResult {
TaskResult::Done
}
fn check() {
let handlers: Vec<Box<dyn TaskHandler>> = Vec::new();
handlers.push(Box::new(("TEST", test)));
}
Link: Rust Playground
It fails with:
error[E0308]: mismatched types
--> src/main.rs:32:19
|
32 | handlers.push(Box::new(("TEST", test)));
| ^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected associated type `<for<'_> fn(&String) -> impl Future {test} as FnOnce<(&String,)>>::Output`
found associated type `<for<'_> fn(&String) -> impl Future {test} as FnOnce<(&String,)>>::Output`
function pointers are in general tricky when you want to implement trait for pointer itself, but usually there is no problem when it is Fn
trait.
Yet in this case it is a bit tricky to do with reference parameter.
It is not clear how to force compiler to understand reference lifetime
P.s. I also noticed that reference doesn't work well for returning future anyway so it is not big deal, but I'm still curious if it is possible to tell compiler how to understand it