Skip to content

Builder::spawn should encode the metadata lifetime contract #76

@jstarks

Description

@jstarks

Considering this from Builder:

pub fn spawn<F, Fut, S>(self, future: F, schedule: S) -> (Runnable<M>, Task<Fut::Output, M>)
where
    F: FnOnce(&M) -> Fut,
    Fut: Future + Send + 'static,
    Fut::Output: Send + 'static,
    S: Schedule<M> + Send + Sync + 'static,
{
    ...
}

My understanding of the contract around metadata is that it is allocated and pinned as part of task allocation, it is guaranteed to remain valid at least as long as the task's future, and it will not be deallocated without being dropped. If these were not intended to be guarantees, it would be strange to have this extra F wrapper at all, because the caller already had access to the metadata in its old location before it was moved into the task.

However, spawn does not reflect these guarantees in the type system.

I don't think the lifetime guarantee can be encoded with Rust today. You need something like:

F: for<'a> FnOnce(&'a M) -> Fut + 'a

But that doesn't work. Maybe something similar could be done with an explicit trait with GAT and RPITIT, though.

But you can encode the fact that the metadata is effectively pinned for its lifetime. And I think this would be a useful thing to do at the next breaking change:

F: FnOnce(Pin<&M>)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions