-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
A-edition-2021Area: The 2021 editionArea: The 2021 editionA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.C-bugCategory: This is a bug.Category: This is a bug.D-editionDiagnostics: An error or lint that should account for edition differences.Diagnostics: An error or lint that should account for edition differences.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
It is possible to write code which looks like it should not compile and does not function as expected when trying to mutate Copy fields on a struct in an async move block.
I tried this code:
use futures::StreamExt;
#[derive(Debug)]
struct Foo { a: i32, b: i32 }
async fn work() -> Foo {
let mut foo = Foo { a: 0, b: 0};
let mut futs = futures::stream::FuturesUnordered::new();
for i in 0..100 {
foo.a += 1;
futs.push(tokio::spawn(async move {
foo.b += 1;
}));
}
for i in 0..100 {
futs.next().await;
}
foo
}
#[tokio::main]
async fn main() {
println!("{:?}", work().await);
}
I expected to see this happen: Foo should have value 100 for both a and b
Instead, this happened: Foo.b is zero.
This behavior is so surprising that it should at least be a warning from rustc. The outcome is clearly not the intent of the code, but it looks like it should work as expected.
Meta
rustc --version --verbose
:
rustc 1.76.0 (07dca489a 2024-02-04)
This is possibly a dupe of #108808
Metadata
Metadata
Assignees
Labels
A-edition-2021Area: The 2021 editionArea: The 2021 editionA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.C-bugCategory: This is a bug.Category: This is a bug.D-editionDiagnostics: An error or lint that should account for edition differences.Diagnostics: An error or lint that should account for edition differences.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.