Skip to content

Consider adding spawn_unchecked for non-static futures #2385

@rnarubin

Description

@rnarubin

Currently the various spawn functions require the provided future to have a 'static lifetime, in much the same way that std::thread::spawn requires the passed closure to have a 'static bound. This is because there's nothing constraining the future from outliving its originating scope, so for soundness it should not have any shorter borrows.

In theory, however, there are ways to constrain the lifespan of a future (e.g. closure scopes and forceful cancellation) such that it would be safe to borrow from a non-'static scope. For libraries exploring this design space, the only current workaround to spawn such a future is to box it as a trait object and then transmute to the static lifetime:

unsafe fn make_static(f: impl Future<Output=()> + Send) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>> {
  std::mem::transmute::<
    Pin<Box<dyn Future<Output=()> + Send>>,
    Pin<Box<dyn Future<Output=()> + Send + 'static>>
  >(Box::pin(f))
}

Although this works, it requires both an allocation and dynamic dispatch (where the underlying scheduler will also add similar indirection). This is even more complicated when the Output type is non-'static, which is a can of worms I won't open here for brevity.

I propose adding an unsafe spawn_unchecked function to the Handle type with a signature like this:

pub unsafe fn spawn_unchecked<'a, F>(&self, f: F) -> JoinHandle<F::Output>
where
    F: Future + Send + 'a,
    F::Output: Send + 'a; 

This is similar to the proposal for adding such a function to std::thread with exactly the same motivation: allowing libraries to build scoped-spawn functionality without the overhead of lifetime workarounds.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-tokioArea: The main tokio crateC-feature-requestCategory: A feature request.M-taskModule: tokio/task

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions