rust-lang / rust-lang/rust

rustc doesn't infer that the future of a recursive `async fn` is `Send`.

Open
#134,101 3 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-async-await A-trait-system C-bug fixed-by-next-solver T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

(Note: this bug is not about recursion in asynchronous functions being limited because futures of async functions cannot contain a copy of themselves.)

I would expect this code to compile successfully:

use std::future::Future;

pub async fn recur(depth: usize) {
    if depth == 0 {
        return;
    }
    spawn(recur(depth - 1));
}

pub fn spawn(_future: impl Future + Send + 'static) { }

Instead, rustc complains:

error[E0283]: type annotations needed: cannot satisfy `impl Future<Output = ()>: Send`
  --> recursive/src/lib.rs:7:5
   |
7  |     spawn(recur(depth - 1));
   |     ^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: cannot satisfy `impl Future<Output = ()>: Send`
note: required by a bound in `spawn`
  --> recursive/src/lib.rs:10:37
   |
10 | pub fn spawn(_future: impl Future + Send + 'static) { }
   |                                     ^^^^ required by this bound in `spawn`

For more information about this error, try `rustc --explain E0283`.
error: could not compile `recursive` (lib) due to 1 previous error

The program compiles fine if I pass RUSTFLAGS=-Znext-solver to nightly rustc. I wasn't able to find any existing issues that seemed similar.

Meta

rustc +nightly --version --verbose:

rustc 1.85.0-nightly (9c707a8b7 2024-12-07)
binary: rustc
commit-hash: 9c707a8b769523bb6768bf58e74fa2c39cc24844
commit-date: 2024-12-07
host: x86_64-unknown-linux-gnu
release: 1.85.0-nightly
LLVM version: 19.1.5

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the minimal example from the issue on the stated nightly compiler, then compare default rustc behavior with RUSTFLAGS=-Znext-solver. Investigate the trait-solving path for the recursive async future's Send requirement. Done means the example compiles without the experimental solver and the behavior is covered by a regression test.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.