0

I'm trying to write something in Rust (which I love but don't have much experience yet) and found a hurdle I have no idea how to sort out.

My intention is to spawn an asynchronous task passing an initial state as parameter. The asynchronous task will take that value (it can keep ownership of it) and use it further. Thing is the initial value needs to be a generic. And I get an error complaining about the lifetime of StateT and I cannot let the compiler know that I want to move it / copy it to the async block.

async fn start<StateT>(initial_value: StateT) -> impl futures::Future
where
    StateT: Send,
{
    tokio::spawn(async move {
        process(initial_value);
    })
}

I tried making StateT: Copy + Send + Sync, etc but it doesn't like it. Only 'static works but I guess that's not right (it's not a constant that I will pass, but some arbitrary struct).

The error message is:

error[E0310]: the parameter type `StateT` may not live long enough
 --> src/workflow2.rs:7:5
  |
7 | /     tokio::spawn(async move {
8 | |         process(initial_value);
9 | |     })
  | |______^ ...so that the type `StateT` will meet its required lifetime bounds
  |
help: consider adding an explicit lifetime bound...
  |
5 |     StateT: Send + 'static,
  |                  +++++++++

If I try passing an i32 or a String instead of the generic it works just fine. So I guess I'm missing some trait bound for StateT that provides what's missing.

helios
  • 13,574
  • 2
  • 45
  • 55

1 Answers1

5

Only 'static works but I guess that's not right (it's not a constant that I will pass, but some arbitrary struct).

This is common Rust lifetime misconception #2: T: 'static does not mean that T lives for the entire program, and even less that T is a constant. It only means that T is a fully self-contained type and that it doesn't borrow any other data. So StateT: 'static is the right thing to do here:

async fn start<StateT>(initial_value: StateT) -> impl futures::Future
where
    StateT: Send + 'static,
{
    tokio::spawn(async move {
        process(initial_value);
    })
}
Jmb
  • 18,893
  • 2
  • 28
  • 55