Skip to content

Commit 4146a83

Browse files
committed
Add implementation section
1 parent 3f3799a commit 4146a83

File tree

1 file changed

+27
-25
lines changed

1 file changed

+27
-25
lines changed

text/0000-gen-fn.md

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,6 @@ gen fn odd_dup(values: impl Iterator<Item = u32>) -> u32 {
7979
# Guide-level explanation
8080
[guide-level-explanation]: #guide-level-explanation
8181

82-
- Introducing new named concepts.
83-
- Explaining the feature largely in terms of examples.
84-
- Explaining how Rust programmers should *think* about the feature, and how it should impact the way they use Rust. It should explain the impact as concretely as possible.
85-
- If applicable, provide sample error messages, deprecation warnings, or migration guidance.
86-
- If applicable, describe the differences between teaching this to existing Rust programmers and new Rust programmers.
87-
- Discuss how this impacts the ability to read, understand, and maintain Rust code. Code is read and modified far more often than written; will the proposed feature make code easier to maintain?
88-
89-
For implementation-oriented RFCs (e.g. for compiler internals), this section should focus on how compiler contributors should think about the change, and give examples of its concrete impact. For policy RFCs, this section should provide an example-driven introduction to the policy, and explain its impact in concrete terms.
90-
9182
## New keyword
9283

9384
Starting in the 2024 edition, `gen` is a keyword that cannot be used for naming any items or bindings. This means during the migration to the 2024 edition, all variables, functions, modules, types, ... named `gen` must be renamed.
@@ -125,15 +116,6 @@ Similarly the `?` operator on `Option`s will `yield None` if it is `None`, and r
125116

126117
# Reference-level explanation
127118
[reference-level-explanation]: #reference-level-explanation
128-
129-
This is the technical portion of the RFC. Explain the design in sufficient detail that:
130-
131-
- Its interaction with other features is clear.
132-
- It is reasonably clear how the feature would be implemented.
133-
- Corner cases are dissected by example.
134-
135-
The section should return to the examples given in the previous section, and explain more fully how the detailed proposal makes those examples work.
136-
137119
## New keyword
138120

139121
In the 2024 edition we reserve `gen` as a keyword. Previous editions need to use `k#gen` to get the same features.
@@ -155,25 +137,45 @@ match foo.branch() {
155137
which will stop iteration after the first error. This is the same behaviour that `collect::<Result<_, _>>()` performs
156138
on any iterator over `Result`s
157139

140+
## Implementation
141+
142+
This feature is mostly implemented via existing generators, we'll just need some desugarings and then lots of work to get good diagnostics.
143+
144+
### Gen fn
145+
146+
`gen fn` desugars to the function itself, with its return type replaced by `impl Iterator<Item = $ret>` and its body wrapped in a `gen` block.
147+
So a `gen fn`'s "return type" is in fact its iterator's `yield` type.
148+
149+
A `gen fn` captures all lifetimes and generic parameters into the `impl Iterator` return type (just like `async fn`).
150+
If you want more control over your captures, you'll need to use type alias impl trait when that becomes stable.
151+
152+
Just like all other uses of `impl Trait`, auto traits are revealed without being specified.
153+
154+
### Gen blocks
155+
156+
`gen` blocks are effectively the same as an unstable generator
157+
158+
* without arguments,
159+
* with an additional check forbidding holding borrows across `yield` points,
160+
* and an automatic `Iterator` implementation.
161+
162+
We'll probably be able to modularize the generator impl and make it more robust (on the impl and diagnostics side) for the `gen` block case, but I believe the initial implementation should just be a HIR lowering to a generator and wrapping that generator in `std::iterator::from_generator`.
163+
158164
# Drawbacks
159165
[drawbacks]: #drawbacks
160166

161167
It's another language feature for something that can already be written entirely in user code.
162168

163169
# Rationale and alternatives
164170
[rationale-and-alternatives]: #rationale-and-alternatives
165-
166-
- Why is this design the best in the space of possible designs?
167-
- What other designs have been considered and what is the rationale for not choosing them?
168-
- What is the impact of not doing this?
169-
- If this is a language proposal, could this be done in a library or macro instead? Does the proposed change make Rust code easier or harder to read, understand, and maintain?
170-
171171
## Keyword
172172

173173
We could also use `iter` as a keyword. I would prefer `iter` in because I connect generators with a more powerful
174174
scheme than just plain `Iterator`s. The `Generator` trait can do everything that `iter` blocks and `async` blocks can do, and more. I believe connecting the `Iterator`
175175
trait with `iter` blocks is the right choice, but that would require us to carve out many exceptions for this keyword,
176-
as `iter` is used for module names and method names everywhere (including libstd/libcore). It may not be much worse than `gen` (see also [#unresolved-questions])
176+
as `iter` is used for module names and method names everywhere (including libstd/libcore). It may not be much worse than `gen` (see also [#unresolved-questions]).
177+
178+
One argument for `iter` is also that we may want to use `gen` for full on generators in the future.
177179

178180
## 2021 edition
179181

0 commit comments

Comments
 (0)