rust-lang / rust-lang/rust

Type inference issue with `|| async {}` closure in AsyncFn

Open
#136,696 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-async-closures C-bug C-discussion T-compiler T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I have reviewed previous issues about type inference in async closures, which are about the type inference not working for the some variable in async |some| {}. However, the issue I encountered is different. Please see my code below.

I tried this code:

struct Foo;
impl Foo {
    fn method(&self) {
    }
}

async fn some_async_fn<F>(_: F)
where
    F: AsyncFn(Foo),
{
}

async fn test() {
    some_async_fn(|boo| async move { boo.method() }).await;
}

I expected the type inference to work correctly

Because the following code can work:

async fn test() {
    // is ok
    some_async_fn(async |boo| boo.method()).await;

    // or this is ok
    some_async_fn(|boo: Foo| async move { boo.method() }).await;
}

Instead, this happened:

error[E0282]: type annotations needed
  --> test_1/src/lib.rs:16:20
   |
16 |     some_async_fn(|boo| async move { boo.method() }).await;
   |                    ^^^          --- type must be known at this point
   |
help: consider giving this closure parameter an explicit type
   |
16 |     some_async_fn(|boo: /* Type */| async move { boo.method() }).await;
   |                       ++++++++++++

I need to edit this issue because I think I should highlight its importance. async || {} is compatible with the previous Fn() -> Fut, upgrading from || async {} to async || {} is a good choice, but what about the other way around? If a function is upgraded from Fn() -> Fut to AsyncFn, if it cannot infer the types of the input parameters in || async {}, much of the existing code that calls this function will no longer work as expected. This could become a barrier for developers upgrading to AsyncFn.

Meta

rustc --version --verbose:

rustc 1.86.0-nightly (942db6782 2025-02-06)
binary: rustc
commit-hash: 942db6782f4a28c55b0b75b38fd4394d0483390f
commit-date: 2025-02-06
host: x86_64-unknown-linux-gnu
release: 1.86.0-nightly
LLVM version: 19.1.7

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 compiling the reproducer in test_1/src/lib.rs with the reported rustc nightly version, focusing on some_async_fn, test, and the || async move closure. Compare it with the working async closure and explicitly typed versions. Done means the unannotated closure parameter infers correctly in the reported case without breaking the existing working examples.

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
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.