5

The following code does not compile bceause the compiler can not assure hashmap_of_lists would live long enough. I can not overcome this.

I've tried using Arc and Mutex but then I had other issues because of the async fashion of some_func and using Mutex inside.

use futures; // 0.3.5
use std::collections::HashMap;
use tokio; // 0.2.21

async fn some_func(_some_slice: &mut [String]) {}

#[tokio::main]
async fn main() {
    let mut hashmap_of_lists = HashMap::<String, Vec<String>>::new();
    let mut join_handles = Vec::new();

    for (_, value) in hashmap_of_lists.iter_mut() {
        let future = some_func(value);
        let join_handle = tokio::task::spawn(future);
        join_handles.push(join_handle);
    }

    futures::future::join_all(join_handles).await;
}

I get this error

error[E0597]: `hashmap_of_lists` does not live long enough
  --> src/main.rs:12:23
   |
12 |     for (_, value) in hashmap_of_lists.iter_mut() {
   |                       ^^^^^^^^^^^^^^^^-----------
   |                       |
   |                       borrowed value does not live long enough
   |                       argument requires that `hashmap_of_lists` is borrowed for `'static`
...
19 | }
   | - `hashmap_of_lists` dropped here while still borrowed

kmdreko
  • 42,554
  • 6
  • 57
  • 106
Gal Ben David
  • 410
  • 4
  • 10
  • 6
    `tokio::task::spawn` requires a `'static` future, but a future that takes a borrowed reference is not `'static`. The esiest solution woult be to use `into_iter()` instead of `iter_mut()` and pass ownership of the lists into your future, but I don't know if that will fit your real code. – rodrigo Sep 02 '20 at 12:37
  • async have their own version of mutex https://docs.rs/tokio/0.2.13/tokio/sync/struct.Mutex.html – Stargateur Sep 02 '20 at 12:55
  • It looks like your question might be answered by the answers of [Borrowed value does not live long enough with a Tokio future](https://stackoverflow.com/q/55610608/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Sep 02 '20 at 13:49
  • Still, I could not manage to overcome this issue. Using a mutex requires an unneeded lock. As for the into_iter, still, I could not satisfy the borrow checker to think that the reference would still point at a valid address. – Gal Ben David Sep 02 '20 at 14:26
  • rodrigo advice code https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=90e10fd5e6e242f1a3fead68ce81435a – Stargateur Sep 02 '20 at 14:41
  • Thanks for the comment, but the problem with your solution is that the value is copied. I've been trying to come with a solution without a copy. :/ – Gal Ben David Sep 02 '20 at 16:35
  • If you want to avoid passing `Vec` to `some_func()`, then maybe you can wrap it inside a `Box`, i.e. `Box>`. However, passing `Vec` to a function doesn't cost much, since the content of `Vec` is heap-allocated. It's a fixed 24 bytes on my machine, while `Box` is 8 bytes. – dianhenglau Sep 02 '20 at 18:55

0 Answers0