@@ -145,8 +145,6 @@ fn fn_sig_for_fn_abi<'tcx>(
145
145
)
146
146
}
147
147
ty::Coroutine(did, args) => {
148
- // FIXME(async_closures): This isn't right for `CoroutineKindShim`.
149
-
150
148
let coroutine_kind = tcx.coroutine_kind(did).unwrap();
151
149
let sig = args.as_coroutine().sig();
152
150
@@ -157,6 +155,40 @@ fn fn_sig_for_fn_abi<'tcx>(
157
155
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
158
156
kind: ty::BoundRegionKind::BrEnv,
159
157
};
158
+
159
+ let mut ty = ty;
160
+ // When this `Closure` comes from a `CoroutineKindShim`,
161
+ // make sure we respect the `target_kind` in that shim.
162
+ // FIXME(async_closures): This shouldn't be needed, and we should be populating
163
+ // a separate def-id for these bodies.
164
+ if let InstanceDef::CoroutineKindShim { target_kind, .. } = instance.def {
165
+ // Grab the parent coroutine-closure. It has the same args for the purposes
166
+ // of substitution, so this will be okay to do.
167
+ let ty::CoroutineClosure(_, coroutine_closure_args) = *tcx
168
+ .instantiate_and_normalize_erasing_regions(
169
+ args,
170
+ param_env,
171
+ tcx.type_of(tcx.parent(did)),
172
+ )
173
+ .kind()
174
+ else {
175
+ bug!("CoroutineKindShim comes from calling a coroutine-closure");
176
+ };
177
+ let coroutine_closure_args = coroutine_closure_args.as_coroutine_closure();
178
+ ty = tcx.instantiate_bound_regions_with_erased(
179
+ coroutine_closure_args.coroutine_closure_sig().map_bound(|sig| {
180
+ sig.to_coroutine_given_kind_and_upvars(
181
+ tcx,
182
+ coroutine_closure_args.parent_args(),
183
+ did,
184
+ target_kind,
185
+ tcx.lifetimes.re_erased,
186
+ coroutine_closure_args.tupled_upvars_ty(),
187
+ coroutine_closure_args.coroutine_captures_by_ref_ty(),
188
+ )
189
+ }),
190
+ );
191
+ }
160
192
let env_ty = Ty::new_mut_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), ty);
161
193
162
194
let pin_did = tcx.require_lang_item(LangItem::Pin, None);
0 commit comments