about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/type_check/input_output.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs12
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs6
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs18
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs17
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs35
-rw-r--r--compiler/rustc_mir_transform/src/pass_manager.rs3
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs98
-rw-r--r--compiler/rustc_span/src/symbol.rs3
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs14
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs8
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs12
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs18
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs33
-rw-r--r--library/alloc/src/boxed.rs8
-rw-r--r--library/core/src/ops/async_function.rs30
-rw-r--r--src/doc/unstable-book/src/library-features/async-fn-traits.md2
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir2
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir2
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-abort.mir47
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-unwind.mir47
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir6
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir6
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-abort.mir16
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-unwind.mir16
-rw-r--r--tests/mir-opt/async_closure_shims.rs2
-rw-r--r--tests/ui/async-await/async-closures/def-path.stderr4
-rw-r--r--tests/ui/async-await/async-fn/dyn-pos.rs3
-rw-r--r--tests/ui/async-await/async-fn/dyn-pos.stderr57
33 files changed, 119 insertions, 432 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs
index 575aab47ac7..a4c1066ee8e 100644
--- a/compiler/rustc_borrowck/src/type_check/input_output.rs
+++ b/compiler/rustc_borrowck/src/type_check/input_output.rs
@@ -87,7 +87,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     self.tcx(),
                     ty::CoroutineArgsParts {
                         parent_args: args.parent_args(),
-                        kind_ty: Ty::from_closure_kind(self.tcx(), args.kind()),
+                        kind_ty: Ty::from_coroutine_closure_kind(self.tcx(), args.kind()),
                         return_ty: user_provided_sig.output(),
                         tupled_upvars_ty,
                         // For async closures, none of these can be annotated, so just fill
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 9a500fa712b..0e75a47683d 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -184,16 +184,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     kind: TypeVariableOriginKind::TypeInference,
                     span: callee_expr.span,
                 });
+                // We may actually receive a coroutine back whose kind is different
+                // from the closure that this dispatched from. This is because when
+                // we have no captures, we automatically implement `FnOnce`. This
+                // impl forces the closure kind to `FnOnce` i.e. `u8`.
+                let kind_ty = self.next_ty_var(TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::TypeInference,
+                    span: callee_expr.span,
+                });
                 let call_sig = self.tcx.mk_fn_sig(
                     [coroutine_closure_sig.tupled_inputs_ty],
                     coroutine_closure_sig.to_coroutine(
                         self.tcx,
                         closure_args.parent_args(),
-                        // Inherit the kind ty of the closure, since we're calling this
-                        // coroutine with the most relaxed `AsyncFn*` trait that we can.
-                        // We don't necessarily need to do this here, but it saves us
-                        // computing one more infer var that will get constrained later.
-                        closure_args.kind_ty(),
+                        kind_ty,
                         self.tcx.coroutine_for_closure(def_id),
                         tupled_upvars_ty,
                     ),
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index 4bea4bb3e82..6e30cb02245 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -262,6 +262,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     },
                 );
 
+                let coroutine_kind_ty = self.next_ty_var(TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::ClosureSynthetic,
+                    span: expr_span,
+                });
                 let coroutine_upvars_ty = self.next_ty_var(TypeVariableOrigin {
                     kind: TypeVariableOriginKind::ClosureSynthetic,
                     span: expr_span,
@@ -279,7 +283,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         sig.to_coroutine(
                             tcx,
                             parent_args,
-                            closure_kind_ty,
+                            coroutine_kind_ty,
                             tcx.coroutine_for_closure(expr_def_id),
                             coroutine_upvars_ty,
                         )
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index be14f5bf0d8..b71e88a1579 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -410,7 +410,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.demand_eqtype(
                 span,
                 coroutine_args.as_coroutine().kind_ty(),
-                Ty::from_closure_kind(self.tcx, closure_kind),
+                Ty::from_coroutine_closure_kind(self.tcx, closure_kind),
             );
         }
 
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index d57ffc0f8b5..984d4687ef8 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -278,13 +278,6 @@ pub struct CoroutineInfo<'tcx> {
     /// using `run_passes`.
     pub by_move_body: Option<Body<'tcx>>,
 
-    /// The body of the coroutine, modified to take its upvars by mutable ref rather than by
-    /// immutable ref.
-    ///
-    /// FIXME(async_closures): This is literally the same body as the parent body. Find a better
-    /// way to represent the by-mut signature (or cap the closure-kind of the coroutine).
-    pub by_mut_body: Option<Body<'tcx>>,
-
     /// The layout of a coroutine. This field is populated after the state transform pass.
     pub coroutine_layout: Option<CoroutineLayout<'tcx>>,
 
@@ -305,7 +298,6 @@ impl<'tcx> CoroutineInfo<'tcx> {
             yield_ty: Some(yield_ty),
             resume_ty: Some(resume_ty),
             by_move_body: None,
-            by_mut_body: None,
             coroutine_drop: None,
             coroutine_layout: None,
         }
@@ -628,10 +620,6 @@ impl<'tcx> Body<'tcx> {
         self.coroutine.as_ref()?.by_move_body.as_ref()
     }
 
-    pub fn coroutine_by_mut_body(&self) -> Option<&Body<'tcx>> {
-        self.coroutine.as_ref()?.by_mut_body.as_ref()
-    }
-
     #[inline]
     pub fn coroutine_kind(&self) -> Option<CoroutineKind> {
         self.coroutine.as_ref().map(|coroutine| coroutine.coroutine_kind)
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 845b1717550..562aed5a643 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -345,8 +345,10 @@ macro_rules! make_mir_visitor {
                         ty::InstanceDef::Virtual(_def_id, _) |
                         ty::InstanceDef::ThreadLocalShim(_def_id) |
                         ty::InstanceDef::ClosureOnceShim { call_once: _def_id, track_caller: _ } |
-                        ty::InstanceDef::ConstructCoroutineInClosureShim { coroutine_closure_def_id: _def_id, target_kind: _ } |
-                        ty::InstanceDef::CoroutineKindShim { coroutine_def_id: _def_id, target_kind: _ } |
+                        ty::InstanceDef::ConstructCoroutineInClosureShim {
+                            coroutine_closure_def_id: _def_id,
+                        } |
+                        ty::InstanceDef::CoroutineKindShim { coroutine_def_id: _def_id } |
                         ty::InstanceDef::DropGlue(_def_id, None) => {}
 
                         ty::InstanceDef::FnPtrShim(_def_id, ty) |
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 814c3629b08..bbe0915baa2 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -90,16 +90,12 @@ pub enum InstanceDef<'tcx> {
     /// and dispatch to the `FnMut::call_mut` instance for the closure.
     ClosureOnceShim { call_once: DefId, track_caller: bool },
 
-    /// `<[FnMut/Fn coroutine-closure] as FnOnce>::call_once` or
-    /// `<[Fn coroutine-closure] as FnMut>::call_mut`.
+    /// `<[FnMut/Fn coroutine-closure] as FnOnce>::call_once`
     ///
     /// The body generated here differs significantly from the `ClosureOnceShim`,
     /// since we need to generate a distinct coroutine type that will move the
     /// closure's upvars *out* of the closure.
-    ConstructCoroutineInClosureShim {
-        coroutine_closure_def_id: DefId,
-        target_kind: ty::ClosureKind,
-    },
+    ConstructCoroutineInClosureShim { coroutine_closure_def_id: DefId },
 
     /// `<[coroutine] as Future>::poll`, but for coroutines produced when `AsyncFnOnce`
     /// is called on a coroutine-closure whose closure kind greater than `FnOnce`, or
@@ -107,7 +103,7 @@ pub enum InstanceDef<'tcx> {
     ///
     /// This will select the body that is produced by the `ByMoveBody` transform, and thus
     /// take and use all of its upvars by-move rather than by-ref.
-    CoroutineKindShim { coroutine_def_id: DefId, target_kind: ty::ClosureKind },
+    CoroutineKindShim { coroutine_def_id: DefId },
 
     /// Compiler-generated accessor for thread locals which returns a reference to the thread local
     /// the `DefId` defines. This is used to export thread locals from dylibs on platforms lacking
@@ -192,9 +188,8 @@ impl<'tcx> InstanceDef<'tcx> {
             | InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ }
             | ty::InstanceDef::ConstructCoroutineInClosureShim {
                 coroutine_closure_def_id: def_id,
-                target_kind: _,
             }
-            | ty::InstanceDef::CoroutineKindShim { coroutine_def_id: def_id, target_kind: _ }
+            | ty::InstanceDef::CoroutineKindShim { coroutine_def_id: def_id }
             | InstanceDef::DropGlue(def_id, _)
             | InstanceDef::CloneShim(def_id, _)
             | InstanceDef::FnPtrAddrShim(def_id, _) => def_id,
@@ -651,10 +646,7 @@ impl<'tcx> Instance<'tcx> {
                 Some(Instance { def: ty::InstanceDef::Item(coroutine_def_id), args })
             } else {
                 Some(Instance {
-                    def: ty::InstanceDef::CoroutineKindShim {
-                        coroutine_def_id,
-                        target_kind: args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap(),
-                    },
+                    def: ty::InstanceDef::CoroutineKindShim { coroutine_def_id },
                     args,
                 })
             }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 540936d7d8a..67908013041 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -483,7 +483,7 @@ impl<'tcx> CoroutineClosureSignature<'tcx> {
         self.to_coroutine(
             tcx,
             parent_args,
-            Ty::from_closure_kind(tcx, goal_kind),
+            Ty::from_coroutine_closure_kind(tcx, goal_kind),
             coroutine_def_id,
             tupled_upvars_ty,
         )
@@ -2456,6 +2456,21 @@ impl<'tcx> Ty<'tcx> {
         }
     }
 
+    /// Like [`Ty::to_opt_closure_kind`], but it caps the "maximum" closure kind
+    /// to `FnMut`. This is because although we have three capability states,
+    /// `AsyncFn`/`AsyncFnMut`/`AsyncFnOnce`, we only need to distinguish two coroutine
+    /// bodies: by-ref and by-value.
+    ///
+    /// This method should be used when constructing a `Coroutine` out of a
+    /// `CoroutineClosure`, when the `Coroutine`'s `kind` field is being populated
+    /// directly from the `CoroutineClosure`'s `kind`.
+    pub fn from_coroutine_closure_kind(tcx: TyCtxt<'tcx>, kind: ty::ClosureKind) -> Ty<'tcx> {
+        match kind {
+            ty::ClosureKind::Fn | ty::ClosureKind::FnMut => tcx.types.i16,
+            ty::ClosureKind::FnOnce => tcx.types.i32,
+        }
+    }
+
     /// Fast path helper for testing if a type is `Sized`.
     ///
     /// Returning true means the type is known to be sized. Returning
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index e40f4520671..000b96ee801 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -67,45 +67,10 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
         by_move_body.source = mir::MirSource {
             instance: InstanceDef::CoroutineKindShim {
                 coroutine_def_id: coroutine_def_id.to_def_id(),
-                target_kind: ty::ClosureKind::FnOnce,
             },
             promoted: None,
         };
         body.coroutine.as_mut().unwrap().by_move_body = Some(by_move_body);
-
-        // If this is coming from an `AsyncFn` coroutine-closure, we must also create a by-mut body.
-        // This is actually just a copy of the by-ref body, but with a different self type.
-        // FIXME(async_closures): We could probably unify this with the by-ref body somehow.
-        if coroutine_kind == ty::ClosureKind::Fn {
-            let by_mut_coroutine_ty = Ty::new_coroutine(
-                tcx,
-                coroutine_def_id.to_def_id(),
-                ty::CoroutineArgs::new(
-                    tcx,
-                    ty::CoroutineArgsParts {
-                        parent_args: args.as_coroutine().parent_args(),
-                        kind_ty: Ty::from_closure_kind(tcx, ty::ClosureKind::FnMut),
-                        resume_ty: args.as_coroutine().resume_ty(),
-                        yield_ty: args.as_coroutine().yield_ty(),
-                        return_ty: args.as_coroutine().return_ty(),
-                        witness: args.as_coroutine().witness(),
-                        tupled_upvars_ty: args.as_coroutine().tupled_upvars_ty(),
-                    },
-                )
-                .args,
-            );
-            let mut by_mut_body = body.clone();
-            by_mut_body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty = by_mut_coroutine_ty;
-            dump_mir(tcx, false, "coroutine_by_mut", &0, &by_mut_body, |_, _| Ok(()));
-            by_mut_body.source = mir::MirSource {
-                instance: InstanceDef::CoroutineKindShim {
-                    coroutine_def_id: coroutine_def_id.to_def_id(),
-                    target_kind: ty::ClosureKind::FnMut,
-                },
-                promoted: None,
-            };
-            body.coroutine.as_mut().unwrap().by_mut_body = Some(by_mut_body);
-        }
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs
index 77478cc741d..17a1c3c7157 100644
--- a/compiler/rustc_mir_transform/src/pass_manager.rs
+++ b/compiler/rustc_mir_transform/src/pass_manager.rs
@@ -186,9 +186,6 @@ fn run_passes_inner<'tcx>(
         if let Some(by_move_body) = coroutine.by_move_body.as_mut() {
             run_passes_inner(tcx, by_move_body, passes, phase_change, validate_each);
         }
-        if let Some(by_mut_body) = coroutine.by_mut_body.as_mut() {
-            run_passes_inner(tcx, by_mut_body, passes, phase_change, validate_each);
-        }
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 733e2f93b25..3efaa69a7e7 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -3,8 +3,8 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_middle::mir::*;
 use rustc_middle::query::Providers;
+use rustc_middle::ty::GenericArgs;
 use rustc_middle::ty::{self, CoroutineArgs, EarlyBinder, Ty, TyCtxt};
-use rustc_middle::ty::{GenericArgs, CAPTURE_STRUCT_LOCAL};
 use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
 
 use rustc_index::{Idx, IndexVec};
@@ -70,39 +70,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
             build_call_shim(tcx, instance, Some(Adjustment::RefMut), CallKind::Direct(call_mut))
         }
 
-        ty::InstanceDef::ConstructCoroutineInClosureShim {
-            coroutine_closure_def_id,
-            target_kind,
-        } => match target_kind {
-            ty::ClosureKind::Fn => unreachable!("shouldn't be building shim for Fn"),
-            ty::ClosureKind::FnMut => {
-                // No need to optimize the body, it has already been optimized
-                // since we steal it from the `AsyncFn::call` body and just fix
-                // the return type.
-                return build_construct_coroutine_by_mut_shim(tcx, coroutine_closure_def_id);
-            }
-            ty::ClosureKind::FnOnce => {
-                build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id)
-            }
-        },
+        ty::InstanceDef::ConstructCoroutineInClosureShim { coroutine_closure_def_id } => {
+            build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id)
+        }
 
-        ty::InstanceDef::CoroutineKindShim { coroutine_def_id, target_kind } => match target_kind {
-            ty::ClosureKind::Fn => unreachable!(),
-            ty::ClosureKind::FnMut => {
-                return tcx
-                    .optimized_mir(coroutine_def_id)
-                    .coroutine_by_mut_body()
-                    .unwrap()
-                    .clone();
-            }
-            ty::ClosureKind::FnOnce => {
-                return tcx
-                    .optimized_mir(coroutine_def_id)
-                    .coroutine_by_move_body()
-                    .unwrap()
-                    .clone();
-            }
-        },
+        ty::InstanceDef::CoroutineKindShim { coroutine_def_id } => {
+            return tcx.optimized_mir(coroutine_def_id).coroutine_by_move_body().unwrap().clone();
+        }
 
         ty::InstanceDef::DropGlue(def_id, ty) => {
             // FIXME(#91576): Drop shims for coroutines aren't subject to the MIR passes at the end
@@ -123,21 +97,11 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
                 let body = if id_args.as_coroutine().kind_ty() == args.as_coroutine().kind_ty() {
                     coroutine_body.coroutine_drop().unwrap()
                 } else {
-                    match args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap() {
-                        ty::ClosureKind::Fn => {
-                            unreachable!()
-                        }
-                        ty::ClosureKind::FnMut => coroutine_body
-                            .coroutine_by_mut_body()
-                            .unwrap()
-                            .coroutine_drop()
-                            .unwrap(),
-                        ty::ClosureKind::FnOnce => coroutine_body
-                            .coroutine_by_move_body()
-                            .unwrap()
-                            .coroutine_drop()
-                            .unwrap(),
-                    }
+                    assert_eq!(
+                        args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap(),
+                        ty::ClosureKind::FnOnce
+                    );
+                    coroutine_body.coroutine_by_move_body().unwrap().coroutine_drop().unwrap()
                 };
 
                 let mut body = EarlyBinder::bind(body.clone()).instantiate(tcx, args);
@@ -1112,7 +1076,6 @@ fn build_construct_coroutine_by_move_shim<'tcx>(
 
     let source = MirSource::from_instance(ty::InstanceDef::ConstructCoroutineInClosureShim {
         coroutine_closure_def_id,
-        target_kind: ty::ClosureKind::FnOnce,
     });
 
     let body =
@@ -1121,40 +1084,3 @@ fn build_construct_coroutine_by_move_shim<'tcx>(
 
     body
 }
-
-fn build_construct_coroutine_by_mut_shim<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    coroutine_closure_def_id: DefId,
-) -> Body<'tcx> {
-    let mut body = tcx.optimized_mir(coroutine_closure_def_id).clone();
-    let coroutine_closure_ty = tcx.type_of(coroutine_closure_def_id).instantiate_identity();
-    let ty::CoroutineClosure(_, args) = *coroutine_closure_ty.kind() else {
-        bug!();
-    };
-    let args = args.as_coroutine_closure();
-
-    body.local_decls[RETURN_PLACE].ty =
-        tcx.instantiate_bound_regions_with_erased(args.coroutine_closure_sig().map_bound(|sig| {
-            sig.to_coroutine_given_kind_and_upvars(
-                tcx,
-                args.parent_args(),
-                tcx.coroutine_for_closure(coroutine_closure_def_id),
-                ty::ClosureKind::FnMut,
-                tcx.lifetimes.re_erased,
-                args.tupled_upvars_ty(),
-                args.coroutine_captures_by_ref_ty(),
-            )
-        }));
-    body.local_decls[CAPTURE_STRUCT_LOCAL].ty =
-        Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, coroutine_closure_ty);
-
-    body.source = MirSource::from_instance(ty::InstanceDef::ConstructCoroutineInClosureShim {
-        coroutine_closure_def_id,
-        target_kind: ty::ClosureKind::FnMut,
-    });
-
-    body.pass_count = 0;
-    dump_mir(tcx, false, "coroutine_closure_by_mut", &0, &body, |_, _| Ok(()));
-
-    body
-}
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 63b950a2803..8b911a41a11 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -166,9 +166,8 @@ symbols! {
         Break,
         C,
         CStr,
-        CallFuture,
-        CallMutFuture,
         CallOnceFuture,
+        CallRefFuture,
         Capture,
         Center,
         Cleanup,
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 83e920e2f8e..1c62ce2d214 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -76,16 +76,10 @@ pub(super) fn mangle<'tcx>(
         }
         // FIXME(async_closures): This shouldn't be needed when we fix
         // `Instance::ty`/`Instance::def_id`.
-        ty::InstanceDef::ConstructCoroutineInClosureShim { target_kind, .. }
-        | ty::InstanceDef::CoroutineKindShim { target_kind, .. } => match target_kind {
-            ty::ClosureKind::Fn => unreachable!(),
-            ty::ClosureKind::FnMut => {
-                printer.write_str("{{fn-mut-shim}}").unwrap();
-            }
-            ty::ClosureKind::FnOnce => {
-                printer.write_str("{{fn-once-shim}}").unwrap();
-            }
-        },
+        ty::InstanceDef::ConstructCoroutineInClosureShim { .. }
+        | ty::InstanceDef::CoroutineKindShim { .. } => {
+            printer.write_str("{{fn-once-shim}}").unwrap();
+        }
         _ => {}
     }
 
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index f1b1b4ed2bb..6bc375512ac 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -46,12 +46,8 @@ pub(super) fn mangle<'tcx>(
         ty::InstanceDef::VTableShim(_) => Some("vtable"),
         ty::InstanceDef::ReifyShim(_) => Some("reify"),
 
-        ty::InstanceDef::ConstructCoroutineInClosureShim { target_kind, .. }
-        | ty::InstanceDef::CoroutineKindShim { target_kind, .. } => match target_kind {
-            ty::ClosureKind::Fn => unreachable!(),
-            ty::ClosureKind::FnMut => Some("fn_mut"),
-            ty::ClosureKind::FnOnce => Some("fn_once"),
-        },
+        ty::InstanceDef::ConstructCoroutineInClosureShim { .. }
+        | ty::InstanceDef::CoroutineKindShim { .. } => Some("fn_once"),
 
         _ => None,
     };
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
index d24bec5a766..85bb6338daf 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
@@ -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(),
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 6756b5dec23..12371155303 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -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()],
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index a5328baadb5..7d54083fbd5 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -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(),
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index 2816bcc888b..c2ea89f4c29 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -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) => {
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index f47fe560b07..cfaf533088a 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -2042,18 +2042,16 @@ impl<Args: Tuple, F: AsyncFnOnce<Args> + ?Sized, A: Allocator> AsyncFnOnce<Args>
 
 #[unstable(feature = "async_fn_traits", issue = "none")]
 impl<Args: Tuple, F: AsyncFnMut<Args> + ?Sized, A: Allocator> AsyncFnMut<Args> for Box<F, A> {
-    type CallMutFuture<'a> = F::CallMutFuture<'a> where Self: 'a;
+    type CallRefFuture<'a> = F::CallRefFuture<'a> where Self: 'a;
 
-    extern "rust-call" fn async_call_mut(&mut self, args: Args) -> Self::CallMutFuture<'_> {
+    extern "rust-call" fn async_call_mut(&mut self, args: Args) -> Self::CallRefFuture<'_> {
         F::async_call_mut(self, args)
     }
 }
 
 #[unstable(feature = "async_fn_traits", issue = "none")]
 impl<Args: Tuple, F: AsyncFn<Args> + ?Sized, A: Allocator> AsyncFn<Args> for Box<F, A> {
-    type CallFuture<'a> = F::CallFuture<'a> where Self: 'a;
-
-    extern "rust-call" fn async_call(&self, args: Args) -> Self::CallFuture<'_> {
+    extern "rust-call" fn async_call(&self, args: Args) -> Self::CallRefFuture<'_> {
         F::async_call(self, args)
     }
 }
diff --git a/library/core/src/ops/async_function.rs b/library/core/src/ops/async_function.rs
index d6b06ffb7fc..6c8a0daf6f3 100644
--- a/library/core/src/ops/async_function.rs
+++ b/library/core/src/ops/async_function.rs
@@ -10,15 +10,9 @@ use crate::marker::Tuple;
 #[must_use = "async closures are lazy and do nothing unless called"]
 #[lang = "async_fn"]
 pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> {
-    /// Future returned by [`AsyncFn::async_call`].
-    #[unstable(feature = "async_fn_traits", issue = "none")]
-    type CallFuture<'a>: Future<Output = Self::Output>
-    where
-        Self: 'a;
-
     /// Call the [`AsyncFn`], returning a future which may borrow from the called closure.
     #[unstable(feature = "async_fn_traits", issue = "none")]
-    extern "rust-call" fn async_call(&self, args: Args) -> Self::CallFuture<'_>;
+    extern "rust-call" fn async_call(&self, args: Args) -> Self::CallRefFuture<'_>;
 }
 
 /// An async-aware version of the [`FnMut`](crate::ops::FnMut) trait.
@@ -30,15 +24,15 @@ pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> {
 #[must_use = "async closures are lazy and do nothing unless called"]
 #[lang = "async_fn_mut"]
 pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
-    /// Future returned by [`AsyncFnMut::async_call_mut`].
+    /// Future returned by [`AsyncFnMut::async_call_mut`] and [`AsyncFn::async_call`].
     #[unstable(feature = "async_fn_traits", issue = "none")]
-    type CallMutFuture<'a>: Future<Output = Self::Output>
+    type CallRefFuture<'a>: Future<Output = Self::Output>
     where
         Self: 'a;
 
     /// Call the [`AsyncFnMut`], returning a future which may borrow from the called closure.
     #[unstable(feature = "async_fn_traits", issue = "none")]
-    extern "rust-call" fn async_call_mut(&mut self, args: Args) -> Self::CallMutFuture<'_>;
+    extern "rust-call" fn async_call_mut(&mut self, args: Args) -> Self::CallRefFuture<'_>;
 }
 
 /// An async-aware version of the [`FnOnce`](crate::ops::FnOnce) trait.
@@ -72,9 +66,7 @@ mod impls {
     where
         F: AsyncFn<A>,
     {
-        type CallFuture<'a> = F::CallFuture<'a> where Self: 'a;
-
-        extern "rust-call" fn async_call(&self, args: A) -> Self::CallFuture<'_> {
+        extern "rust-call" fn async_call(&self, args: A) -> Self::CallRefFuture<'_> {
             F::async_call(*self, args)
         }
     }
@@ -84,9 +76,9 @@ mod impls {
     where
         F: AsyncFn<A>,
     {
-        type CallMutFuture<'a> = F::CallFuture<'a> where Self: 'a;
+        type CallRefFuture<'a> = F::CallRefFuture<'a> where Self: 'a;
 
-        extern "rust-call" fn async_call_mut(&mut self, args: A) -> Self::CallMutFuture<'_> {
+        extern "rust-call" fn async_call_mut(&mut self, args: A) -> Self::CallRefFuture<'_> {
             F::async_call(*self, args)
         }
     }
@@ -97,7 +89,7 @@ mod impls {
         F: AsyncFn<A>,
     {
         type Output = F::Output;
-        type CallOnceFuture = F::CallFuture<'a>;
+        type CallOnceFuture = F::CallRefFuture<'a>;
 
         extern "rust-call" fn async_call_once(self, args: A) -> Self::CallOnceFuture {
             F::async_call(self, args)
@@ -109,9 +101,9 @@ mod impls {
     where
         F: AsyncFnMut<A>,
     {
-        type CallMutFuture<'a> = F::CallMutFuture<'a> where Self: 'a;
+        type CallRefFuture<'a> = F::CallRefFuture<'a> where Self: 'a;
 
-        extern "rust-call" fn async_call_mut(&mut self, args: A) -> Self::CallMutFuture<'_> {
+        extern "rust-call" fn async_call_mut(&mut self, args: A) -> Self::CallRefFuture<'_> {
             F::async_call_mut(*self, args)
         }
     }
@@ -122,7 +114,7 @@ mod impls {
         F: AsyncFnMut<A>,
     {
         type Output = F::Output;
-        type CallOnceFuture = F::CallMutFuture<'a>;
+        type CallOnceFuture = F::CallRefFuture<'a>;
 
         extern "rust-call" fn async_call_once(self, args: A) -> Self::CallOnceFuture {
             F::async_call_mut(self, args)
diff --git a/src/doc/unstable-book/src/library-features/async-fn-traits.md b/src/doc/unstable-book/src/library-features/async-fn-traits.md
index e1c3f067e5b..a0edb3c7dd2 100644
--- a/src/doc/unstable-book/src/library-features/async-fn-traits.md
+++ b/src/doc/unstable-book/src/library-features/async-fn-traits.md
@@ -10,4 +10,4 @@ for creating custom closure-like types that return futures.
 [`AsyncFn*`]: ../../std/ops/trait.AsyncFn.html
 
 The main difference to the `Fn*` family of traits is that `AsyncFn` can return a future
-that borrows from itself (`FnOnce::Output` has no lifetime parameters, while `AsyncFn::CallFuture` does).
+that borrows from itself (`FnOnce::Output` has no lifetime parameters, while `AsyncFnMut::CallRefFuture` does).
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir
index 1fae40c5f40..6ca3dd61005 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir
@@ -1,6 +1,6 @@
 // MIR for `main::{closure#0}::{closure#0}::{closure#0}` 0 coroutine_by_move
 
-fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10}, _2: ResumeTy) -> ()
+fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:37:53: 40:10}, _2: ResumeTy) -> ()
 yields ()
  {
     debug _task_context => _2;
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir
index 1fae40c5f40..6ca3dd61005 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir
@@ -1,6 +1,6 @@
 // MIR for `main::{closure#0}::{closure#0}::{closure#0}` 0 coroutine_by_move
 
-fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10}, _2: ResumeTy) -> ()
+fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:37:53: 40:10}, _2: ResumeTy) -> ()
 yields ()
  {
     debug _task_context => _2;
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-abort.mir
deleted file mode 100644
index 9886d6f68a4..00000000000
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-abort.mir
+++ /dev/null
@@ -1,47 +0,0 @@
-// MIR for `main::{closure#0}::{closure#0}::{closure#0}` 0 coroutine_by_mut
-
-fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10}, _2: ResumeTy) -> ()
-yields ()
- {
-    debug _task_context => _2;
-    debug a => (_1.0: i32);
-    debug b => (*(_1.1: &i32));
-    let mut _0: ();
-    let _3: i32;
-    scope 1 {
-        debug a => _3;
-        let _4: &i32;
-        scope 2 {
-            debug a => _4;
-            let _5: &i32;
-            scope 3 {
-                debug b => _5;
-            }
-        }
-    }
-
-    bb0: {
-        StorageLive(_3);
-        _3 = (_1.0: i32);
-        FakeRead(ForLet(None), _3);
-        StorageLive(_4);
-        _4 = &_3;
-        FakeRead(ForLet(None), _4);
-        StorageLive(_5);
-        _5 = &(*(_1.1: &i32));
-        FakeRead(ForLet(None), _5);
-        _0 = const ();
-        StorageDead(_5);
-        StorageDead(_4);
-        StorageDead(_3);
-        drop(_1) -> [return: bb1, unwind: bb2];
-    }
-
-    bb1: {
-        return;
-    }
-
-    bb2 (cleanup): {
-        resume;
-    }
-}
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-unwind.mir
deleted file mode 100644
index 9886d6f68a4..00000000000
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.panic-unwind.mir
+++ /dev/null
@@ -1,47 +0,0 @@
-// MIR for `main::{closure#0}::{closure#0}::{closure#0}` 0 coroutine_by_mut
-
-fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10}, _2: ResumeTy) -> ()
-yields ()
- {
-    debug _task_context => _2;
-    debug a => (_1.0: i32);
-    debug b => (*(_1.1: &i32));
-    let mut _0: ();
-    let _3: i32;
-    scope 1 {
-        debug a => _3;
-        let _4: &i32;
-        scope 2 {
-            debug a => _4;
-            let _5: &i32;
-            scope 3 {
-                debug b => _5;
-            }
-        }
-    }
-
-    bb0: {
-        StorageLive(_3);
-        _3 = (_1.0: i32);
-        FakeRead(ForLet(None), _3);
-        StorageLive(_4);
-        _4 = &_3;
-        FakeRead(ForLet(None), _4);
-        StorageLive(_5);
-        _5 = &(*(_1.1: &i32));
-        FakeRead(ForLet(None), _5);
-        _0 = const ();
-        StorageDead(_5);
-        StorageDead(_4);
-        StorageDead(_3);
-        drop(_1) -> [return: bb1, unwind: bb2];
-    }
-
-    bb1: {
-        return;
-    }
-
-    bb2 (cleanup): {
-        resume;
-    }
-}
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir
index 21a9f6f8721..b5768e14452 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir
@@ -1,10 +1,10 @@
 // MIR for `main::{closure#0}::{closure#0}` 0 coroutine_closure_by_move
 
-fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:39:33: 39:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10} {
-    let mut _0: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10};
+fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:37:33: 37:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:37:53: 40:10} {
+    let mut _0: {async closure body@$DIR/async_closure_shims.rs:37:53: 40:10};
 
     bb0: {
-        _0 = {coroutine@$DIR/async_closure_shims.rs:39:53: 42:10 (#0)} { a: move _2, b: move (_1.0: i32) };
+        _0 = {coroutine@$DIR/async_closure_shims.rs:37:53: 40:10 (#0)} { a: move _2, b: move (_1.0: i32) };
         return;
     }
 }
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir
index 21a9f6f8721..b5768e14452 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir
@@ -1,10 +1,10 @@
 // MIR for `main::{closure#0}::{closure#0}` 0 coroutine_closure_by_move
 
-fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:39:33: 39:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10} {
-    let mut _0: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10};
+fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:37:33: 37:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:37:53: 40:10} {
+    let mut _0: {async closure body@$DIR/async_closure_shims.rs:37:53: 40:10};
 
     bb0: {
-        _0 = {coroutine@$DIR/async_closure_shims.rs:39:53: 42:10 (#0)} { a: move _2, b: move (_1.0: i32) };
+        _0 = {coroutine@$DIR/async_closure_shims.rs:37:53: 40:10 (#0)} { a: move _2, b: move (_1.0: i32) };
         return;
     }
 }
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-abort.mir
deleted file mode 100644
index 1cfb6c2f3ea..00000000000
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-abort.mir
+++ /dev/null
@@ -1,16 +0,0 @@
-// MIR for `main::{closure#0}::{closure#0}` 0 coroutine_closure_by_mut
-
-fn main::{closure#0}::{closure#0}(_1: &mut {async closure@$DIR/async_closure_shims.rs:39:33: 39:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10} {
-    debug a => _2;
-    debug b => ((*_1).0: i32);
-    let mut _0: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10};
-    let mut _3: &i32;
-
-    bb0: {
-        StorageLive(_3);
-        _3 = &((*_1).0: i32);
-        _0 = {coroutine@$DIR/async_closure_shims.rs:39:53: 42:10 (#0)} { a: _2, b: move _3 };
-        StorageDead(_3);
-        return;
-    }
-}
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-unwind.mir
deleted file mode 100644
index 1cfb6c2f3ea..00000000000
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.panic-unwind.mir
+++ /dev/null
@@ -1,16 +0,0 @@
-// MIR for `main::{closure#0}::{closure#0}` 0 coroutine_closure_by_mut
-
-fn main::{closure#0}::{closure#0}(_1: &mut {async closure@$DIR/async_closure_shims.rs:39:33: 39:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10} {
-    debug a => _2;
-    debug b => ((*_1).0: i32);
-    let mut _0: {async closure body@$DIR/async_closure_shims.rs:39:53: 42:10};
-    let mut _3: &i32;
-
-    bb0: {
-        StorageLive(_3);
-        _3 = &((*_1).0: i32);
-        _0 = {coroutine@$DIR/async_closure_shims.rs:39:53: 42:10 (#0)} { a: _2, b: move _3 };
-        StorageDead(_3);
-        return;
-    }
-}
diff --git a/tests/mir-opt/async_closure_shims.rs b/tests/mir-opt/async_closure_shims.rs
index 5e875321400..47c41ed0500 100644
--- a/tests/mir-opt/async_closure_shims.rs
+++ b/tests/mir-opt/async_closure_shims.rs
@@ -30,8 +30,6 @@ async fn call_once(f: impl AsyncFnOnce(i32)) {
 }
 
 // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir
-// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.mir
-// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.mir
 // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.mir
 pub fn main() {
     block_on(async {
diff --git a/tests/ui/async-await/async-closures/def-path.stderr b/tests/ui/async-await/async-closures/def-path.stderr
index dae45825f37..0a1e30c1253 100644
--- a/tests/ui/async-await/async-closures/def-path.stderr
+++ b/tests/ui/async-await/async-closures/def-path.stderr
@@ -5,11 +5,11 @@ LL |     let x = async || {};
    |                      -- the expected `async` closure body
 LL |
 LL |     let () = x();
-   |         ^^   --- this expression has type `{static main::{closure#0}::{closure#0}<?7t> upvar_tys=?15t witness=?6t}`
+   |         ^^   --- this expression has type `{static main::{closure#0}::{closure#0}<?17t> upvar_tys=?16t witness=?6t}`
    |         |
    |         expected `async` closure body, found `()`
    |
-   = note: expected `async` closure body `{static main::{closure#0}::{closure#0}<?7t> upvar_tys=?15t witness=?6t}`
+   = note: expected `async` closure body `{static main::{closure#0}::{closure#0}<?17t> upvar_tys=?16t witness=?6t}`
                          found unit type `()`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/async-await/async-fn/dyn-pos.rs b/tests/ui/async-await/async-fn/dyn-pos.rs
index e817a1b518f..772c7d15cfd 100644
--- a/tests/ui/async-await/async-fn/dyn-pos.rs
+++ b/tests/ui/async-await/async-fn/dyn-pos.rs
@@ -4,9 +4,6 @@
 
 fn foo(x: &dyn async Fn()) {}
 //~^ ERROR the trait `AsyncFn` cannot be made into an object
-//~| ERROR the trait `AsyncFn` cannot be made into an object
-//~| ERROR the trait `AsyncFn` cannot be made into an object
-//~| ERROR the trait `AsyncFn` cannot be made into an object
 //~| ERROR the trait `AsyncFnMut` cannot be made into an object
 //~| ERROR the trait `AsyncFnMut` cannot be made into an object
 //~| ERROR the trait `AsyncFnMut` cannot be made into an object
diff --git a/tests/ui/async-await/async-fn/dyn-pos.stderr b/tests/ui/async-await/async-fn/dyn-pos.stderr
index 488c5d06938..3bef5a27897 100644
--- a/tests/ui/async-await/async-fn/dyn-pos.stderr
+++ b/tests/ui/async-await/async-fn/dyn-pos.stderr
@@ -1,17 +1,3 @@
-error[E0038]: the trait `AsyncFn` cannot be made into an object
-  --> $DIR/dyn-pos.rs:5:16
-   |
-LL | fn foo(x: &dyn async Fn()) {}
-   |                ^^^^^^^^^^ `AsyncFn` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
-   |
-   = note: the trait cannot be made into an object because it contains the generic associated type `CallFuture`
-   = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFn` for this new enum and using it instead:
-             &F
-             std::boxed::Box<F, A>
-
 error[E0038]: the trait `AsyncFnMut` cannot be made into an object
   --> $DIR/dyn-pos.rs:5:16
    |
@@ -21,27 +7,12 @@ LL | fn foo(x: &dyn async Fn()) {}
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
   --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
    |
-   = note: the trait cannot be made into an object because it contains the generic associated type `CallMutFuture`
+   = note: the trait cannot be made into an object because it contains the generic associated type `CallRefFuture`
    = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFnMut` for this new enum and using it instead:
              &F
              &mut F
              std::boxed::Box<F, A>
 
-error[E0038]: the trait `AsyncFn` cannot be made into an object
-  --> $DIR/dyn-pos.rs:5:16
-   |
-LL | fn foo(x: &dyn async Fn()) {}
-   |                ^^^^^^^^^^ `AsyncFn` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
-   |
-   = note: the trait cannot be made into an object because it contains the generic associated type `CallFuture`
-   = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFn` for this new enum and using it instead:
-             &F
-             std::boxed::Box<F, A>
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
 error[E0038]: the trait `AsyncFnMut` cannot be made into an object
   --> $DIR/dyn-pos.rs:5:16
    |
@@ -51,28 +22,13 @@ LL | fn foo(x: &dyn async Fn()) {}
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
   --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
    |
-   = note: the trait cannot be made into an object because it contains the generic associated type `CallMutFuture`
+   = note: the trait cannot be made into an object because it contains the generic associated type `CallRefFuture`
    = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFnMut` for this new enum and using it instead:
              &F
              &mut F
              std::boxed::Box<F, A>
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0038]: the trait `AsyncFn` cannot be made into an object
-  --> $DIR/dyn-pos.rs:5:16
-   |
-LL | fn foo(x: &dyn async Fn()) {}
-   |                ^^^^^^^^^^ `AsyncFn` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
-   |
-   = note: the trait cannot be made into an object because it contains the generic associated type `CallFuture`
-   = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFn` for this new enum and using it instead:
-             &F
-             std::boxed::Box<F, A>
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
 error[E0038]: the trait `AsyncFnMut` cannot be made into an object
   --> $DIR/dyn-pos.rs:5:16
    |
@@ -82,7 +38,7 @@ LL | fn foo(x: &dyn async Fn()) {}
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
   --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
    |
-   = note: the trait cannot be made into an object because it contains the generic associated type `CallMutFuture`
+   = note: the trait cannot be made into an object because it contains the generic associated type `CallRefFuture`
    = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFnMut` for this new enum and using it instead:
              &F
              &mut F
@@ -98,14 +54,11 @@ LL | fn foo(x: &dyn async Fn()) {}
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
   --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
    |
-   = note: the trait cannot be made into an object because it contains the generic associated type `CallFuture`
-  ::: $SRC_DIR/core/src/ops/async_function.rs:LL:COL
-   |
-   = note: the trait cannot be made into an object because it contains the generic associated type `CallMutFuture`
+   = note: the trait cannot be made into an object because it contains the generic associated type `CallRefFuture`
    = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFn` for this new enum and using it instead:
              &F
              std::boxed::Box<F, A>
 
-error: aborting due to 7 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0038`.