about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2023-11-24 10:46:22 +0100
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2023-11-24 10:46:22 +0100
commit9c958196e717744257e40623ca6598b82e050b9f (patch)
treeb526838338695d5e205746ec9edeeee1ba471a71
parent430ab4e923a16fc46a6738aa4dfc2ff0c735ac9f (diff)
downloadrust-9c958196e717744257e40623ca6598b82e050b9f.tar.gz
rust-9c958196e717744257e40623ca6598b82e050b9f.zip
Fix polymorphization for coroutines
Fixes rust-lang/rustc_codegen_cranelift#1429
-rw-r--r--build_system/tests.rs4
-rw-r--r--config.txt1
-rw-r--r--example/polymorphize_coroutine.rs16
-rw-r--r--src/value_and_place.rs26
4 files changed, 47 insertions, 0 deletions
diff --git a/build_system/tests.rs b/build_system/tests.rs
index f6e6ac6f1e8..4cc572f0aba 100644
--- a/build_system/tests.rs
+++ b/build_system/tests.rs
@@ -99,6 +99,10 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
     TestCase::build_bin_and_run("aot.mod_bench", "example/mod_bench.rs", &[]),
     TestCase::build_bin_and_run("aot.issue-72793", "example/issue-72793.rs", &[]),
     TestCase::build_bin("aot.issue-59326", "example/issue-59326.rs"),
+    TestCase::custom("aot.polymorphize_coroutine", &|runner| {
+        runner.run_rustc(&["example/polymorphize_coroutine.rs", "-Zpolymorphize"]);
+        runner.run_out_command("polymorphize_coroutine", &[]);
+    }),
     TestCase::build_bin_and_run("aot.neon", "example/neon.rs", &[]),
 ];
 
diff --git a/config.txt b/config.txt
index 2ccdc7d7874..79284df6b19 100644
--- a/config.txt
+++ b/config.txt
@@ -42,6 +42,7 @@ aot.float-minmax-pass
 aot.mod_bench
 aot.issue-72793
 aot.issue-59326
+aot.polymorphize_coroutine
 aot.neon
 
 testsuite.extended_sysroot
diff --git a/example/polymorphize_coroutine.rs b/example/polymorphize_coroutine.rs
new file mode 100644
index 00000000000..c965b34e13b
--- /dev/null
+++ b/example/polymorphize_coroutine.rs
@@ -0,0 +1,16 @@
+#![feature(coroutines, coroutine_trait)]
+
+use std::ops::Coroutine;
+use std::pin::Pin;
+
+fn main() {
+    run_coroutine::<i32>();
+}
+
+fn run_coroutine<T>() {
+    let mut coroutine = || {
+        yield;
+        return;
+    };
+    Pin::new(&mut coroutine).resume(());
+}
diff --git a/src/value_and_place.rs b/src/value_and_place.rs
index 9eb8e80d3fc..f52f59716a8 100644
--- a/src/value_and_place.rs
+++ b/src/value_and_place.rs
@@ -977,6 +977,32 @@ pub(crate) fn assert_assignable<'tcx>(
                 }
             }
         }
+        (&ty::Coroutine(def_id_a, args_a, mov_a), &ty::Coroutine(def_id_b, args_b, mov_b))
+            if def_id_a == def_id_b && mov_a == mov_b =>
+        {
+            let mut types_a = args_a.types();
+            let mut types_b = args_b.types();
+            loop {
+                match (types_a.next(), types_b.next()) {
+                    (Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
+                    (None, None) => return,
+                    (Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty),
+                }
+            }
+        }
+        (&ty::CoroutineWitness(def_id_a, args_a), &ty::CoroutineWitness(def_id_b, args_b))
+            if def_id_a == def_id_b =>
+        {
+            let mut types_a = args_a.types();
+            let mut types_b = args_b.types();
+            loop {
+                match (types_a.next(), types_b.next()) {
+                    (Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
+                    (None, None) => return,
+                    (Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty),
+                }
+            }
+        }
         (ty::Param(_), _) | (_, ty::Param(_)) if fx.tcx.sess.opts.unstable_opts.polymorphize => {
             // No way to check if it is correct or not with polymorphization enabled
         }