Open
Description
Yesterday in the rust community discord, we came across the following (minimized) example.
I don't understand why these futures aren't Send
. Obviously, bar
can only be Send
if foo
is as well. However, while bar
requires foo
to be Send
in order to successfully type-check, it's Send
ness shouldn't depend on it.
I tried this code:
fn spawn<T: Send>(_: T) { }
async fn foo() {
spawn(bar())
}
async fn bar() {
foo().await;
}
I expected to see this happen: I believe the code should compile.
Instead, this happened:
error: future cannot be sent between threads safely
--> <source>:4:5
|
4 | spawn(bar())
| ^^^^^^^^^^^^ future returned by `bar` is not `Send`
|
= note: cannot satisfy `impl Future<Output = ()>: Send`
note: future is not `Send` as it awaits another future which is not `Send`
--> <source>:8:5
|
8 | foo().await;
| ^^^^^ await occurs here on type `impl Future<Output = ()>`, which is not `Send`
note: required by a bound in `spawn`
--> <source>:1:13
|
1 | fn spawn<T: Send>(_: T) { }
| ^^^^ required by this bound in `spawn`
Meta
rustc --version --verbose
:
rustc 1.85.0-nightly (4363f9b6f 2025-01-02)
binary: rustc
commit-hash: 4363f9b6f6d3656d94adbcabba6348a485ef9a56
commit-date: 2025-01-02
host: x86_64-unknown-linux-gnu
release: 1.85.0-nightly
LLVM version: 19.1.6
This also happens on stable rustc 1.83.0
.
Before rustc 1.75
the type checker encounters a cycle instead.
With -Znext-solver
there's an ICE.