You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
84
84
85
+
## New keyword
86
+
87
+
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.
88
+
85
89
## Returning/finishing an iterator
86
90
87
-
`iter` blocks' trailing expression must be of unit type or the block must diverge before reaching its end.
91
+
`gen` blocks' trailing expression must be of unit type or the block must diverge before reaching its end.
88
92
89
93
### Diverging iterators
90
94
91
-
For example, an `iter` block that produces the sequence `0, 1, 0, 1, 0, 1, ...`, will never return `None`
95
+
For example, an `gen` block that produces the sequence `0, 1, 0, 1, 0, 1, ...`, will never return `None`
92
96
from `next`, and only drop its captured data when the iterator is dropped.
93
97
94
98
```rust
95
-
iter {
99
+
gen {
96
100
loop {
97
101
yield0;
98
102
yield1;
99
103
}
100
104
}
101
105
```
102
106
103
-
If an `iter` panics, the behavior is very similar to `return`, except that `next` doesn't return `None`, but unwinds.
107
+
If an `gen` panics, the behavior is very similar to `return`, except that `next` doesn't return `None`, but unwinds.
104
108
105
109
## Error handling
106
110
107
-
Within `iter` blocks, the `?` operator desugars differently from how it desugars outside of `iter` blocks.
111
+
Within `gen` blocks, the `?` operator desugars differently from how it desugars outside of `gen` blocks.
108
112
Instead of returning the `Err` variant, `foo?` yields the `Err` variant and then `return`s immediately afterwards.
109
113
This has the effect of it being an iterator with `Iterator::Item`'s type being `Result<T, E>`, and once a `Some(Err(e))`
110
114
is produced via `?`, the iterator returns `None` next.
111
115
112
-
`iter` blocks do not need to have a trailing `Ok(x)` expression, because returning from an `iter` block will make the `Iterator` return `None` from now, which needs no value.
116
+
`gen` blocks do not need to have a trailing `Ok(x)` expression, because returning from an `gen` block will make the `Iterator` return `None` from now, which needs no value.
@@ -141,34 +145,40 @@ Why should we *not* do this?
141
145
142
146
## Keyword
143
147
144
-
We could also use `gen` (for `generator`) as a keyword. The reason I chose `iter` in this RFC, is that people (including me) connect generators with a more powerful
148
+
We could also use `iter`as a keyword. I would prefer `iter` in because I connect generators with a more powerful
145
149
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`
146
-
trait with `iter` blocks is the right choice, but I also don't feel too strongly about it.
150
+
trait with `iter` blocks is the right choice, but that would require us to carve out many exceptions for this keyword,
151
+
as `iter` is used for module names and method names everywhere (including libstd/libcore).
152
+
153
+
## Contextual keyword
154
+
155
+
We allow `gen` as an identifier for function names and module names, without that conflicting with `gen` blocks, but that makes the syntax more complicated than necessary, for not too much gain.
156
+
157
+
## 2021 edition
147
158
148
-
## Non-Contextual keyword
159
+
We could allow `gen` blocks on the 2021 edition via `k#gen {}` syntax.
160
+
We can allow `gen fn` on all editions.
149
161
150
-
We could forbid `iter` from being used as an identifier anywhere.
162
+
## `gen` identifiers on 2024 edition
151
163
152
-
I believe blocking `iter` (or even just `gen`) from being used as module, type and function names is not feasible.
153
-
The standard library contains an `iter` module and many
154
-
data structures have `iter` methods implemented for them.
164
+
We can allow `i#gen` identifiers in the 2024 edition in order to refer to items named `gen` in previous edition crates.
155
165
156
166
## Do not do this
157
167
158
168
The alternative is to keep adding more helper methods to `Iterator`. It is already rather hard for new Rustaceans to get a hold of all the options they have on `Iterator`.
159
169
Some such methods would also need to be very generic (not an `Iterator` example, but https://doc.rust-lang.org/std/primitive.array.html#method.try_map on arrays is something
160
170
that has very complex diagnostics that are hard to improve, even if it's nice once it works).
161
171
162
-
Users can use crates like [`genawaiter`](https://crates.io/crates/genawaiter) instead, which work on stable and give you `gen!` blocks that behave pretty mostly
163
-
like `iter` blocks, but don't have compiler support for nice diagnostics or language support for the `?` operator.
172
+
Users can use crates like [`genawagen`](https://crates.io/crates/genawagen) instead, which work on stable and give you `gen!` blocks that behave pretty mostly
173
+
like `gen` blocks, but don't have compiler support for nice diagnostics or language support for the `?` operator.
164
174
165
175
# Prior art
166
176
[prior-art]: #prior-art
167
177
168
178
## Python
169
179
170
-
Python has `iter fn`: any funciton that uses `yield` internally.
171
-
These work pretty much like the `iter` functions proposed in this PR. The main difference is that raising an
180
+
Python has `gen fn`: any function that uses `yield` internally.
181
+
These work pretty much like the `gen` functions proposed in this PR. The main difference is that raising an
172
182
exception automatically passes the exception outwards, instead of yielding an `Err()` element.
0 commit comments