about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/messages.ftl2
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs3
-rw-r--r--tests/ui/coroutine/gen_block_panic.rs25
-rw-r--r--tests/ui/coroutine/gen_block_panic.stderr12
4 files changed, 40 insertions, 2 deletions
diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl
index 37ff5bcf1e2..27d555d7e26 100644
--- a/compiler/rustc_middle/messages.ftl
+++ b/compiler/rustc_middle/messages.ftl
@@ -12,6 +12,8 @@ middle_assert_coroutine_resume_after_return = coroutine resumed after completion
 middle_assert_divide_by_zero =
     attempt to divide `{$val}` by zero
 
+middle_assert_gen_resume_after_panic = `gen` fn or block cannot be further iterated on after it panicked
+
 middle_assert_misaligned_ptr_deref =
     misaligned pointer dereference: address must be a multiple of {$required} but is {$found}
 
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index c2aa015f4b7..9dfbe1733cc 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -250,8 +250,7 @@ impl<O> AssertKind<O> {
                 middle_assert_coroutine_resume_after_return
             }
             ResumedAfterPanic(CoroutineKind::Async(_)) => middle_assert_async_resume_after_panic,
-            // FIXME(gen_blocks): custom error message for `gen` blocks
-            ResumedAfterPanic(CoroutineKind::Gen(_)) => middle_assert_async_resume_after_panic,
+            ResumedAfterPanic(CoroutineKind::Gen(_)) => middle_assert_gen_resume_after_panic,
             ResumedAfterPanic(CoroutineKind::Coroutine) => {
                 middle_assert_coroutine_resume_after_panic
             }
diff --git a/tests/ui/coroutine/gen_block_panic.rs b/tests/ui/coroutine/gen_block_panic.rs
new file mode 100644
index 00000000000..33e2b4b265a
--- /dev/null
+++ b/tests/ui/coroutine/gen_block_panic.rs
@@ -0,0 +1,25 @@
+//compile-flags: --edition 2024 -Zunstable-options
+// run-pass
+#![feature(gen_blocks)]
+
+fn main() {
+    let mut iter = gen {
+        yield 42;
+        panic!("foo");
+        yield 69; //~ WARN: unreachable statement
+    };
+    assert_eq!(iter.next(), Some(42));
+    let mut tmp = std::panic::AssertUnwindSafe(&mut iter);
+    match std::panic::catch_unwind(move || tmp.next()) {
+        Ok(_) => unreachable!(),
+        Err(err) => assert_eq!(*err.downcast::<&'static str>().unwrap(), "foo"),
+    }
+
+    match std::panic::catch_unwind(move || iter.next()) {
+        Ok(_) => unreachable!(),
+        Err(err) => assert_eq!(
+            *err.downcast::<&'static str>().unwrap(),
+            "`gen fn` should just keep returning `None` after panicking",
+        ),
+    }
+}
diff --git a/tests/ui/coroutine/gen_block_panic.stderr b/tests/ui/coroutine/gen_block_panic.stderr
new file mode 100644
index 00000000000..33d2a95cab8
--- /dev/null
+++ b/tests/ui/coroutine/gen_block_panic.stderr
@@ -0,0 +1,12 @@
+warning: unreachable statement
+  --> $DIR/gen_block_panic.rs:9:9
+   |
+LL |         panic!("foo");
+   |         ------------- any code following this expression is unreachable
+LL |         yield 69;
+   |         ^^^^^^^^^ unreachable statement
+   |
+   = note: `#[warn(unreachable_code)]` on by default
+
+warning: 1 warning emitted
+