Skip to content

The rules for how non-Send local variables "infect" an async function, making its Future type non-Send also, are stricter than they need to be. #63768

Open
@oconnor663

Description

@oconnor663

Here's an example which I think should compile, but which doesn't (cargo 1.39.0-nightly 3f700ec43 2019-08-19):

#![feature(async_await)]

fn require_send<T: Send>(_: T) {}

struct NonSendStruct { _ptr: *mut () }

async fn my_future() {
    let nonsend = NonSendStruct { _ptr: &mut () };
    async {}.await;
}

fn main() {
    require_send(my_future()); // error: `*mut ()` cannot be sent between threads safely
}

The error is "*mut () cannot be sent between threads safely", which is to say my_future() is !Send. I'm surprised by that, because the nonsend variable is never used after the .await point, and it's not Drop. Some other notes:

  • Adding a drop(nonsend) call after the let nonsend = ... line doesn't help.
  • This does compile if swap the two lines in my_future. That is, if nonsend is created after the .await point, the future is still Send.

Are there any future plans to have the rustc look more closely at which locals do or do not need to be stored across an .await?

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-feature-requestCategory: A feature request, i.e: not implemented / a PR.T-langRelevant to the language team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions