1

I'm trying to kick off some async tasks in rust, then await them later in the code. Here's a simplified version of my code:

async fn my_async_fn() -> i64 {
  return 0;
}

async fn main() {
  let mut futures = HashMap::new();
  futures.insert("a", my_async_fn());
  // this is where I would do other work not blocked by these futures
  let res_a = futures.get("a").expect("unreachable").await;
  println!("my result: {}", res_a);
}

But when I try to run this, I get this self-contradictory message:

error[E0277]: `&impl futures::Future` is not a future
   --> my/code:a:b
    |
111 |   let res_a = futures.get("a").expect("unreachable").await;
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&impl futures::Future` is not a future
    |
    = help: the trait `futures::Future` is not implemented for `&impl futures::Future`
    = note: required by `futures::Future::poll`

How can I await futures that I've put into a HashMap? Or is there another way altogether?

mwlon
  • 798
  • 5
  • 19
  • Does this answer your question? [How do you call future::select on a Future stored in a struct from a method that takes &mut self?](https://stackoverflow.com/questions/60515999/how-do-you-call-futureselect-on-a-future-stored-in-a-struct-from-a-method-that) – E_net4 Apr 23 '21 at 13:03
  • 1
    Awaiting a future requires a mutable reference, not an immutable reference. – E_net4 Apr 23 '21 at 13:04
  • Also note that you will almost certainly want to _box_ your futures before you insert them into the `HashMap`. As written, your `HashMap` will only ever accept futures produced by calling `my_async_fn()`, which was probably not what you intended. – user4815162342 Apr 23 '21 at 13:59
  • @E_net4saysdon'tcopythat - it doesn't quite answer my question, but gives me a more complicated error message that `Unpin` is not implemented for `from_generator::GenFuture...` – mwlon Apr 25 '21 at 12:56
  • I said that having a mutable reference was a requirement, not a sufficient condition. The `Unpin` constraint is mentioned in the linked question. – E_net4 Apr 25 '21 at 12:59

1 Answers1

2

Using await requires the Future is pinned and mutable.

use std::collections::HashMap;

async fn my_async_fn() -> i64 {
    return 0;
}

#[tokio::main]
async fn main() {
    let mut futures = HashMap::new();
    futures.insert("a", Box::pin(my_async_fn()));
    // this is where I would do other work not blocked by these futures
    let res_a = futures.get_mut("a").expect("unreachable").await;
    println!("my result: {}", res_a);
}

Alsein
  • 4,268
  • 1
  • 15
  • 35