Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gen blocks and reserve keyword in Rust 2024 #3513

Merged
merged 45 commits into from
Apr 7, 2024
Merged
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
1cbbe3c
WIP
oli-obk Oct 11, 2023
6b3726e
iter -> gen
oli-obk Oct 11, 2023
585afb9
`?` desugaring
oli-obk Oct 11, 2023
c905ce0
Use correct desugaring to support all `Try` types
oli-obk Oct 11, 2023
e10c2a6
Unresolved questions and future ideas
oli-obk Oct 12, 2023
625826d
replace-all failure
oli-obk Oct 12, 2023
3f3799a
Motivation and generators
oli-obk Oct 12, 2023
4146a83
Add implementation section
oli-obk Oct 12, 2023
ca7bb01
Some details about interactions with other features
oli-obk Oct 12, 2023
e07b766
Explain lack of fusing
oli-obk Oct 12, 2023
1bb969f
Actually, the `async gen` troubles aren't anything beyond the `self-r…
oli-obk Oct 12, 2023
7d06af4
feedback (#2)
shepmaster Oct 12, 2023
08c07d2
Address concerns around my phrasing of `async gen` blocks
oli-obk Oct 13, 2023
d89eb26
Address some concerns
oli-obk Oct 13, 2023
e06745e
No syntax, only semantics
oli-obk Oct 13, 2023
09c3ff1
`Iterator::size_hint`
oli-obk Oct 13, 2023
45ce4db
Update RFC PR id
oli-obk Oct 13, 2023
e9bbc6e
Fix and improve capitalization and punctuation
traviscross Oct 13, 2023
118b777
Fix links to the unresolved questions section
traviscross Oct 13, 2023
00335a2
Add section noting C# prior art
traviscross Oct 13, 2023
94096d5
Add example and mention of `std::iter::from_fn`
traviscross Oct 13, 2023
a8295c8
Clarify rules on the valid return type of a `gen` block
traviscross Oct 13, 2023
e5c803c
Clarify section on error handling
traviscross Oct 13, 2023
b949fec
Add more full history of generators in prior art
traviscross Oct 16, 2023
c982935
Switch back to using `gen` keyword throughout RFC
traviscross Oct 18, 2023
ffcf881
Remove language about an experiment
traviscross Oct 18, 2023
b524348
Address T-lang feedback
oli-obk Feb 29, 2024
349c517
Give some examples of self-referential generators and why they don't …
oli-obk Feb 29, 2024
b836635
Make self-referential `gen` blocks an open question
traviscross Mar 13, 2024
6478947
Adjust for `Generator -> Coroutine` rename
traviscross Mar 14, 2024
a2bf473
Add unresolved question about implemented traits
traviscross Mar 14, 2024
caf93ba
Fix `k#gen`
traviscross Mar 15, 2024
8846955
Fix where we fixed `k#gen`
traviscross Mar 15, 2024
32ffb27
Add tracking issue for RFC 3513
traviscross Mar 27, 2024
3f0159d
Rename file for RFC 3513
traviscross Mar 27, 2024
787e0e9
Update feature name to `gen_blocks`
traviscross Mar 27, 2024
ad74905
Unwrap lines
traviscross Mar 27, 2024
f6cd712
Add future possibility of implementing `FusedIterator`
traviscross Mar 27, 2024
4bf6106
Remove incorrect statement about pinning
traviscross Mar 27, 2024
59be7f9
Add open question about Rust 2015 and Rust 2018
traviscross Mar 28, 2024
31c7b28
Do a round of copyediting
traviscross Mar 27, 2024
7eacd06
Add Koka example to prior art
traviscross Mar 28, 2024
a021905
Add Rust example to prior art
traviscross Mar 28, 2024
354abf6
Add note about `return yield EXPR`
traviscross Mar 29, 2024
22f7267
Use RLE as a stronger motivating example
traviscross Mar 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Adjust for Generator -> Coroutine rename
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.
  • Loading branch information
traviscross committed Mar 14, 2024
commit 6478947eb43406859d5a63dd728d1b2969726471
20 changes: 10 additions & 10 deletions text/0000-gen-fn.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,11 @@ on iterators over `Result`s.

## Implementation

This feature is mostly implemented via existing generators, though there are some special cases.
This feature is mostly implemented via existing coroutines, though there are some special cases.

### `gen` blocks

`gen` blocks are the same as an unstable generator...
`gen` blocks are the same as an unstable coroutine...

* ...without arguments,
* ...with an additional check forbidding holding borrows across `yield` points,
traviscross marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -207,7 +207,7 @@ This feature is mostly implemented via existing generators, though there are som

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

In contrast to `Generator`, `gen` blocks that produce `Iterator`s cannot hold references across `yield` points.
In contrast to `Coroutine`s (currently unstable), `gen` blocks that produce iterators cannot hold references across `yield` points.
See [`from_generator`][] which has an `Unpin` bound on the generator it takes to produce an `Iterator`.

The `gen` keyword causes some fallout in the community, mostly around the `rand` crate, which has `gen` methods on its traits.
Expand All @@ -220,7 +220,7 @@ The `gen` keyword causes some fallout in the community, mostly around the `rand`

We could use `iter` as the keyword.
I prefer `iter` because I connect generators with a more powerful scheme than plain `Iterator`s.
The `Generator` trait can do everything that `iter` blocks and `async` blocks can do and more.
The unstable `Coroutine` trait (which was previously called `Generator`) can do everything that `iter` blocks and `async` blocks can do and more.
I believe connecting the `Iterator` trait with `iter` blocks is the right choice,
but that would require us to carve out many exceptions for this keyword as `iter` is used for module names and method names everywhere (including libstd/libcore).
It may not be much worse than `gen` (see also [the unresolved questions][unresolved-questions]).
Expand All @@ -234,7 +234,7 @@ Some of these new methods would need to be very generic.
While it's not an `Iterator` example, [`array::try_map`][] is something that has very complex diagnostics that are hard to improve, even if it's nice once it works.

Users can use crates like [`genawaiter`](https://crates.io/crates/genawaiter) or [`propane`](https://crates.io/crates/propane) instead.
`genawaiter` works on stable and provides `gen!` macro blocks that behave like `gen` blocks, but don't have compiler support for nice diagnostics or language support for the `?` operator. The `propane` crate uses the `Generator` trait from nightly and works mostly
`genawaiter` works on stable and provides `gen!` macro blocks that behave like `gen` blocks, but don't have compiler support for nice diagnostics or language support for the `?` operator. The `propane` crate uses the `Coroutine` trait from nightly and works mostly
like `gen` would.

The standard library includes [`std::iter::from_fn`][], which can be used in
Expand Down Expand Up @@ -736,18 +736,18 @@ The macro would expand to a `for` loop + `yield`.
yield_all!(iter)
```

## Complete `Generator` support
## Complete `Coroutine` support

We already have a `Generator` trait on nightly that is more powerful than the `Iterator`
We already have a `Coroutine` trait on nightly (previously called `Generator`) that is more powerful than the `Iterator`
API could possibly be:

1. It uses `Pin<&mut Self>`, allowing self-references in the generator across yield points.
1. It uses `Pin<&mut Self>`, allowing self-references across yield points.
2. It has arguments (`yield` returns the arguments passed to it in the subsequent invocations).

Similar to the ideas around `async` closures,
I think we could argue for `Generators` to be `gen` closures while `gen` blocks are a simpler concept that has no arguments and only captures variables.
I think we could argue for coroutines to be `gen` closures while `gen` blocks are a simpler concept that has no arguments and only captures variables.

Either way, support for full `Generator`s should be discussed and implemented separately,
Either way, support for full coroutines should be discussed and implemented separately,
as there are many more open questions around them beyond a simpler way to write `Iterator`s.

## `async` interactions
Expand Down