Skip to content

Commit

Permalink
Actually, the async gen troubles aren't anything beyond the `self-r…
Browse files Browse the repository at this point in the history
…eferential` `gen` block issues
  • Loading branch information
oli-obk committed Oct 12, 2023
1 parent e07b766 commit 1bb969f
Showing 1 changed file with 9 additions and 4 deletions.
13 changes: 9 additions & 4 deletions text/0000-gen-fn.md
Original file line number Diff line number Diff line change
Expand Up @@ -350,17 +350,22 @@ as there are many more open questions around them than around just a simpler way

## `async` interactions

We could support using `await` in `gen` blocks, similar to how we support `?` being used within them.
This is not trivially possible due to the fact that `Iterator::next` takes `&mut self` and not `Pin<&mut self>`.
We could support using `await` in `async gen` blocks, similar to how we support `?` being used within `gen` blocks.
This is not possible in general due to the fact that `Iterator::next` takes `&mut self` and not `Pin<&mut self>`, but
it should be possible if no references are held across the `await` point, similar to how we disallow holding
references across `yield` points in this RFC.

This comment has been minimized.

Copy link
@yoshuawuyts

yoshuawuyts Oct 12, 2023

Member

I feel like this section could benefit from explaining the composition rules of the "async" and "gen" effects. Right now it mostly just focuses on the self-references. Can I suggest an alternate wording here?


async interactions

Given this RFC proposes adding a gen keyword to both blocks and functions, users might reasonably expect to be able to combine them with other effect keywords such as async. This would result in the existence of async gen fn functions and async gen {} blocks. The way we expect these effects to compose would be to return an "iterator which yields futures", and not "a future which returns an iterator". This RFC treats control-flow modifier keywords as sets, meaning they should only ever compose in a single way. If a user desires to express alternate formulations for effect composition such as "a future which returns an iterator", it should be possible to manually author those via RPIT.

Note also that under these rules this RFC does not pose the restriction that "async iterators" need to be self-referential (async fn next supporting self-references). self-references are not required to provide async iterator functionality, just like they're not required for non-async iterators. For that reason this RFC considers support for self-references in iterators to be an orthogonal feature. See the section on "self-referential gen blocks" for further discussion on self-referential iterators.


There are a few options forward for this:

## self-referential `gen` bloocks

There are a few options forward:

* Add a separate trait for pinned iteration that is also usable with `gen` and `for`
* downside: very similar traits for the same thing
* backwards compatibly add a way to change the argument type of `Iterator::next`
* downside: unclear if possible
* implement `Iterator` for `Pin<&mut G>` instead of for `G` directly (whatever `G` is here, but it could be a `gen` block)
* downside: the thing being iterated over must now be pinned for the entire iteration, instead of for each iteration
* downside: the thing being iterated over must now be pinned for the entire iteration, instead of for each invocation of `next`.

## `try` interactions

Expand Down

0 comments on commit 1bb969f

Please sign in to comment.