Open
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