@@ -28,7 +28,7 @@ around them below:
28
28
are stored if needed across yields. I'm borrowing this terminology here. Any
29
29
such cross-yield bindings are said to be "witnessed".
30
30
31
- ``` rust
31
+ ``` rust,ignore
32
32
// This is an example coroutine which might assist a streaming base64 encoder
33
33
|sextet, octets| {
34
34
let a = sextet; // witness a, b, and c sextets for later use
@@ -108,7 +108,7 @@ async gen {
108
108
- People will get yelled at by the borrow checker if they try to hold borrows
109
109
of arguments across yields. But the fix is generally easy: move the argument
110
110
to a new binding before yielding.
111
- ```
111
+ ``` text
112
112
=> |x| {
113
113
let y = &x;
114
114
yield;
@@ -138,7 +138,7 @@ error[E0506]: cannot pass new `x` because it is borrowed
138
138
shadow old ones at yield in order to allow easy borrowing of past argument
139
139
values. But this is a huge footgun. See if you can spot the issue with the
140
140
following code if ` ctx ` shadows its past value rather than overwriting it:
141
- ``` rust
141
+ ``` rust,ignore
142
142
std::future::from_fn(|ctx| {
143
143
if is_blocked() {
144
144
register_waker(ctx);
@@ -168,7 +168,7 @@ std::future::from_fn(|ctx| {
168
168
169
169
- What happens when a coroutine witnesses a borrow passed as a resume argument?
170
170
For example:
171
- ``` rust
171
+ ``` rust,ignore
172
172
let co = |x: &i32| {
173
173
let mut values = Vec::new();
174
174
loop {
@@ -191,7 +191,7 @@ co(&x);
191
191
treat the witness and capture data the same whenever possible, the example
192
192
above would fail in a similar way to the example below, giving a "borrowed
193
193
data escapes into closure state" error or similar even if ` x ` is not mutated.
194
- ``` rust
194
+ ``` rust,ignore
195
195
let mut values = Vec::new();
196
196
|x: &i32| {
197
197
loop {
@@ -210,7 +210,7 @@ let mut values = Vec::new();
210
210
- Coroutines would eventually like to yield borrows of state to the caller. This
211
211
is "lending" coroutine (sometimes also called an "attached" coroutine).
212
212
- Using [ MCP-49] [ 3 ] , a lending coroutine might look like:
213
- ``` rust
213
+ ``` rust,ignore
214
214
|| {
215
215
let mut buffer = Vec::new();
216
216
loop {
@@ -252,7 +252,7 @@ let mut values = Vec::new();
252
252
` GeneratorState<T, T> ` could be wrapped to return ` T ` by some sort of
253
253
combinator and a coroutine that only returns ` T ` can have ` yield ` and ` return `
254
254
values manually wrapped in ` GeneratorState ` . This is just about ergonomics:
255
- ``` rust
255
+ ``` rust,ignore
256
256
// Without enum wrapping:
257
257
std::iter::from_fn(|| {
258
258
yield Some(1);
@@ -308,7 +308,7 @@ fn merge_gen_state<T>(f: impl FnMut() -> GeneratorState<T, T>) -> T { ... }
308
308
(really witness-pinned) by ` pin_mut! ` is not referenced and is ` Unpin ` .
309
309
- Until inference is solved, the ` static ` keyword can be used as a modifier.
310
310
311
- ``` rust
311
+ ``` rust,ignore
312
312
// movable via inference
313
313
|| {
314
314
let x = 4;
@@ -388,7 +388,7 @@ static || {
388
388
- What happens if a yielded future is destroyed early? Panic on resume?
389
389
- Generators and async are both sugars on top of coroutines and are orthogonal
390
390
to each other. But neither is orthogonal to the underlying coroutine feature:
391
- ``` rust
391
+ ``` rust,ignore
392
392
// an async block
393
393
async {
394
394
"hello"
@@ -412,7 +412,7 @@ async gen {
412
412
used.
413
413
- For example, an simple little checksumming async write wrapper might look
414
414
like this:
415
- ``` rust
415
+ ``` rust,ignore
416
416
|ctx: &mut Context, bytes: &[u8]| -> Poll<usize> {
417
417
let mut checksum = 0;
418
418
let mut count = 0;
@@ -465,7 +465,7 @@ def write_greeting(name, words):
465
465
466
466
```
467
467
468
- ``` rust
468
+ ``` rust,ignore
469
469
// Function only needs name to construct coroutine.
470
470
// Coroutine gets mutable access to the word list each resume.
471
471
fn write_greeting(name: String) -> impl FnMut(&mut Vec<String>) {
@@ -522,7 +522,7 @@ fn write_greeting(name: String) -> impl FnMut(&mut Vec<String>) {
522
522
so obvious for coroutines in general as it is for generators specifically.
523
523
- Once generalized coroutines are in place, a generator syntax like the one in
524
524
[ RFC-2996] [ 4 ] is a trivial sugar on top:
525
- ``` rust
525
+ ``` rust,ignore
526
526
gen {
527
527
for item in inner {
528
528
for mapped in func(item) {
@@ -542,7 +542,7 @@ std::iter::from_fn(|| {
542
542
None
543
543
})
544
544
```
545
- ``` rust
545
+ ``` rust,ignore
546
546
async gen {
547
547
while let Some(item) = inner.next().await {
548
548
yield func(item).await;
0 commit comments