Skip to content

Non-Send values that are assigned to a variable but not used across an await point incorrectly mark the entire Future as non-Send #116680

Open
@wallefan

Description

@wallefan

I tried this code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f9f172724348c228b481bcd813cc92e5

use std::sync::Mutex;

fn main() {
    assert_send(foo(&Mutex::new(SomeStruct)));
}

struct SomeStruct;

impl SomeStruct {
    fn some_method(&self) -> u32 {
        return 1;
    }
}

async fn foo(mutex: &Mutex<SomeStruct>) {
    let guard = mutex.lock().unwrap();
    guard.some_method();
    std::mem::drop(guard);
    bar().await;
}

async fn bar() {
}

fn assert_send<T: Send>(_t:T) {}

It fails to compile since the future is not Send.

Since the guard is explicitly dropped before the await point, I would expect this future to be Send. Indeed, if I remove the variable guard and condense those three lines onto a single line, like so:

async fn foo(mutex: &Mutex<SomeStruct>) {
    mutex.lock().unwrap().some_method();
    bar().await;
}

...it compiles and runs fine. I created a second Playground to confirm this that does some additional testing to make sure the future runs correctly.

I suspect, therefore, that this is a bug. I've confirmed it's present in the most recent stable, nightly, and beta releases of the compiler available from rustup.

Of note is that the bug occurs even if I remove the call to some_method(). Merely assigning the guard to a variable is sufficient to make the future non-Send.

Meta

rustup run stable rustc --version --verbose:

rustc 1.73.0 (cc66ad468 2023-10-03)
binary: rustc
commit-hash: cc66ad468955717ab92600c770da8c1601a4ff33
commit-date: 2023-10-03
host: x86_64-unknown-linux-gnu
release: 1.73.0
LLVM version: 17.0.2

rustup run nightly rustc --version --vernose:

rustc 1.75.0-nightly (475c71da0 2023-10-11)
binary: rustc
commit-hash: 475c71da0710fd1d40c046f9cee04b733b5b2b51
commit-date: 2023-10-11
host: x86_64-unknown-linux-gnu
release: 1.75.0-nightly
LLVM version: 17.0.2

rustup run beta rustc --version --verbose:

rustc 1.74.0-beta.1 (b5c050feb 2023-10-03)
binary: rustc
commit-hash: b5c050febf10c9bcc0459d41fe2a1e190ad30b8d
commit-date: 2023-10-03
host: x86_64-unknown-linux-gnu
release: 1.74.0-beta.1
LLVM version: 17.0.2

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-compilerRelevant to the compiler team, which will review and decide on the PR/issue.WG-asyncWorking group: Async & await

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions