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 fn jit_bin(config: &'static str, source: &'static str, args: &'static str) 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::(); +} + +fn run_coroutine() { + 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 }