Skip to content

Commit 70632be

Browse files
Merge pull request #64 from samsartor/master
Add general_coroutines notes to the mdbook
2 parents 7645e56 + 740bbe5 commit 70632be

File tree

2 files changed

+14
-13
lines changed

2 files changed

+14
-13
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99
- [Proposing a new project](./proposing_a_project.md)
1010
- [Design notes](./design_notes.md)
1111
- [Allowing integer literals like `1` to be inferred to floating point](./design_notes/int_literal_as_float.md)
12+
- [Generalizing coroutines](./design_notes/general_coroutines.md)

src/design_notes/general_coroutines.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ around them below:
2828
are stored if needed across yields. I'm borrowing this terminology here. Any
2929
such cross-yield bindings are said to be "witnessed".
3030

31-
```rust
31+
```rust,ignore
3232
// This is an example coroutine which might assist a streaming base64 encoder
3333
|sextet, octets| {
3434
let a = sextet; // witness a, b, and c sextets for later use
@@ -108,7 +108,7 @@ async gen {
108108
- People will get yelled at by the borrow checker if they try to hold borrows
109109
of arguments across yields. But the fix is generally easy: move the argument
110110
to a new binding before yielding.
111-
```
111+
```text
112112
=> |x| {
113113
let y = &x;
114114
yield;
@@ -138,7 +138,7 @@ error[E0506]: cannot pass new `x` because it is borrowed
138138
shadow old ones at yield in order to allow easy borrowing of past argument
139139
values. But this is a huge footgun. See if you can spot the issue with the
140140
following code if `ctx` shadows its past value rather than overwriting it:
141-
```rust
141+
```rust,ignore
142142
std::future::from_fn(|ctx| {
143143
if is_blocked() {
144144
register_waker(ctx);
@@ -168,7 +168,7 @@ std::future::from_fn(|ctx| {
168168

169169
- What happens when a coroutine witnesses a borrow passed as a resume argument?
170170
For example:
171-
```rust
171+
```rust,ignore
172172
let co = |x: &i32| {
173173
let mut values = Vec::new();
174174
loop {
@@ -191,7 +191,7 @@ co(&x);
191191
treat the witness and capture data the same whenever possible, the example
192192
above would fail in a similar way to the example below, giving a "borrowed
193193
data escapes into closure state" error or similar even if `x` is not mutated.
194-
```rust
194+
```rust,ignore
195195
let mut values = Vec::new();
196196
|x: &i32| {
197197
loop {
@@ -210,7 +210,7 @@ let mut values = Vec::new();
210210
- Coroutines would eventually like to yield borrows of state to the caller. This
211211
is "lending" coroutine (sometimes also called an "attached" coroutine).
212212
- Using [MCP-49][3], a lending coroutine might look like:
213-
```rust
213+
```rust,ignore
214214
|| {
215215
let mut buffer = Vec::new();
216216
loop {
@@ -252,7 +252,7 @@ let mut values = Vec::new();
252252
`GeneratorState<T, T>` could be wrapped to return `T` by some sort of
253253
combinator and a coroutine that only returns `T` can have `yield` and `return`
254254
values manually wrapped in `GeneratorState`. This is just about ergonomics:
255-
```rust
255+
```rust,ignore
256256
// Without enum wrapping:
257257
std::iter::from_fn(|| {
258258
yield Some(1);
@@ -308,7 +308,7 @@ fn merge_gen_state<T>(f: impl FnMut() -> GeneratorState<T, T>) -> T { ... }
308308
(really witness-pinned) by `pin_mut!` is not referenced and is `Unpin`.
309309
- Until inference is solved, the `static` keyword can be used as a modifier.
310310

311-
```rust
311+
```rust,ignore
312312
// movable via inference
313313
|| {
314314
let x = 4;
@@ -388,7 +388,7 @@ static || {
388388
- What happens if a yielded future is destroyed early? Panic on resume?
389389
- Generators and async are both sugars on top of coroutines and are orthogonal
390390
to each other. But neither is orthogonal to the underlying coroutine feature:
391-
```rust
391+
```rust,ignore
392392
// an async block
393393
async {
394394
"hello"
@@ -412,7 +412,7 @@ async gen {
412412
used.
413413
- For example, an simple little checksumming async write wrapper might look
414414
like this:
415-
```rust
415+
```rust,ignore
416416
|ctx: &mut Context, bytes: &[u8]| -> Poll<usize> {
417417
let mut checksum = 0;
418418
let mut count = 0;
@@ -465,7 +465,7 @@ def write_greeting(name, words):
465465

466466
```
467467

468-
```rust
468+
```rust,ignore
469469
// Function only needs name to construct coroutine.
470470
// Coroutine gets mutable access to the word list each resume.
471471
fn write_greeting(name: String) -> impl FnMut(&mut Vec<String>) {
@@ -522,7 +522,7 @@ fn write_greeting(name: String) -> impl FnMut(&mut Vec<String>) {
522522
so obvious for coroutines in general as it is for generators specifically.
523523
- Once generalized coroutines are in place, a generator syntax like the one in
524524
[RFC-2996][4] is a trivial sugar on top:
525-
```rust
525+
```rust,ignore
526526
gen {
527527
for item in inner {
528528
for mapped in func(item) {
@@ -542,7 +542,7 @@ std::iter::from_fn(|| {
542542
None
543543
})
544544
```
545-
```rust
545+
```rust,ignore
546546
async gen {
547547
while let Some(item) = inner.next().await {
548548
yield func(item).await;

0 commit comments

Comments
 (0)