Skip to content

async function being !Send due to match retaining type of a consumed value. #114624

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
Stormshield-robinc opened this issue Aug 8, 2023 · 4 comments
Labels
A-async-await Area: Async & Await A-auto-traits Area: auto traits (e.g., `auto trait Send {}`) C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Stormshield-robinc
Copy link

Stormshield-robinc commented Aug 8, 2023

Hi,

I tried this code:

// is Send
async fn good() {
    let life = NonSend::new().life();

    match life {
        _ => f().await,
    }
}

// is not Send
async fn bad() {
    match NonSend::new().life() {
        _ => f().await,
    }
}

playground will the full code : https://play.rust-lang.org/?version=nightly&mode=release&edition=2021&gist=e0c1095262f83a6f62cea40d6059fe3d

I expected to see this happen:

In this case I would expect both good() and bad() async function to be Send and the whole code to compile.

This code basically create a !Send value that is consumed by some function that return something Send.
After this point, a .await is called. Since the non sendable value have been consumed, I would expect the async function to be Send

Instead, this happened:

The function good() is Send but not the function bad().
It seem that the match somehow retain the non-sendable type even though it should have been consumed.
What is even more surprising is to see the difference of behavior between the let and the match, since I would have expected those to be identical.

I dug a bit through the existing issues and found #93883 and #94067 that kinda look like what I have here, but I cannot for sure know if this it is exactly the same issue.

Meta

rustc --version --verbose:

rustc 1.71.0 (8ede3aae2 2023-07-12)
binary: rustc
commit-hash: 8ede3aae28fe6e4d52b38157d7bfe0d3bceef225
commit-date: 2023-07-12
host: x86_64-unknown-linux-gnu
release: 1.71.0
LLVM version: 16.0.5

Note : also reproduced with the available versions in the playground

@Stormshield-robinc Stormshield-robinc added the C-bug Category: This is a bug. label Aug 8, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Aug 8, 2023
@fmease
Copy link
Member

fmease commented Sep 30, 2023

Fixed on nightly, not sure which PR fixed this though.

@fmease fmease added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-async-await Area: Async & Await A-auto-traits Area: auto traits (e.g., `auto trait Send {}`) and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Sep 30, 2023
@stormshield-kg
Copy link

stormshield-kg commented Oct 2, 2023

Fixed by 13e6f24, according to cargo-bisect-rustc.

@fmease
Copy link
Member

fmease commented Oct 2, 2023

@cjgillot (#107421), do you think it's worth adding the code from the issue description as a regression test or can I close this issue directly?

@cjgillot
Copy link
Contributor

There are already tests on this kind of code.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-async-await Area: Async & Await A-auto-traits Area: auto traits (e.g., `auto trait Send {}`) C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants