about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-12-22 03:49:44 +0100
committerGitHub <noreply@github.com>2024-12-22 03:49:44 +0100
commit239b7e83371fa0a5ee95ea944ea2ac6ac1fa7395 (patch)
tree3a1362395ad90e8eba491425901eefaad7fed83a
parent7cf91567c4adaa906987c9dae39a96347da7b187 (diff)
parent8f9fede0b877966a702c1f1ac6e4ade7028aef8a (diff)
downloadrust-239b7e83371fa0a5ee95ea944ea2ac6ac1fa7395.tar.gz
rust-239b7e83371fa0a5ee95ea944ea2ac6ac1fa7395.zip
Rollup merge of #134618 - RalfJung:coroutine-clone-comments, r=lqd
coroutine_clone: add comments

I was very surprised to learn that coroutines can be cloned. This has non-trivial semantic consequences that I do not think have been considered. Lucky enough, it's still unstable. Let's add some comments and pointers so we hopefully become aware when a MIR opt actually is in conflict with this.

Cc `@rust-lang/wg-mir-opt`
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs5
-rw-r--r--tests/ui/coroutine/clone-impl-static.rs2
-rw-r--r--tests/ui/coroutine/clone-impl-static.stderr16
3 files changed, 15 insertions, 8 deletions
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index b7ece5ffa62..0c17a2e0fe5 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -821,6 +821,11 @@ pub enum TerminatorKind<'tcx> {
     /// continues at the `resume` basic block, with the second argument written to the `resume_arg`
     /// place. If the coroutine is dropped before then, the `drop` basic block is invoked.
     ///
+    /// Note that coroutines can be (unstably) cloned under certain conditions, which means that
+    /// this terminator can **return multiple times**! MIR optimizations that reorder code into
+    /// different basic blocks needs to be aware of that.
+    /// See <https://github.com/rust-lang/rust/issues/95360>.
+    ///
     /// Not permitted in bodies that are not coroutine bodies, or after coroutine lowering.
     ///
     /// **Needs clarification**: What about the evaluation order of the `resume_arg` and `value`?
diff --git a/tests/ui/coroutine/clone-impl-static.rs b/tests/ui/coroutine/clone-impl-static.rs
index 62d4392e30c..f6fadff7faf 100644
--- a/tests/ui/coroutine/clone-impl-static.rs
+++ b/tests/ui/coroutine/clone-impl-static.rs
@@ -1,6 +1,8 @@
 //@compile-flags: --diagnostic-width=300
 // gate-test-coroutine_clone
 // Verifies that static coroutines cannot be cloned/copied.
+// This is important: the cloned coroutine would reference state of the original
+// coroutine, leading to semantic nonsense.
 
 #![feature(coroutines, coroutine_clone, stmt_expr_attributes)]
 
diff --git a/tests/ui/coroutine/clone-impl-static.stderr b/tests/ui/coroutine/clone-impl-static.stderr
index bf16b166960..db1d2770346 100644
--- a/tests/ui/coroutine/clone-impl-static.stderr
+++ b/tests/ui/coroutine/clone-impl-static.stderr
@@ -1,27 +1,27 @@
-error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:9:5: 9:19}: Copy` is not satisfied
-  --> $DIR/clone-impl-static.rs:12:16
+error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}: Copy` is not satisfied
+  --> $DIR/clone-impl-static.rs:14:16
    |
 LL |     check_copy(&gen);
-   |     ---------- ^^^^ the trait `Copy` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:9:5: 9:19}`
+   |     ---------- ^^^^ the trait `Copy` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}`
    |     |
    |     required by a bound introduced by this call
    |
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl-static.rs:18:18
+  --> $DIR/clone-impl-static.rs:20:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
-error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:9:5: 9:19}: Clone` is not satisfied
-  --> $DIR/clone-impl-static.rs:14:17
+error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}: Clone` is not satisfied
+  --> $DIR/clone-impl-static.rs:16:17
    |
 LL |     check_clone(&gen);
-   |     ----------- ^^^^ the trait `Clone` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:9:5: 9:19}`
+   |     ----------- ^^^^ the trait `Clone` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}`
    |     |
    |     required by a bound introduced by this call
    |
 note: required by a bound in `check_clone`
-  --> $DIR/clone-impl-static.rs:19:19
+  --> $DIR/clone-impl-static.rs:21:19
    |
 LL | fn check_clone<T: Clone>(_x: &T) {}
    |                   ^^^^^ required by this bound in `check_clone`