---
# System prepended metadata

title: WG-async triage meeting 2024-01-22
tags: [triage-meeting, minutes, WG-async]

---

---
title: WG-async triage meeting 2024-01-22
tags: ["WG-async", "triage-meeting", "minutes"]
date: 2024-01-22
discussion: https://rust-lang.zulipchat.com/#narrow/stream/187312-wg-async/topic/.60AsyncIterator.60.20rename.20meeting.202024-01-22.3F
url: https://hackmd.io/wy0xQU8eRyuwhki5zkpoCg
---

# WG-async meeting agenda

- Meeting date: 2024-01-22

## Attendance

- People: TC, eholk, yosh, Vincenzo

## Meeting roles

- Minutes: TC

## Scheduled meetings

- 2024-01-25: "Roadmap planning: 2024-01-25" [#331](https://github.com/rust-lang/wg-async/issues/331)
- 2024-02-01: "Discuss `async Drop`" [#330](https://github.com/rust-lang/wg-async/issues/330)

Update these [here](https://github.com/orgs/rust-lang/projects/40/views/1).

## Proposed meetings

None.

Update these [here](https://github.com/orgs/rust-lang/projects/40/views/1).

## Announcements or custom items

(Meeting attendees, feel free to add items here!)

## Nominated RFCs, PRs, and issues

### "Rename `AsyncIterator` back to `Stream`, introduce an AFIT-based `AsyncIterator` trait" rust#119550

**Link:** https://github.com/rust-lang/rust/pull/119550

TC: Part of the challenge here is that we should consider this holistically.  There are a number of degrees of freedom here, including e.g.:

- Pinning.
- Whether to use AFIT.
- Whether to separately signal empty state (c.f. `FuturesUnordered`).
- `poll_pending` or a similar mechanism for backpressure and liveness.
- Lending?
- Try?

This PR conflates the first two.  But we need to consider the others also.

Yosh: There still may be value here in terms of demonstrating feasibility.

TC: There's also the bigger effects picture.  Yosh, what you have in mind is a larger system implemented in terms of const generics.  It may be better to look at the bigger system rather than litigating this small piece of it.

Yosh: I'm leaning toward arguing both.  In my view, they both stand independently on their merits.

eholk: There is an angle with I/O traits also.  There may be some fundamental tension between `poll`-based traits and AFIT-based ones that may come up over and over again.  We should perhaps look at other traits.

Yosh: Agree with should look at it holistically.  What we do for `AsyncIterator` will imply what we should do for other things.

TC: There's a connection here with the `AsyncFn` family of traits that we haven't yet discussed.  There's a basic question of whether we layer or flatten traits when composing the effects.  To solve borrow checking problems, for the `AsyncFn` traits we're flattening them.  For asynchronous generator closures, we're doing similarly for the same reason.  This is the same compositional question as what we have for `AsyncIterator`.

eholk: I'm thinking of a chemistry analogy here.  You can't just layer sodium and chlorine.  NaCl is a separate thing with separate properties.

TC: That's a good analogy.  One way that happens in this context is that when composing traits for these effects, we have to take the intersection of what the bounds allow.  That intersection means that we end up with a new thing.

TC: Yosh has proposed that we ensure that all the effects have the same bounds so that these can be layered without having to deal with this.  That, e.g., pinning should be treated orthogonally and without composing it into the traits.  This tradeoff should be stated explicitly when discussing this approach.

Yosh: Partly this PR is to push back on the idea that we are ready to stabilize `AsyncIterator` now.  We still have open questions and this PR illustrates them.

TC: That's actually why this PR concerns me.  It has the effect of externalizing to other teams a request for a directional decision even though we're not ready for that.

Yosh: I want to be sure that implementation concerns are flushed out, if there are any, with the AFIT-based approach.

eholk: The two state machines version is the more complex thing to implement.  There's probably not a reason it couldn't be done.  But it's always possible for things to be way harder than they look.  Implementation does take work.  The `poll_next` version fits really neatly into what we have in the current machinery.  It's going to take a lot more work to do the AFIT one.  So there has to be enough benefit to be worth paying that cost.

eholk: So I'm torn.  I don't really want to block for that reason.  But it is a real cost.

TC: We have to be careful too about imposing costs on others.  If the people doing the work think the `poll_next` version is better anyway and that the AFIT version is probably infeasible when all considerations are taken into account, then obviously those people are going to object to a request or requirement that they should also implement things in terms of `async fn next`.

Yosh: What if we did what Josh proposed and just delete the `poll_next` one?  How does that affect the implementation and the T-lang questions?

eholk: I don't think that changes much.  Because we still then have to write that separate code.

TC: It's difficult for me to imagine T-lang accepting this without feeling like they were making a directional decision, and that could lead to much discussion and to people starting to form binding views on this.  We should deliver the full context that we want people to consider before asking these questions.

eholk: `async gen` is in particular much more complicated to implement with AFIT.  So the question is, how important are async generators?

TC: We had a recent discussion about this.  One of the reasons we wanted to do async closures was to enable experimentation with e.g. the combinators.  We realized in our discussion, though, that what we really want for that are async generator closures.  So these seem important.

eholk: Once we have async generators, writing iterators by hand will hopefully be uncommon.  That could mitigate concerns over the `poll_next` ergonomics.

Yosh: The ergonomics at every layer matter.

TC: When I'm writing these implementations by hand, I never want to be using combinators or `.await` anyway.  E.g., I need to handle the `Pending` state explicitly.  The problems I run into when writing these impls are missing affordances at other layers, such as the lack of stable TAIT (working to solve that).

Yosh: Stepping back a level, what do we want to decide?

TC: The main important thing is that, whatever the answer, we come to consensus ourselves before externalizing this.

Yosh: +1.  I don't feel we currently have that consensus.

eholk/TC: +1.

TC: The key thing here is to not seem to be putting work on other people.

eholk: Yosh, do you think adding this separate trait has value even if it doesn't work with `async gen`?

Yosh: Yes, it probably would.

TC: I'd suggest also not renaming in this PR.  That will make it seem less like a directional decision.

Yosh: OK, I'll split this into two separate PRs.

TC: So one that adds `AsyncFnNextIterator` and another that renames the existing one to `AsyncPollNextIterator`.

*Consensus*: As a meeting consensus, we're all +0 or greater on adding a new `AsyncFnNextIterator` trait such that it does not work with `async gen`, subject to that we need to discuss this with at least tmandry and CE.  And we agree that we want to develop consensus on this within WG-async before externalizing it to other teams.

(The meeting ended here.)

### "Tracking Issue for `task::Waker::noop`" rust#98286

**Link:** https://github.com/rust-lang/rust/issues/98286

### "Tracking Issue for `Ready::into_inner()`" rust#101196

**Link:** https://github.com/rust-lang/rust/issues/101196

### "Add `AsyncFn` family of traits" rust#119305

**Link:** https://github.com/rust-lang/rust/pull/119305

### "Add LocalWaker support" libs-team#191

**Link:** https://github.com/rust-lang/libs-team/issues/191

## Untriaged issues

### "ICE with "failed to resolve instance for <... as IntoFuture>::into_future: Ok(None)" (regression between 1.73 and 1.74)" rust#119095

**Link:** https://github.com/rust-lang/rust/issues/119095

### "Add `AsyncFn` family of traits" rust#119305

**Link:** https://github.com/rust-lang/rust/pull/119305

### "never patterns: `!` argument not detected as diverging on async fn" rust#120240

**Link:** https://github.com/rust-lang/rust/issues/120240

### "Add LocalWaker support" libs-team#191

**Link:** https://github.com/rust-lang/libs-team/issues/191

## WG RFCs, PRs, and issues nominated for T-lang/T-types

### "`.await` does not perform autoref or autoderef" rust#111546

**Link:** https://github.com/rust-lang/rust/issues/111546

## Pending PRs on the WG-async repo

None.

## `S-waiting-on-team`

### "Rename `AsyncIterator` back to `Stream`, introduce an AFIT-based `AsyncIterator` trait" rust#119550

**Link:** https://github.com/rust-lang/rust/pull/119550

## Proposed FCPs

**Check your boxes!**

### "Tracking Issue for `Ready::into_inner()`" rust#101196

**Link:** https://github.com/rust-lang/rust/issues/101196

## Active FCPs

None.

## P-critical issues

None.

## WG-async work project board

https://github.com/orgs/rust-lang/projects/29/views1/d
