async function being !Send due to match retaining type of a consumed value. #114624
Description
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