Async methods as parameters to another async method


    async fn first(&mut self, input: &str) { ... }

Is, behind the scenes, doing something like this:

type FirstFut<'a, 'b> = impl Future<Output = ()>;
fn first<'a, 'b>(&'a mut self, input: &'b str) -> FirstFut<'a, 'b> {
    async move {
        let _force_always_move = (&self, &input);
        // ...

Of particular note, the opaque future type which is returned is parameterized by lifetimes. But here:

async fn call_on_list<F, Fut>(&mut self, mut f: F, list: Vec<&str>)
        F: FnMut(&mut Foo, &str) -> Fut,
        Fut: std::future::Future<Output = ()>,

Fut has to be a singular, fully qualified type -- not something with free lifetime parameters, say. By implication, Fut can't capture (be parameterized by) any of the input lifetimes.

So it's impossible for first to meet that bound.

You can:

  • Hide the opaque types by using Pin<Box<dyn Future<...> + Send + 'a>> or so
  • Make your own AsyncFn trait that side-steps mentioning the return type in bounds

Here's an example of the former. There's other threads where I walk through the latter approach, and can do so again when I have some time if you like.[1]

  1. Really need to get around to writing up some more permanent pages on Fn and friends... ↩︎