1
Fork 0

Only split by-ref/by-move futures for async closures

This commit is contained in:
Michael Goulet 2024-02-13 15:29:50 +00:00
parent e760daa6a7
commit 05116c5c30
33 changed files with 119 additions and 432 deletions

View file

@ -102,6 +102,7 @@ fn fn_sig_for_fn_abi<'tcx>(
)
}
ty::CoroutineClosure(def_id, args) => {
let coroutine_ty = Ty::new_coroutine_closure(tcx, def_id, args);
let sig = args.as_coroutine_closure().coroutine_closure_sig();
let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
sig.bound_vars().iter().chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))),
@ -111,18 +112,17 @@ fn fn_sig_for_fn_abi<'tcx>(
kind: ty::BoundRegionKind::BrEnv,
};
let env_region = ty::Region::new_bound(tcx, ty::INNERMOST, br);
// When this `CoroutineClosure` comes from a `ConstructCoroutineInClosureShim`,
// 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.
let mut kind = args.as_coroutine_closure().kind();
if let InstanceDef::ConstructCoroutineInClosureShim { target_kind, .. } = instance.def {
kind = target_kind;
let mut coroutine_kind = args.as_coroutine_closure().kind();
if let InstanceDef::ConstructCoroutineInClosureShim { .. } = instance.def {
coroutine_kind = ty::ClosureKind::FnOnce;
}
let env_ty =
tcx.closure_env_ty(Ty::new_coroutine_closure(tcx, def_id, args), kind, env_region);
let env_ty = tcx.closure_env_ty(coroutine_ty, coroutine_kind, env_region);
let sig = sig.skip_binder();
ty::Binder::bind_with_vars(
@ -132,7 +132,7 @@ fn fn_sig_for_fn_abi<'tcx>(
tcx,
args.as_coroutine_closure().parent_args(),
tcx.coroutine_for_closure(def_id),
kind,
coroutine_kind,
env_region,
args.as_coroutine_closure().tupled_upvars_ty(),
args.as_coroutine_closure().coroutine_captures_by_ref_ty(),
@ -161,7 +161,7 @@ fn fn_sig_for_fn_abi<'tcx>(
// 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 {
if let InstanceDef::CoroutineKindShim { .. } = instance.def {
// Grab the parent coroutine-closure. It has the same args for the purposes
// of instantiation, so this will be okay to do.
let ty::CoroutineClosure(_, coroutine_closure_args) = *tcx
@ -181,7 +181,7 @@ fn fn_sig_for_fn_abi<'tcx>(
tcx,
coroutine_closure_args.parent_args(),
did,
target_kind,
ty::ClosureKind::FnOnce,
tcx.lifetimes.re_erased,
coroutine_closure_args.tupled_upvars_ty(),
coroutine_closure_args.coroutine_captures_by_ref_ty(),

View file

@ -282,7 +282,6 @@ fn resolve_associated_item<'tcx>(
Some(Instance {
def: ty::InstanceDef::ConstructCoroutineInClosureShim {
coroutine_closure_def_id,
target_kind: ty::ClosureKind::FnOnce,
},
args,
})
@ -297,25 +296,19 @@ fn resolve_associated_item<'tcx>(
{
match *rcvr_args.type_at(0).kind() {
ty::CoroutineClosure(coroutine_closure_def_id, args) => {
match (target_kind, args.as_coroutine_closure().kind()) {
(ClosureKind::FnOnce | ClosureKind::FnMut, ClosureKind::Fn)
| (ClosureKind::FnOnce, ClosureKind::FnMut) => {
// If we're computing `AsyncFnOnce`/`AsyncFnMut` for a by-ref closure,
// or `AsyncFnOnce` for a by-mut closure, then construct a new body that
// has the right return types.
//
// Specifically, `AsyncFnMut` for a by-ref coroutine-closure just needs
// to have its input and output types fixed (`&mut self` and returning
// `i16` coroutine kind).
Some(Instance {
def: ty::InstanceDef::ConstructCoroutineInClosureShim {
coroutine_closure_def_id,
target_kind,
},
args,
})
}
_ => Some(Instance::new(coroutine_closure_def_id, args)),
if target_kind == ClosureKind::FnOnce
&& args.as_coroutine_closure().kind() != ClosureKind::FnOnce
{
// If we're computing `AsyncFnOnce` for a by-ref closure then
// construct a new body that has the right return types.
Some(Instance {
def: ty::InstanceDef::ConstructCoroutineInClosureShim {
coroutine_closure_def_id,
},
args,
})
} else {
Some(Instance::new(coroutine_closure_def_id, args))
}
}
ty::Closure(closure_def_id, args) => {