about summary refs log tree commit diff
path: root/example
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2023-11-23 20:02:45 +0000
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2023-11-23 20:17:19 +0000
commit4ae658683f87b0f34ffb5c06f50ca1c51333a1a4 (patch)
tree0aa817138b1c4142147f3965fe7fe213ecf4f948 /example
parentdfc669b74c214ad5afeb94211ebe1fd70ac8d43a (diff)
downloadrust-4ae658683f87b0f34ffb5c06f50ca1c51333a1a4.tar.gz
rust-4ae658683f87b0f34ffb5c06f50ca1c51333a1a4.zip
Fix fn_sig_for_fn_abi and the coroutine transform for generators
There were three issues previously:
* The self argument was pinned, despite Iterator::next taking an
  unpinned mutable reference.
* A resume argument was passed, despite Iterator::next not having one.
* The return value was CoroutineState<Item, ()> rather than Option<Item>

While these things just so happened to work with the LLVM backend,
cg_clif does much stricter checks when trying to assign a value to a
place. In addition it can't handle the mismatch between the amount of
arguments specified by the FnAbi and the FnSig.
Diffstat (limited to 'example')
-rw-r--r--example/gen_block_iterate.rs36
1 files changed, 36 insertions, 0 deletions
diff --git a/example/gen_block_iterate.rs b/example/gen_block_iterate.rs
new file mode 100644
index 00000000000..14bd23e77ea
--- /dev/null
+++ b/example/gen_block_iterate.rs
@@ -0,0 +1,36 @@
+// Copied from https://github.com/rust-lang/rust/blob/46455dc65069387f2dc46612f13fd45452ab301a/tests/ui/coroutine/gen_block_iterate.rs
+// revisions: next old
+//compile-flags: --edition 2024 -Zunstable-options
+//[next] compile-flags: -Ztrait-solver=next
+// run-pass
+#![feature(gen_blocks)]
+
+fn foo() -> impl Iterator<Item = u32> {
+    gen { yield 42; for x in 3..6 { yield x } }
+}
+
+fn moved() -> impl Iterator<Item = u32> {
+    let mut x = "foo".to_string();
+    gen move {
+        yield 42;
+        if x == "foo" { return }
+        x.clear();
+        for x in 3..6 { yield x }
+    }
+}
+
+fn main() {
+    let mut iter = foo();
+    assert_eq!(iter.next(), Some(42));
+    assert_eq!(iter.next(), Some(3));
+    assert_eq!(iter.next(), Some(4));
+    assert_eq!(iter.next(), Some(5));
+    assert_eq!(iter.next(), None);
+    // `gen` blocks are fused
+    assert_eq!(iter.next(), None);
+
+    let mut iter = moved();
+    assert_eq!(iter.next(), Some(42));
+    assert_eq!(iter.next(), None);
+
+}