Auto merge of #120717 - compiler-errors:cap-closure-kind, r=oli-obk

For async closures, cap closure kind, get rid of `by_mut_body`

Right now we have three `AsyncFn*` traits, and three corresponding futures that are returned by the `call_*` functions for them. This is fine, but it is a bit excessive, since the future returned by `AsyncFn` and `AsyncFnMut` are identical. Really, the only distinction we need to make with these bodies is "by ref" and "by move".

This PR removes `AsyncFn::CallFuture` and renames `AsyncFnMut::CallMutFuture` to `AsyncFnMut::CallRefFuture`. This simplifies MIR building for async closures, since we don't need to build an extra "by mut" body, but just a "by move" body which is materially different.

We need to do a bit of delicate handling of the ClosureKind for async closures, since we need to "cap" it to `AsyncFnMut` in some cases when we only care about what body we're looking for.

This also fixes a bug where `<{async closure} as Fn>::call` was returning a body that takes the async-closure receiver *by move*.

This also helps align the `AsyncFn` traits to the `LendingFn` traits' eventual designs.
This commit is contained in:
bors 2024-03-20 11:40:45 +00:00
commit c86f3ac24f
35 changed files with 192 additions and 429 deletions

View file

@ -414,7 +414,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
),
output_coroutine_ty.into(),
),
sym::CallMutFuture | sym::CallFuture => (
sym::CallRefFuture => (
ty::AliasTy::new(
tcx,
goal.predicate.def_id(),

View file

@ -1726,7 +1726,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
let sig = args.coroutine_closure_sig().skip_binder();
let term = match item_name {
sym::CallOnceFuture | sym::CallMutFuture | sym::CallFuture => {
sym::CallOnceFuture | sym::CallRefFuture => {
if let Some(closure_kind) = kind_ty.to_opt_closure_kind() {
if !closure_kind.extends(goal_kind) {
bug!("we should not be confirming if the closure kind is not met");
@ -1787,7 +1787,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
obligation.predicate.def_id,
[self_ty, sig.tupled_inputs_ty],
),
sym::CallMutFuture | sym::CallFuture => ty::AliasTy::new(
sym::CallRefFuture => ty::AliasTy::new(
tcx,
obligation.predicate.def_id,
[ty::GenericArg::from(self_ty), sig.tupled_inputs_ty.into(), env_region.into()],
@ -1803,7 +1803,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
let sig = bound_sig.skip_binder();
let term = match item_name {
sym::CallOnceFuture | sym::CallMutFuture | sym::CallFuture => sig.output(),
sym::CallOnceFuture | sym::CallRefFuture => sig.output(),
sym::Output => {
let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
let future_output_def_id = tcx
@ -1822,7 +1822,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
obligation.predicate.def_id,
[self_ty, Ty::new_tup(tcx, sig.inputs())],
),
sym::CallMutFuture | sym::CallFuture => ty::AliasTy::new(
sym::CallRefFuture => ty::AliasTy::new(
tcx,
obligation.predicate.def_id,
[
@ -1842,7 +1842,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
let sig = bound_sig.skip_binder();
let term = match item_name {
sym::CallOnceFuture | sym::CallMutFuture | sym::CallFuture => sig.output(),
sym::CallOnceFuture | sym::CallRefFuture => sig.output(),
sym::Output => {
let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
let future_output_def_id = tcx
@ -1859,7 +1859,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
sym::CallOnceFuture | sym::Output => {
ty::AliasTy::new(tcx, obligation.predicate.def_id, [self_ty, sig.inputs()[0]])
}
sym::CallMutFuture | sym::CallFuture => ty::AliasTy::new(
sym::CallRefFuture => ty::AliasTy::new(
tcx,
obligation.predicate.def_id,
[ty::GenericArg::from(self_ty), sig.inputs()[0].into(), env_region.into()],