about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-02-07 16:06:52 +0000
committerMichael Goulet <michael@errs.io>2024-02-07 16:18:31 +0000
commitdcca9a12cdda3be34ed74beca05d72c77d797e7f (patch)
tree4c4d6e481fedab322aa8729f9e96ff8cc2278660
parentd6c46a23ce19e910225abacc33bcca9d0f549148 (diff)
downloadrust-dcca9a12cdda3be34ed74beca05d72c77d797e7f.tar.gz
rust-dcca9a12cdda3be34ed74beca05d72c77d797e7f.zip
Record coroutine kind in generics
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs13
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs9
-rw-r--r--tests/ui/coroutine/polymorphize-args.rs17
3 files changed, 35 insertions, 4 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 1dabb6feb5e..4860555de20 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -344,11 +344,18 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
         kind: hir::ExprKind::Closure(hir::Closure { kind, .. }), ..
     }) = node
     {
+        // See `ClosureArgsParts`, `CoroutineArgsParts`, and `CoroutineClosureArgsParts`
+        // for info on the usage of each of these fields.
         let dummy_args = match kind {
             ClosureKind::Closure => &["<closure_kind>", "<closure_signature>", "<upvars>"][..],
-            ClosureKind::Coroutine(_) => {
-                &["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..]
-            }
+            ClosureKind::Coroutine(_) => &[
+                "<coroutine_kind>",
+                "<resume_ty>",
+                "<yield_ty>",
+                "<return_ty>",
+                "<witness>",
+                "<upvars>",
+            ][..],
             ClosureKind::CoroutineClosure(_) => &[
                 "<closure_kind>",
                 "<closure_signature_parts>",
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 9c1f4b20d2c..8848d216f5b 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -765,7 +765,14 @@ fn polymorphize<'tcx>(
     let def_id = instance.def_id();
     let upvars_ty = match tcx.type_of(def_id).skip_binder().kind() {
         ty::Closure(..) => Some(args.as_closure().tupled_upvars_ty()),
-        ty::Coroutine(..) => Some(args.as_coroutine().tupled_upvars_ty()),
+        ty::Coroutine(..) => {
+            assert_eq!(
+                args.as_coroutine().kind_ty(),
+                tcx.types.unit,
+                "polymorphization does not support coroutines from async closures"
+            );
+            Some(args.as_coroutine().tupled_upvars_ty())
+        }
         _ => None,
     };
     let has_upvars = upvars_ty.is_some_and(|ty| !ty.tuple_fields().is_empty());
diff --git a/tests/ui/coroutine/polymorphize-args.rs b/tests/ui/coroutine/polymorphize-args.rs
new file mode 100644
index 00000000000..de44d667656
--- /dev/null
+++ b/tests/ui/coroutine/polymorphize-args.rs
@@ -0,0 +1,17 @@
+// compile-flags: -Zpolymorphize=on
+// build-pass
+
+#![feature(coroutines, coroutine_trait)]
+
+use std::ops::Coroutine;
+use std::pin::Pin;
+use std::thread;
+
+fn main() {
+    let mut foo = || yield;
+    thread::spawn(move || match Pin::new(&mut foo).resume(()) {
+        s => panic!("bad state: {:?}", s),
+    })
+    .join()
+    .unwrap();
+}