rust-lang/rust

Tracking Issue for `#![feature(async_fn_traits)]`

Opened this issue · 5 comments

Feature gate: #![feature(async_fn_traits)]

RFC: I couldn't find one.

Public API

This is a tracking issue for the methods and associated types of the AsyncFn family of traits:

The traits themselves are stable, but it is not possible to implement them or (critically) write bounds on the returned future on stable.

Steps / History

(Remember to update the S-tracking-* label when checking boxes.)

  • Implementation: #119305
  • Final comment period (FCP)1
  • Stabilization PR

Unresolved Questions

  • Unknown?

Related:

Footnotes

  1. https://std-dev-guide.rust-lang.org/feature-lifecycle/stabilization.html

Here's a function you can express with AsyncFnOnce and the FnOnce equivalent, which requires a second generic parameter:

async fn doggy<F>(succeeded: F)
where
    F: AsyncFnOnce() + Send + Sync + 'static,
    F::CallOnceFuture: Send + Sync + 'static,
{
    todo!()
}

// I don't think this is exactly equivalent, but close...?
async fn doggy_stable<F, F2>(succeeded: F)
where
    F: FnOnce() -> F2 + Send + Sync + 'static,
    F2: Future<Output = ()> + Send + Sync + 'static,
{
    todo!()
}

Thanks for opening a tracking issue for this! I have linked the obvious PR but any other related PRs are not on my radar. cc @traviscross I believe you may know?

I don't think this is exactly equivalent, but close...?

For FnOnce it's fine, it's close enough and not harmful to write the bound in a two-part T: FnOnce() -> F, F: .... For Fn/FnMut, you'll lose the ability to return a future that borrows from its captures, which is basically the point of async closures in the first place.

Not necessarily a comment for this tracking issue itself, but I believe the "idea" is to allow users to write RTN-style T(..): ... bounds to bound the futures returned by async closures, see https://rust-lang.github.io/rfcs/3668-async-closures.html#interaction-with-return-type-notation-naming-the-future-returned-by-calling.