The motivating example we had given for `gen` blocks admitted too easy
an implementation with existing stable iterator combinators. Let's
make the example more *motivating* by showing a simple algorithm,
run-length encoding, that's more difficult to implement in other ways.
(Thanks to Ralf Jung for pointing out the need for a better example.)
Under this RFC, it's possible to yield one last value concisely with
`return yield EXPR`. Let's make a note of that.
(Thanks to Nemo157 for pointing this out and to pnkfelix for
suggesting that this be noted in the RFC.)
The Koka language provides an interesting alternative data point for
how generators and other powerful control flow constructs could work
in a typed language such as Rust. Let's include an example in the
prior art section.
(Thanks to zesterer for asking for this.)
We had been meaning to do some final copyediting prior to this RFC
being merged, so let's do that. In addition to making the text a bit
more regular and precise, fixing some minor errors, removing outdated
information, and adding references between sections, we've tried to
"tighten it up" a bit where possible. We've been careful to not
change anything of semantic significance or otherwise of significance
to the consensus.
In RFC 3101 we reserved in Rust 2021 prefixed identifiers such as
`prefix#ident`. For this reason, we can make `gen` blocks available
in Rust 2021 using `k#gen` as was anticipated in the (currently
pending) RFC 3098.
It's less clear what to do about Rust 2015 and Rust 2018, however, so
let's mark this as an open question.
(Thanks to tmandry for raising this point.)
There was a statement in the draft about, as a downside, something
needing to be pinned for the entire iteration rather than just for
each call to `next`. But, of course, under the pinning guarantees,
these are equivalent. Once something is pinned, unless it is `Unpin`,
it must be treated as pinned until it is destructed. Let's remove
this statement.
The main body of the RFC discusses how we might implement
`FusedIterator` for the iterators produced by `gen` blocks, but this
was not listed as a future possibility. Let's do that.
In addition to giving the file the correct number, let's call this
`gen-blocks` rather than `gen-fn` since we removed `gen fn` from the
main body of this RFC.
In RFC 3498 "Lifetime Capture Rules 2024" we specify that lifetime
parameters from `for<..>` binders are captured under the rules.
Currently opaque types in Rust do not support capturing these. In
early drafts of the document, we had called the missing feature
"higher ranked lifetime bounds on nested opaque types". However, we
had then noticed that the relevant error message in `rustc` called
these "higher kinded" instead:
> error: higher kinded lifetime bounds on nested opaque types are not
> supported yet
We changed later drafts to follow that language. But that language
was wrong. These are definitely "higher ranked" lifetime bounds, not
"higher kinded" ones, whatever that might mean. We've now fixed the
error message emitted by `rustc` in:
- https://github.com/rust-lang/rust/pull/122100
Correspondingly, let's now fix this error in the RFC.
We meant to change `r#gen` to `k#gen` on one line to fix an apparent
earlier search/replace error, and we erroneously changed it on a
different line. Let's fix the correct line and fix the mistaken fix.
The language about how to refer to the `gen` keyword in older editions
was changed in a recent commit from `k#gen` to `r#gen`. This was
probably a search/replace error. Let's fix that.
To give us better options for supporting self-referential generators
we may not want the type returned by `gen` blocks to implement
`Iterator` directly. Let's call this out as an open question and
weaken claims throughout the document related to this.
For many years, we had a trait in nightly Rust called `Generator`.
We've now renamed this to `Coroutine`, but this RFC still referred to
it as `Generator`. Let's use the new name and make a note of the old
one.
We had listed self-referential `gen` blocks as a future possibility,
but in discussion with T-lang, it's become clear that this should
instead be listed as an open question, so let's do that.