Skip to content

Commit edf65e7

Browse files
committed
Add support for postfix yield expressions
We had a discussion[1] today about whether postfix yield would make sense. It's easy enough to support both in the parser, so we might as well have both and see how people use it while the feature is experimental. [1]: https://rust-lang.zulipchat.com/#narrow/channel/481571-t-lang.2Fgen/topic/postfix-yield/with/505231568
1 parent cb50d4d commit edf65e7

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,13 @@ impl<'a> Parser<'a> {
13101310
return self.parse_match_block(lo, match_span, self_arg, MatchKind::Postfix);
13111311
}
13121312

1313+
// Post-fix yield
1314+
if self.eat_keyword(exp!(Yield)) {
1315+
let yield_span = self.prev_token.span;
1316+
self.psess.gated_spans.gate(sym::yield_expr, yield_span);
1317+
return Ok(self.mk_expr(yield_span, ExprKind::Yield(Some(self_arg))));
1318+
}
1319+
13131320
let fn_span_lo = self.token.span;
13141321
let mut seg = self.parse_path_segment(PathStyle::Expr, None)?;
13151322
self.check_trailing_angle_brackets(&seg, &[exp!(OpenParen)]);

tests/ui/coroutine/postfix-yield.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// This demonstrates a proposed alternate or additional option of having yield in postfix position.
2+
3+
//@ run-pass
4+
//@ edition: 2024
5+
6+
#![feature(gen_blocks, coroutines, coroutine_trait, yield_expr)]
7+
8+
use std::ops::{Coroutine, CoroutineState};
9+
use std::pin::pin;
10+
11+
fn main() {
12+
// generators (i.e. yield doesn't return anything useful)
13+
let mut gn = gen {
14+
yield 1;
15+
2.yield;
16+
};
17+
18+
assert_eq!(gn.next(), Some(1));
19+
assert_eq!(gn.next(), Some(2));
20+
assert_eq!(gn.next(), None);
21+
22+
//coroutines (i.e. yield returns something useful)
23+
let mut coro = pin!(
24+
#[coroutine]
25+
|_: i32| {
26+
let x = yield 1;
27+
yield x + 2;
28+
}
29+
);
30+
31+
assert_eq!(coro.as_mut().resume(0), CoroutineState::Yielded(1));
32+
assert_eq!(coro.as_mut().resume(2), CoroutineState::Yielded(4));
33+
assert_eq!(coro.as_mut().resume(3), CoroutineState::Complete(()));
34+
}

0 commit comments

Comments
 (0)