Skip to content

Tracking issue for #![feature(async_closure)] (RFC 2394 / RFC 3668) #62290

Open

Description

@Centril

This is a tracking issue for #![feature(async_closure)] (rust-lang/rfcs#2394).
The feature gate provides the async |...| expr closure syntax.

As with all tracking issues for the language, please file anything unrelated to implementation history, that is: bugs and design questions, as separate issues as opposed to leaving comments here. The status of the feature should also be covered by the feature gate label. Please do not ask about developments here.

Steps:

Open questions (RFC 2394)

Open questions (RFC 3668)

Related

Activity

  1. added
    B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.
    A-closuresArea: Closures (`|…| { … }`)
    T-langRelevant to the language team
    B-unstableBlocker: Implemented in the nightly compiler and unstable.
    B-RFC-implementedBlocker: Approved by a merged RFC and implemented but not stabilized.
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    AsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.
    on Jul 2, 2019
  2. added 2 commits that reference this issue on Jul 4, 2019
  3. added 2 commits that reference this issue on Jul 4, 2019
  4. added 2 commits that reference this issue on Jul 5, 2019
  5. 44 remaining items

  6. added a commit that references this issue on Jul 4, 2024
  7. added a commit that references this issue on Jul 11, 2024
  8. added a commit that references this issue on Jul 11, 2024
  9. c-git commented on Jul 16, 2024

    @c-git
    Contributor

    Not sure if this is a suitable place to point to the workaround I use. But this is where the compiler points me every time I bump into this. This post pointed me in the right direction. My main takeaway is put the async on the right of || not the left and then progress becomes possible again (at least for my use cases).

    Copy of code so others don't need to follow the link

    async fn with_async_callback<Fut: Future<Output = i32>, F: FnOnce() -> Fut>(f: F) -> i32 {
        f().await
    }
    
    with_async_closure(|| async { 123 })

    Edit

    After I'd added my comment I went to re-read the posts and saw the one quoted below that already provided a solution but I didn't find it when I searched because I used the word workaround and possibly others will as well so I decided to leave it.

    If I understand correctly, just replace async || {...} with || async {...}. It acts no differently to async fn.

    @Fancyflame No, you can see this example. It seems the compiler cannot handle the lifetimes correctly without async_closure.

  10. changed the title [-]Tracking issue for `#![feature(async_closure)]` (RFC 2394)[/-] [+]Tracking issue for `#![feature(async_closure)]` (RFC 2394) (RFC 3668)[/+] on Aug 3, 2024
  11. changed the title [-]Tracking issue for `#![feature(async_closure)]` (RFC 2394) (RFC 3668)[/-] [+]Tracking issue for `#![feature(async_closure)]` (RFC 2394 / RFC 3668)[/+] on Aug 3, 2024
  12. compiler-errors commented on Dec 13, 2024

    @compiler-errors
    Contributor

    this is done

  13. tisonkun commented on Apr 19, 2025

    @tisonkun
    Contributor

    [Just a data point]

    Today I meet an issue that when the return type CallRefFuture cannot be used in stable channel, some code cannot be written:

    fn schedule_with_arbitrary_delay<F, S, D>(
        mut self,
        mut is_shutdown: F,
        spawn: &S,
        make_delay: D,
        initial_delay: Option<Duration>,
    ) where
        Self: Sized,
        F: AsyncFnMut() -> () + Send + 'static,
        S: Spawn,
        D: MakeDelay + Send + 'static,
    {
        spawn.spawn(async move { .. })
    }

    returns:

    error[E0277]: `<F as AsyncFnMut<()>>::CallRefFuture<'_>` cannot be sent between threads safely
      --> fastimer/src/schedule/arbitrary.rs:55:15
       |
    55 |         spawn.spawn(async move {
       |               ^^^^^ ---------- within this `{async block@fastimer/src/schedule/arbitrary.rs:55:21: 55:31}`
       |               |
       |               `<F as AsyncFnMut<()>>::CallRefFuture<'_>` cannot be sent between threads safely
       |
       = help: within `{async block@fastimer/src/schedule/arbitrary.rs:55:21: 55:31}`, the trait `Send` is not implemented for `<F as AsyncFnMut<()>>::CallRefFuture<'_>`
    note: required because it's used within this `async` fn body
      --> fastimer/src/schedule/mod.rs:40:1
       |
    40 | / {
    41 | |     match select(is_shutdown, f).await {
    42 | |         Either::Left(()) => ControlFlow::Break(()),
    43 | |         Either::Right(o) => ControlFlow::Continue(o),
    44 | |     }
    45 | | }
       | |_^
    note: required because it's used within this `async` block
      --> fastimer/src/schedule/arbitrary.rs:55:21
       |
    55 |         spawn.spawn(async move {
       |                     ^^^^^^^^^^
    note: required by a bound in `Spawn::spawn`
      --> fastimer/src/lib.rs:92:39
       |
    92 |     fn spawn<F: Future<Output = ()> + Send + 'static>(&self, future: F);
       |                                       ^^^^ required by this bound in `Spawn::spawn`
       = note: the full name for the type has been written to '/Users/tison/Brittani/fastimer/target/debug/deps/fastimer-fa19318f90c9a3a8.long-type-3363693415664072930.txt'
       = note: consider using `--verbose` to print the full type name to the console
    help: consider further restricting the associated type
       |
    53 |         D: MakeDelay + Send + 'static, <F as AsyncFnMut<()>>::CallRefFuture<'_>: Send
       |                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    fn schedule_with_arbitrary_delay<F, S, D>(
        mut self,
        mut is_shutdown: F,
        spawn: &S,
        make_delay: D,
        initial_delay: Option<Duration>,
    ) where
        Self: Sized,
        F: AsyncFnMut() -> () + Send + 'static,
        for<'a> F::CallRefFuture<'a>: Send,
        S: Spawn,
        D: MakeDelay + Send + 'static,
    {
        spawn.spawn(async move { .. })
    }

    returns:

    error[E0658]: use of unstable library feature `async_fn_traits`
      --> fastimer/src/schedule/arbitrary.rs:52:17
       |
    52 |         for<'a> F::CallRefFuture<'a>: Send,
       |                 ^^^^^^^^^^^^^^^^^^^^
    
  14. dtolnay commented on Aug 15, 2025

    @dtolnay
    Member

    Reopening because async Trait trait bounds still refers to this tracking issue as of the latest nightly.

    A new tracking issue should be created for feature(async_trait_bounds).

    pub fn f<T: async Fn()>() {}
    error[E0658]: `async` trait bounds are unstable
     --> src/lib.rs:1:13
      |
    1 | pub fn f<T: async Fn()>() {}
      |             ^^^^^
      |
      = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
      = help: add `#![feature(async_trait_bounds)]` to the crate attributes to enable
      = note: this compiler was built on 2025-08-14; consider upgrading it if it is out of date
      = help: use the desugared name of the async trait, such as `AsyncFn`
  15. added 2 commits that reference this issue on Mar 19, 2026
  16. added a commit that references this issue on Mar 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-async-closures`async || {}`A-closuresArea: Closures (`|…| { … }`)AsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.B-RFC-implementedBlocker: Approved by a merged RFC and implemented but not stabilized.B-unstableBlocker: Implemented in the nightly compiler and unstable.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCS-tracking-needs-summaryStatus: It's hard to tell what's been done and what hasn't! Someone should do some investigation.T-langRelevant to the language teamWG-asyncWorking group: Async & awaitrequires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions