Description
I've returned to one of my projects after a few months of pause. Before I was using rust nigthly ~1.7x (around November 2023). It also worked through whole 2022 and 2021 IIRC. I've moved to new computer and installed rust nightly 1.80 (latest).
After upgrading I noticed that my whole codebase is full of errors around async move |foo|
capturing something from environment.
error: async closure does not implement `FnMut` because it captures state from its environment
. However if I change async |_| { ... }
to |_| async { ... }
it builds and works like previosly.
Minimal example below.
#![feature(async_closure)]
use futures::StreamExt;
#[tokio::main(flavor = "current_thread")]
async fn main() {
let test = Test {};
test.async_with_async_closure().await;
}
struct Test {}
impl Test {
// This is how it used to work, but now it does not compile
async fn async_with_async_closure(&self) {
futures::stream::repeat(())
.take(5)
.for_each(async |_item| { // the difference is here
self.sync_method();
}).await;
}
// This is the workaround
async fn async_with_async_block(&self) {
futures::stream::repeat(())
.take(5)
.for_each(|_item| async { // the difference is here
self.sync_method();
}).await;
}
fn sync_method(&self) {
println!("i am being called");
}
}
The error for first method is:
Compiling playground v0.0.1 (/playground)
error: async closure does not implement `FnMut` because it captures state from its environment
--> src/main.rs:17:23
|
17 | .for_each(async |_item| {
| -------- ^^^^^^^^^^^^^
| |
| required by a bound introduced by this call
|
note: required by a bound in `futures::StreamExt::for_each`
--> /playground/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.30/src/stream/stream/mod.rs:1093:12
|
1091 | fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
| -------- required by a bound in this associated function
1092 | where
1093 | F: FnMut(Self::Item) -> Fut,
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StreamExt::for_each`
error: async closure does not implement `FnMut` because it captures state from its environment
--> src/main.rs:17:23
|
17 | .for_each(async |_item| {
| ^^^^^^^^^^^^^
|
= note: required for `ForEach<Take<Repeat<()>>, {async closure body@src/main.rs:17:37: 19:14}, {async [email protected]:17:23}>` to implement `futures::Future`
= note: required for `ForEach<Take<Repeat<()>>, {async closure body@src/main.rs:17:37: 19:14}, {async [email protected]:17:23}>` to implement `std::future::IntoFuture`
= note: the full name for the type has been written to '/playground/target/debug/deps/playground-71f1e6caf9dc6471.long-type-11561845803583376377.txt'
= note: consider using `--verbose` to print the full type name to the console
= note: the full name for the type has been written to '/playground/target/debug/deps/playground-71f1e6caf9dc6471.long-type-11561845803583376377.txt'
= note: consider using `--verbose` to print the full type name to the console
error: could not compile `playground` (bin "playground") due to 2 previous errors
i booted my very old PC to check, this is definately not the last version this worked fine:
rustc 1.70.0-nightly (ab654863c 2023-03-15)
I definately does not work with:
rustc 1.80.0-nightly (8387315ab 2024-05-14)