about summary refs log tree commit diff
diff options
context:
space:
mode:
authorArpad Borsos <swatinem@swatinem.de>2022-11-29 23:17:08 +0100
committerArpad Borsos <swatinem@swatinem.de>2022-12-08 23:27:57 +0100
commitecf812777a260e35ec9cd0c7d9dbd17a3f5cf5f9 (patch)
treea2bd1e3681603ee9730d2dde8658662d353e71e2
parent7632db0e87d8adccc9a83a47795c9411b1455855 (diff)
downloadrust-ecf812777a260e35ec9cd0c7d9dbd17a3f5cf5f9.tar.gz
rust-ecf812777a260e35ec9cd0c7d9dbd17a3f5cf5f9.zip
Fix Async Generator ABI
This change was missed when making async generators implement `Future` directly.
It did not cause any problems in codegen so far, as `GeneratorState<(), Output>`
happens to have the same ABI as `Poll<Output>`.
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs22
1 files changed, 17 insertions, 5 deletions
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index 73c7eb6992f..d644cbccea1 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -85,7 +85,7 @@ fn fn_sig_for_fn_abi<'tcx>(
                 bound_vars,
             )
         }
-        ty::Generator(_, substs, _) => {
+        ty::Generator(did, substs, _) => {
             let sig = substs.as_generator().poly_sig();
 
             let bound_vars = tcx.mk_bound_variable_kinds(
@@ -104,10 +104,22 @@ fn fn_sig_for_fn_abi<'tcx>(
             let env_ty = tcx.mk_adt(pin_adt_ref, pin_substs);
 
             let sig = sig.skip_binder();
-            let state_did = tcx.require_lang_item(LangItem::GeneratorState, None);
-            let state_adt_ref = tcx.adt_def(state_did);
-            let state_substs = tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]);
-            let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
+            // The `FnSig` and the `ret_ty` here is for a generators main
+            // `Generator::resume(...) -> GeneratorState` function in case we
+            // have an ordinary generator, or the `Future::poll(...) -> Poll`
+            // function in case this is a special generator backing an async construct.
+            let ret_ty = if tcx.generator_is_async(did) {
+                let state_did = tcx.require_lang_item(LangItem::Poll, None);
+                let state_adt_ref = tcx.adt_def(state_did);
+                let state_substs = tcx.intern_substs(&[sig.return_ty.into()]);
+                tcx.mk_adt(state_adt_ref, state_substs)
+            } else {
+                let state_did = tcx.require_lang_item(LangItem::GeneratorState, None);
+                let state_adt_ref = tcx.adt_def(state_did);
+                let state_substs = tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]);
+                tcx.mk_adt(state_adt_ref, state_substs)
+            };
+
             ty::Binder::bind_with_vars(
                 tcx.mk_fn_sig(
                     [env_ty, sig.resume_ty].iter(),