about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-02-06 02:53:06 +0000
committerMichael Goulet <michael@errs.io>2024-02-06 02:53:06 +0000
commited7fca1f8805b4348b801f23f444e0dda42f7aed (patch)
treef5d5d55b9747dce921cb3829078082122da0a51d
parent827bfe4154a9679a173755bb2098b863ef890f70 (diff)
downloadrust-ed7fca1f8805b4348b801f23f444e0dda42f7aed.tar.gz
rust-ed7fca1f8805b4348b801f23f444e0dda42f7aed.zip
Fudge coroutine argument for CoroutineKindShim in fn_sig_for_fn_abi
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs36
-rw-r--r--tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.stderr1
-rw-r--r--tests/ui/async-await/async-closures/async-fn-once-for-async-fn.stderr1
3 files changed, 34 insertions, 4 deletions
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index 7b95b4d03a6..0542ef4ecf9 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -145,8 +145,6 @@ fn fn_sig_for_fn_abi<'tcx>(
             )
         }
         ty::Coroutine(did, args) => {
-            // FIXME(async_closures): This isn't right for `CoroutineKindShim`.
-
             let coroutine_kind = tcx.coroutine_kind(did).unwrap();
             let sig = args.as_coroutine().sig();
 
@@ -157,6 +155,40 @@ fn fn_sig_for_fn_abi<'tcx>(
                 var: ty::BoundVar::from_usize(bound_vars.len() - 1),
                 kind: ty::BoundRegionKind::BrEnv,
             };
+
+            let mut ty = ty;
+            // When this `Closure` comes from a `CoroutineKindShim`,
+            // make sure we respect the `target_kind` in that shim.
+            // FIXME(async_closures): This shouldn't be needed, and we should be populating
+            // a separate def-id for these bodies.
+            if let InstanceDef::CoroutineKindShim { target_kind, .. } = instance.def {
+                // Grab the parent coroutine-closure. It has the same args for the purposes
+                // of substitution, so this will be okay to do.
+                let ty::CoroutineClosure(_, coroutine_closure_args) = *tcx
+                    .instantiate_and_normalize_erasing_regions(
+                        args,
+                        param_env,
+                        tcx.type_of(tcx.parent(did)),
+                    )
+                    .kind()
+                else {
+                    bug!("CoroutineKindShim comes from calling a coroutine-closure");
+                };
+                let coroutine_closure_args = coroutine_closure_args.as_coroutine_closure();
+                ty = tcx.instantiate_bound_regions_with_erased(
+                    coroutine_closure_args.coroutine_closure_sig().map_bound(|sig| {
+                        sig.to_coroutine_given_kind_and_upvars(
+                            tcx,
+                            coroutine_closure_args.parent_args(),
+                            did,
+                            target_kind,
+                            tcx.lifetimes.re_erased,
+                            coroutine_closure_args.tupled_upvars_ty(),
+                            coroutine_closure_args.coroutine_captures_by_ref_ty(),
+                        )
+                    }),
+                );
+            }
             let env_ty = Ty::new_mut_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), ty);
 
             let pin_did = tcx.require_lang_item(LangItem::Pin, None);
diff --git a/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.stderr b/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.stderr
deleted file mode 100644
index 48917e8b23f..00000000000
--- a/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.stderr
+++ /dev/null
@@ -1 +0,0 @@
-WARN rustc_codegen_ssa::mir::locals Unexpected initial operand type: expected std::pin::Pin<&ReErased mut Coroutine(DefId(0:8 ~ async_fn_mut_for_async_fn[3241]::main::{closure#0}::{closure#0}::{closure#0}), [i16, std::future::ResumeTy, (), (), CoroutineWitness(DefId(0:8 ~ async_fn_mut_for_async_fn[3241]::main::{closure#0}::{closure#0}::{closure#0}), []), ()])>, found std::pin::Pin<&ReErased mut Coroutine(DefId(0:8 ~ async_fn_mut_for_async_fn[3241]::main::{closure#0}::{closure#0}::{closure#0}), [i8, std::future::ResumeTy, (), (), CoroutineWitness(DefId(0:8 ~ async_fn_mut_for_async_fn[3241]::main::{closure#0}::{closure#0}::{closure#0}), []), ()])>.See <https://github.com/rust-lang/rust/issues/114858>.
diff --git a/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.stderr b/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.stderr
deleted file mode 100644
index 978a5a653f9..00000000000
--- a/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.stderr
+++ /dev/null
@@ -1 +0,0 @@
-WARN rustc_codegen_ssa::mir::locals Unexpected initial operand type: expected std::pin::Pin<&ReErased mut Coroutine(DefId(0:8 ~ async_fn_once_for_async_fn[6cdf]::main::{closure#0}::{closure#0}::{closure#0}), [i32, std::future::ResumeTy, (), (), CoroutineWitness(DefId(0:8 ~ async_fn_once_for_async_fn[6cdf]::main::{closure#0}::{closure#0}::{closure#0}), []), ()])>, found std::pin::Pin<&ReErased mut Coroutine(DefId(0:8 ~ async_fn_once_for_async_fn[6cdf]::main::{closure#0}::{closure#0}::{closure#0}), [i8, std::future::ResumeTy, (), (), CoroutineWitness(DefId(0:8 ~ async_fn_once_for_async_fn[6cdf]::main::{closure#0}::{closure#0}::{closure#0}), []), ()])>.See <https://github.com/rust-lang/rust/issues/114858>.