about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Holk <ericholk@microsoft.com>2025-03-12 15:59:28 -0700
committerEric Holk <ericholk@microsoft.com>2025-03-14 12:21:58 -0700
commitedf65e735cd871d01149131f5d050293a9f1037c (patch)
treefe1a0949b5b8cd23d3448634d224c00c710ffdc4
parentcb50d4d8566b1ee97e9a5ef95a37a40936a62c30 (diff)
downloadrust-edf65e735cd871d01149131f5d050293a9f1037c.tar.gz
rust-edf65e735cd871d01149131f5d050293a9f1037c.zip
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
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs7
-rw-r--r--tests/ui/coroutine/postfix-yield.rs34
2 files changed, 41 insertions, 0 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 9b2d562a69e..1df6283af26 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1310,6 +1310,13 @@ impl<'a> Parser<'a> {
             return self.parse_match_block(lo, match_span, self_arg, MatchKind::Postfix);
         }
 
+        // Post-fix yield
+        if self.eat_keyword(exp!(Yield)) {
+            let yield_span = self.prev_token.span;
+            self.psess.gated_spans.gate(sym::yield_expr, yield_span);
+            return Ok(self.mk_expr(yield_span, ExprKind::Yield(Some(self_arg))));
+        }
+
         let fn_span_lo = self.token.span;
         let mut seg = self.parse_path_segment(PathStyle::Expr, None)?;
         self.check_trailing_angle_brackets(&seg, &[exp!(OpenParen)]);
diff --git a/tests/ui/coroutine/postfix-yield.rs b/tests/ui/coroutine/postfix-yield.rs
new file mode 100644
index 00000000000..77b1c2a19d0
--- /dev/null
+++ b/tests/ui/coroutine/postfix-yield.rs
@@ -0,0 +1,34 @@
+// This demonstrates a proposed alternate or additional option of having yield in postfix position.
+
+//@ run-pass
+//@ edition: 2024
+
+#![feature(gen_blocks, coroutines, coroutine_trait, yield_expr)]
+
+use std::ops::{Coroutine, CoroutineState};
+use std::pin::pin;
+
+fn main() {
+    // generators (i.e. yield doesn't return anything useful) 
+    let mut gn = gen {
+        yield 1;
+        2.yield;
+    };
+
+    assert_eq!(gn.next(), Some(1));
+    assert_eq!(gn.next(), Some(2));
+    assert_eq!(gn.next(), None);
+
+    //coroutines (i.e. yield returns something useful)
+    let mut coro = pin!(
+        #[coroutine]
+        |_: i32| {
+            let x = yield 1;
+            yield x + 2;
+        }
+    );
+
+    assert_eq!(coro.as_mut().resume(0), CoroutineState::Yielded(1));
+    assert_eq!(coro.as_mut().resume(2), CoroutineState::Yielded(4));
+    assert_eq!(coro.as_mut().resume(3), CoroutineState::Complete(()));
+}