Skip to content

Cannot combine async fn-in-traits with AsyncFn{,Mut} closures #145127

@alexcrichton

Description

@alexcrichton

This program:

#![allow(dead_code)]

trait Foo {
    fn foo(&self) -> impl Future<Output = ()> + Send + '_;
}

struct MyType;

impl Foo for MyType {
    async fn foo(&self) {
        self.run_async_fn(async || self.noop()).await;
    }
}

impl MyType {
    fn noop(&self) {}

    async fn run_async_fn<T>(&self, mut f: impl AsyncFnMut() -> T) -> T {
        f().await
    }
}

fails to compile with:

error[E0477]: the type `{async closure@src/lib.rs:11:27: 11:35}` does not fulfill the required lifetime
  --> src/lib.rs:10:5
   |
10 |     async fn foo(&self) {
   |     ^^^^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0477`.

A similar version of this program with a dyn-compatible trait also does not compile:

#![allow(dead_code)]

trait Foo {
    fn foo<'a>(&'a self) -> Box<dyn Future<Output = ()> + Send + 'a>;
}

struct MyType;

impl Foo for MyType {
    fn foo<'a>(&'a self) -> Box<dyn Future<Output = ()> + Send + 'a> {
        Box::new(async move {
            self.run_async_fn(async || self.noop()).await;
        })
    }
}

impl MyType {
    fn noop(&self) {}

    async fn run_async_fn<T>(&self, mut f: impl AsyncFnMut() -> T) -> T {
        f().await
    }
}

and this fails with a different error:

error: implementation of `Send` is not general enough
  --> src/lib.rs:11:9
   |
11 | /         Box::new(async move {
12 | |             self.run_async_fn(async || self.noop()).await;
13 | |         })
   | |__________^ implementation of `Send` is not general enough
   |
   = note: `Send` would have to be implemented for the type `&'0 MyType`, for any lifetime `'0`...
   = note: ...but `Send` is actually implemented for the type `&'1 MyType`, for some specific lifetime `'1`

My instinct is that both of these programs should compile. Replacing AsyncFnMut with AsyncFn yields similar errors, but replacing the bound with AsyncFnOnce makes these errors go away. This feels like a bug in the compiler so I wanted to be sure to document this, but if I'm also misunderstanding things it might be good to also improve the error message here as a diagnostics issue.

Meta

rustc --version --verbose:

rustc 1.91.0-nightly (7d82b83ed 2025-08-06)
binary: rustc
commit-hash: 7d82b83ed57d188ab3f2441a765a6419685a88a3
commit-date: 2025-08-06
host: x86_64-unknown-linux-gnu
release: 1.91.0-nightly
LLVM version: 21.1.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-async-closures`async || {}`A-auto-traitsArea: auto traits (e.g., `auto trait Send {}`)A-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)C-bugCategory: This is a bug.fixed-by-higher-ranked-assumptionsFixed by `-Zhigher-ranked-assumptions`

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions