---
# System prepended metadata

title: The path to async functions in traits

---

# The path to async functions in traits

This hackmd lays out a roadmap to achieve support for async functions in traits. This includes some number of related language changes and optional components that will require RFCs or other work. It is also intended to stabilize parts of other features along the way.

## Goals

The goal is to enable the following features:

* named impl Trait (`type Foo = impl Trait`) at module and impl level
    * it is only important for `Foo` to be usable in "defining positions" (function return) and as value of an associated type
* `type Foo<..>` in trait defintions, i.e., GATs, with both types and lifetimes
* `fn foo() -> impl Trait` in trait definitions
    * desugars to a `fn foo() -> Foo` and `type Foo = impl Trait` (literally) GAT
* `async fn foo()` in trait definitions
    * desugars to a `-> impl Trait`, which in turn desugars to `type Foo`

## Milestones

Largely unordered:

* `min_type_alias_impl_trait` stabilized
* GAT blockers resolved
* RFC for GATs with types open
* RFC for async fn and impl trait open
* RFC for GATs with types merged
* RFC for async fn and impl trait merged
* All features implemented on nightly
* All feature stabilization reports are written
* All features stable on nightly
* All features stable


## Planning next steps and blockers

See the [project board](https://github.com/rust-lang/wg-traits/projects/4?add_cards_query=is%3Aopen)






## Actionable next steps

* ~~Define impl Trait slice 0 feature gate with appropriate tests -- oli~~ done in [#82898](https://github.com/rust-lang/rust/pull/82898)
    * [Impl trait triage notes by jackh726](https://hackmd.io/W4khQJyIQdy_ezT9xUdgQg)
* Write tests for GATs -- Areredify, nikomatsakis to review
* Resolve [GAT blockers](https://hackmd.io/uxoObhSxSRijNmfmGkId0g) -- maybe b-naber? jackh762 to reach out
    * [#81801] - Bad diagnostics for GATs in trait paths -- [#82272] is open
    * [#81862] - GAT: elided lifetimes in paths errors with `error[E0107]: missing generics for associated type` -- [#82272] is open
    * [#81961] - GAT: incorrect suggestion on missing lifetime -- [#82272] is open
    * [#81823] - Trait objects do not work with generic associated types #81823 -- matthewjasper
    * [#80626] - Enum variant with GAT field fails to derive Sized
* Extend #61997 to all `impl Trait` and not just `async fn`,  -- nikomatsakis
    * this effectively "stabilizes" it
* Stabilize the "member constraints" feature gate ([#61997]), extending this approach to all `impl Trait`, and not just `async fn` -- Niko
* Write RFC for `impl Trait` --nikomatsakis
* Stabilization report for `min_type_alias_impl_trait`

[#81801]: https://github.com/rust-lang/rust/issues/81801
[#81861]: https://github.com/rust-lang/rust/issues/81861
[#81862]: https://github.com/rust-lang/rust/issues/81862
[#61997]: https://github.com/rust-lang/rust/issues/61997
[#82272]: https://github.com/rust-lang/rust/issues/82272

## Blocked items

* Write stabilization report for impl Trait slice 0
* Write stabilization report for GATs
* Write RFC for `async fn` in trait definitions -- nikomatsakis
* [#76407] - Associated type constraint fails, even if it implements requested trait
    - Probably failed associated type normalization, might not be GATs
    - https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=87f0cc94ab4a9a620b684b4c7bf6431a
    - Blocked on lazy normalization

## Needs expansion

* Lazy normalization-- can we expand this, what are the blockers?

## Open questions

* Given the following table, do we need a "where clause" based syntax that the impl proves? What would that be?

| Syntax | who proves it | who can assume it |
| --- | --- | --- |
| `type Foo: Bar = X` | the impl | generic code using `T::Foo` |
| `type Foo<A: Bar> = X` | generic code using `T::Foo<U>`, which must prove that `U: Bar` | the impl, when proving the type `X` is WF |
| `type Foo<A> = X where A: Bar` | generic code using `T::Foo<U>`, which must prove that `U: Bar` | the impl, when proving the type `X` is WF |

## High-level roadmap

### Core compilation improvements required

* Stabilize named [impl Trait slice 0]
    * Ability to write `type Foo = impl Trait`, with various limitations on where `Foo` can be used.
    * Work is largely writing tests, stabilization report, and some limited hacking on the compiler.
* Stabilize GATs with lifetimes (at least)
    * Requires writing more tests.
    * May require .
* Write RFC to extend GATs to cover types

### XXX


### Sugar-y improvements

* Write RFC to permit `-> impl Trait` within traits
    * Resolve desuaring question -- this becomes an associated type, can it be named?
* Write RFC to permit `async fn` syntax within traits
    * Desugars conceptually to `impl Trait`, thus raising some of the same questions (can the resulting associated type be named?)
* Write RFC to permit 

### Vaguely related sugar

* Permit `type Foo = XXX` to be inferred for an impl if `Self::Foo` is the return type of a function, and the function is defined? 

## Links

* [Previous meeting notes](https://hackmd.io/j8KTAWU2TzC-STlsB8ZSVQ)
* [impl Trait slice 0]
* [impl Trait Implementation Plan](https://hackmd.io/4dafnCiTSiOZJy_3u4ju0A)

[impl Trait slice 0]: https://hackmd.io/nzqSIjdHTFW3-IT3ZWRjow