diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 5981b5031c649..0183ba19475c1 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -606,14 +606,14 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
         ty::EarlyBinder::bind(callee_body.clone()),
     ) else {
         debug!("failed to normalize callee body");
-        return Err("implementation limitation");
+        return Err("implementation limitation -- could not normalize callee body");
     };
 
     // Normally, this shouldn't be required, but trait normalization failure can create a
     // validation ICE.
     if !validate_types(tcx, inliner.typing_env(), &callee_body, &caller_body).is_empty() {
         debug!("failed to validate callee body");
-        return Err("implementation limitation");
+        return Err("implementation limitation -- callee body failed validation");
     }
 
     // Check call signature compatibility.
@@ -622,17 +622,9 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
     let output_type = callee_body.return_ty();
     if !util::sub_types(tcx, inliner.typing_env(), output_type, destination_ty) {
         trace!(?output_type, ?destination_ty);
-        debug!("failed to normalize return type");
-        return Err("implementation limitation");
+        return Err("implementation limitation -- return type mismatch");
     }
     if callsite.fn_sig.abi() == ExternAbi::RustCall {
-        // FIXME: Don't inline user-written `extern "rust-call"` functions,
-        // since this is generally perf-negative on rustc, and we hope that
-        // LLVM will inline these functions instead.
-        if callee_body.spread_arg.is_some() {
-            return Err("user-written rust-call functions");
-        }
-
         let (self_arg, arg_tuple) = match &args[..] {
             [arg_tuple] => (None, arg_tuple),
             [self_arg, arg_tuple] => (Some(self_arg), arg_tuple),
@@ -642,12 +634,17 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
         let self_arg_ty = self_arg.map(|self_arg| self_arg.node.ty(&caller_body.local_decls, tcx));
 
         let arg_tuple_ty = arg_tuple.node.ty(&caller_body.local_decls, tcx);
-        let ty::Tuple(arg_tuple_tys) = *arg_tuple_ty.kind() else {
-            bug!("Closure arguments are not passed as a tuple");
+        let arg_tys = if callee_body.spread_arg.is_some() {
+            std::slice::from_ref(&arg_tuple_ty)
+        } else {
+            let ty::Tuple(arg_tuple_tys) = *arg_tuple_ty.kind() else {
+                bug!("Closure arguments are not passed as a tuple");
+            };
+            arg_tuple_tys.as_slice()
         };
 
         for (arg_ty, input) in
-            self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter())
+            self_arg_ty.into_iter().chain(arg_tys.iter().copied()).zip(callee_body.args_iter())
         {
             let input_type = callee_body.local_decls[input].ty;
             if !util::sub_types(tcx, inliner.typing_env(), input_type, arg_ty) {
@@ -663,7 +660,7 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
             if !util::sub_types(tcx, inliner.typing_env(), input_type, arg_ty) {
                 trace!(?arg_ty, ?input_type);
                 debug!("failed to normalize argument type");
-                return Err("implementation limitation");
+                return Err("implementation limitation -- arg mismatch");
             }
         }
     }
@@ -693,13 +690,13 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>(
             // won't cause cycles on this.
             if !inliner.tcx().is_mir_available(callee_def_id) {
                 debug!("item MIR unavailable");
-                return Err("implementation limitation");
+                return Err("implementation limitation -- MIR unavailable");
             }
         }
         // These have no own callable MIR.
         InstanceKind::Intrinsic(_) | InstanceKind::Virtual(..) => {
             debug!("instance without MIR (intrinsic / virtual)");
-            return Err("implementation limitation");
+            return Err("implementation limitation -- cannot inline intrinsic");
         }
 
         // FIXME(#127030): `ConstParamHasTy` has bad interactions with
@@ -709,7 +706,7 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>(
         // substituted.
         InstanceKind::DropGlue(_, Some(ty)) if ty.has_type_flags(TypeFlags::HAS_CT_PARAM) => {
             debug!("still needs substitution");
-            return Err("implementation limitation");
+            return Err("implementation limitation -- HACK for dropping polymorphic type");
         }
 
         // This cannot result in an immediate cycle since the callee MIR is a shim, which does
@@ -1060,8 +1057,7 @@ fn make_call_args<'tcx, I: Inliner<'tcx>>(
 
         closure_ref_arg.chain(tuple_tmp_args).collect()
     } else {
-        // FIXME(edition_2024): switch back to a normal method call.
-        <_>::into_iter(args)
+        args.into_iter()
             .map(|a| create_temp_if_necessary(inliner, a.node, callsite, caller_body, return_block))
             .collect()
     }
diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff
index 757617e594021..0615f8132af00 100644
--- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff
@@ -7,23 +7,42 @@
       let mut _0: ();
       let mut _3: &mut std::boxed::Box<dyn std::ops::FnMut<I, Output = ()>>;
       let mut _4: I;
++     scope 1 (inlined <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut) {
++         let mut _5: &mut dyn std::ops::FnMut<I, Output = ()>;
++         let mut _6: std::boxed::Box<dyn std::ops::FnMut<I, Output = ()>>;
++         let mut _7: *const dyn std::ops::FnMut<I, Output = ()>;
++     }
   
       bb0: {
           StorageLive(_3);
           _3 = &mut _1;
           StorageLive(_4);
           _4 = move _2;
-          _0 = <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut(move _3, move _4) -> [return: bb1, unwind unreachable];
+-         _0 = <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut(move _3, move _4) -> [return: bb1, unwind unreachable];
++         StorageLive(_6);
++         StorageLive(_7);
++         StorageLive(_5);
++         _6 = copy (*_3);
++         _7 = copy ((_6.0: std::ptr::Unique<dyn std::ops::FnMut<I, Output = ()>>).0: std::ptr::NonNull<dyn std::ops::FnMut<I, Output = ()>>) as *const dyn std::ops::FnMut<I, Output = ()> (Transmute);
++         _5 = &mut (*_7);
++         _0 = <dyn FnMut<I, Output = ()> as FnMut<I>>::call_mut(move _5, move _4) -> [return: bb2, unwind unreachable];
       }
   
       bb1: {
-          StorageDead(_4);
-          StorageDead(_3);
-          drop(_1) -> [return: bb2, unwind unreachable];
+-         StorageDead(_4);
+-         StorageDead(_3);
+-         drop(_1) -> [return: bb2, unwind unreachable];
++         return;
       }
   
       bb2: {
-          return;
+-         return;
++         StorageDead(_5);
++         StorageDead(_7);
++         StorageDead(_6);
++         StorageDead(_4);
++         StorageDead(_3);
++         drop(_1) -> [return: bb1, unwind unreachable];
       }
   }
   
diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff
index b82961c2815d6..21b20329d4fa9 100644
--- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff
@@ -7,31 +7,54 @@
       let mut _0: ();
       let mut _3: &mut std::boxed::Box<dyn std::ops::FnMut<I, Output = ()>>;
       let mut _4: I;
++     scope 1 (inlined <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut) {
++         let mut _5: &mut dyn std::ops::FnMut<I, Output = ()>;
++         let mut _6: std::boxed::Box<dyn std::ops::FnMut<I, Output = ()>>;
++         let mut _7: *const dyn std::ops::FnMut<I, Output = ()>;
++     }
   
       bb0: {
           StorageLive(_3);
           _3 = &mut _1;
           StorageLive(_4);
           _4 = move _2;
-          _0 = <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut(move _3, move _4) -> [return: bb1, unwind: bb3];
+-         _0 = <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut(move _3, move _4) -> [return: bb1, unwind: bb3];
++         StorageLive(_6);
++         StorageLive(_7);
++         StorageLive(_5);
++         _6 = copy (*_3);
++         _7 = copy ((_6.0: std::ptr::Unique<dyn std::ops::FnMut<I, Output = ()>>).0: std::ptr::NonNull<dyn std::ops::FnMut<I, Output = ()>>) as *const dyn std::ops::FnMut<I, Output = ()> (Transmute);
++         _5 = &mut (*_7);
++         _0 = <dyn FnMut<I, Output = ()> as FnMut<I>>::call_mut(move _5, move _4) -> [return: bb4, unwind: bb2];
       }
   
       bb1: {
-          StorageDead(_4);
-          StorageDead(_3);
-          drop(_1) -> [return: bb2, unwind: bb4];
+-         StorageDead(_4);
+-         StorageDead(_3);
+-         drop(_1) -> [return: bb2, unwind: bb4];
++         return;
       }
   
-      bb2: {
-          return;
+-     bb2: {
+-         return;
++     bb2 (cleanup): {
++         drop(_1) -> [return: bb3, unwind terminate(cleanup)];
       }
   
       bb3 (cleanup): {
-          drop(_1) -> [return: bb4, unwind terminate(cleanup)];
+-         drop(_1) -> [return: bb4, unwind terminate(cleanup)];
++         resume;
       }
   
-      bb4 (cleanup): {
-          resume;
+-     bb4 (cleanup): {
+-         resume;
++     bb4: {
++         StorageDead(_5);
++         StorageDead(_7);
++         StorageDead(_6);
++         StorageDead(_4);
++         StorageDead(_3);
++         drop(_1) -> [return: bb1, unwind: bb3];
       }
   }
   
diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs
index abc0ef5c61d5f..ac0c3ddac764c 100644
--- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs
+++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs
@@ -8,6 +8,6 @@ use std::marker::Tuple;
 // EMIT_MIR dont_ice_on_generic_rust_call.call.Inline.diff
 pub fn call<I: Tuple>(mut mock: Box<dyn FnMut<I, Output = ()>>, input: I) {
     // CHECK-LABEL: fn call(
-    // CHECK-NOT: inlined
+    // CHECK: (inlined <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut)
     mock.call_mut(input)
 }
diff --git a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff
index 4fa04b05e8993..ecea7a97513d5 100644
--- a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff
@@ -7,6 +7,11 @@
       let _2: ();
       let mut _3: &std::boxed::Box<dyn std::ops::Fn(i32)>;
       let mut _4: (i32,);
++     scope 1 (inlined <Box<dyn Fn(i32)> as Fn<(i32,)>>::call) {
++         let mut _5: &dyn std::ops::Fn(i32);
++         let mut _6: std::boxed::Box<dyn std::ops::Fn(i32)>;
++         let mut _7: *const dyn std::ops::Fn(i32);
++     }
   
       bb0: {
           StorageLive(_2);
@@ -14,19 +19,34 @@
           _3 = &_1;
           StorageLive(_4);
           _4 = (const 1_i32,);
-          _2 = <Box<dyn Fn(i32)> as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind unreachable];
+-         _2 = <Box<dyn Fn(i32)> as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind unreachable];
++         StorageLive(_6);
++         StorageLive(_7);
++         StorageLive(_5);
++         _6 = copy (*_3);
++         _7 = copy ((_6.0: std::ptr::Unique<dyn std::ops::Fn(i32)>).0: std::ptr::NonNull<dyn std::ops::Fn(i32)>) as *const dyn std::ops::Fn(i32) (Transmute);
++         _5 = &(*_7);
++         _2 = <dyn Fn(i32) as Fn<(i32,)>>::call(move _5, move _4) -> [return: bb2, unwind unreachable];
       }
   
       bb1: {
++         return;
++     }
++ 
++     bb2: {
++         StorageDead(_5);
++         StorageDead(_7);
++         StorageDead(_6);
           StorageDead(_4);
           StorageDead(_3);
           StorageDead(_2);
           _0 = const ();
-          drop(_1) -> [return: bb2, unwind unreachable];
-      }
-  
-      bb2: {
-          return;
+-         drop(_1) -> [return: bb2, unwind unreachable];
+-     }
+- 
+-     bb2: {
+-         return;
++         drop(_1) -> [return: bb1, unwind unreachable];
       }
   }
   
diff --git a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff
index 47fd0ed079995..3a4a528e879fb 100644
--- a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff
@@ -7,6 +7,11 @@
       let _2: ();
       let mut _3: &std::boxed::Box<dyn std::ops::Fn(i32)>;
       let mut _4: (i32,);
++     scope 1 (inlined <Box<dyn Fn(i32)> as Fn<(i32,)>>::call) {
++         let mut _5: &dyn std::ops::Fn(i32);
++         let mut _6: std::boxed::Box<dyn std::ops::Fn(i32)>;
++         let mut _7: *const dyn std::ops::Fn(i32);
++     }
   
       bb0: {
           StorageLive(_2);
@@ -14,27 +19,47 @@
           _3 = &_1;
           StorageLive(_4);
           _4 = (const 1_i32,);
-          _2 = <Box<dyn Fn(i32)> as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind: bb3];
+-         _2 = <Box<dyn Fn(i32)> as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind: bb3];
++         StorageLive(_6);
++         StorageLive(_7);
++         StorageLive(_5);
++         _6 = copy (*_3);
++         _7 = copy ((_6.0: std::ptr::Unique<dyn std::ops::Fn(i32)>).0: std::ptr::NonNull<dyn std::ops::Fn(i32)>) as *const dyn std::ops::Fn(i32) (Transmute);
++         _5 = &(*_7);
++         _2 = <dyn Fn(i32) as Fn<(i32,)>>::call(move _5, move _4) -> [return: bb4, unwind: bb2];
       }
   
       bb1: {
-          StorageDead(_4);
-          StorageDead(_3);
-          StorageDead(_2);
-          _0 = const ();
-          drop(_1) -> [return: bb2, unwind: bb4];
+-         StorageDead(_4);
+-         StorageDead(_3);
+-         StorageDead(_2);
+-         _0 = const ();
+-         drop(_1) -> [return: bb2, unwind: bb4];
++         return;
       }
   
-      bb2: {
-          return;
+-     bb2: {
+-         return;
++     bb2 (cleanup): {
++         drop(_1) -> [return: bb3, unwind terminate(cleanup)];
       }
   
       bb3 (cleanup): {
-          drop(_1) -> [return: bb4, unwind terminate(cleanup)];
+-         drop(_1) -> [return: bb4, unwind terminate(cleanup)];
++         resume;
       }
   
-      bb4 (cleanup): {
-          resume;
+-     bb4 (cleanup): {
+-         resume;
++     bb4: {
++         StorageDead(_5);
++         StorageDead(_7);
++         StorageDead(_6);
++         StorageDead(_4);
++         StorageDead(_3);
++         StorageDead(_2);
++         _0 = const ();
++         drop(_1) -> [return: bb1, unwind: bb3];
       }
   }
   
diff --git a/tests/mir-opt/inline/inline_box_fn.rs b/tests/mir-opt/inline/inline_box_fn.rs
index bb2da3ac51576..e9ab3bef01fbe 100644
--- a/tests/mir-opt/inline/inline_box_fn.rs
+++ b/tests/mir-opt/inline/inline_box_fn.rs
@@ -5,6 +5,6 @@
 // EMIT_MIR inline_box_fn.call.Inline.diff
 fn call(x: Box<dyn Fn(i32)>) {
     // CHECK-LABEL: fn call(
-    // CHECK-NOT: inlined
+    // CHECK: (inlined <Box<dyn Fn(i32)> as Fn<(i32,)>>::call)
     x(1);
 }
diff --git a/tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff
index 8a6eec3352a34..c878b8b632414 100644
--- a/tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff
@@ -5,9 +5,15 @@
       let mut _0: ();
       let _1: ();
 +     let mut _2: fn() {f};
++     let mut _4: ();
 +     scope 1 (inlined call::<fn() {f}>) {
 +         debug f => _2;
 +         let _3: ();
++         scope 2 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) {
++             scope 3 (inlined f) {
++                 let _5: ();
++             }
++         }
 +     }
   
       bb0: {
@@ -16,10 +22,15 @@
 +         StorageLive(_2);
 +         _2 = f;
 +         StorageLive(_3);
-+         _3 = <fn() {f} as FnOnce<()>>::call_once(move _2, const ()) -> [return: bb1, unwind unreachable];
++         StorageLive(_4);
++         _4 = const ();
++         StorageLive(_5);
++         _5 = call::<fn() {f}>(f) -> [return: bb1, unwind unreachable];
       }
   
       bb1: {
++         StorageDead(_5);
++         StorageDead(_4);
 +         StorageDead(_3);
 +         StorageDead(_2);
           StorageDead(_1);
diff --git a/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff
index a24649c1ebd57..072b7ab3fa491 100644
--- a/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff
@@ -5,9 +5,15 @@
       let mut _0: ();
       let _1: ();
 +     let mut _2: fn() {f};
++     let mut _4: ();
 +     scope 1 (inlined call::<fn() {f}>) {
 +         debug f => _2;
 +         let _3: ();
++         scope 2 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) {
++             scope 3 (inlined f) {
++                 let _5: ();
++             }
++         }
 +     }
   
       bb0: {
@@ -16,10 +22,15 @@
 +         StorageLive(_2);
 +         _2 = f;
 +         StorageLive(_3);
-+         _3 = <fn() {f} as FnOnce<()>>::call_once(move _2, const ()) -> [return: bb1, unwind continue];
++         StorageLive(_4);
++         _4 = const ();
++         StorageLive(_5);
++         _5 = call::<fn() {f}>(f) -> [return: bb1, unwind continue];
       }
   
       bb1: {
++         StorageDead(_5);
++         StorageDead(_4);
 +         StorageDead(_3);
 +         StorageDead(_2);
           StorageDead(_1);
diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff
index 338dca85e5c9f..75fc2ea16e3d9 100644
--- a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff
@@ -5,6 +5,7 @@
       let mut _0: ();
       let _1: (!, !);
 +     let mut _2: fn() -> ! {sleep};
++     let mut _7: ();
 +     scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) {
 +         debug f => _2;
 +         let mut _3: &fn() -> ! {sleep};
@@ -17,6 +18,10 @@
 +                 debug b => _6;
 +             }
 +         }
++         scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) {
++             scope 5 (inlined sleep) {
++             }
++         }
 +     }
   
       bb0: {
@@ -28,24 +33,13 @@
 +         StorageLive(_6);
 +         StorageLive(_3);
 +         _3 = &_2;
-+         _4 = <fn() -> ! {sleep} as Fn<()>>::call(move _3, const ()) -> [return: bb1, unwind unreachable];
++         StorageLive(_7);
++         _7 = const ();
++         goto -> bb1;
 +     }
 + 
 +     bb1: {
-+         StorageDead(_3);
-+         StorageLive(_5);
-+         _5 = &_2;
-+         _6 = <fn() -> ! {sleep} as Fn<()>>::call(move _5, const ()) -> [return: bb2, unwind unreachable];
-+     }
-+ 
-+     bb2: {
-+         StorageDead(_5);
-+         _1 = (copy _4, copy _6);
-+         drop(_2) -> [return: bb3, unwind unreachable];
-+     }
-+ 
-+     bb3: {
-+         unreachable;
++         goto -> bb1;
       }
   }
   
diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
index a77cb913bfd03..407cb24df6751 100644
--- a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
@@ -5,6 +5,7 @@
       let mut _0: ();
       let _1: (!, !);
 +     let mut _2: fn() -> ! {sleep};
++     let mut _8: ();
 +     scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) {
 +         debug f => _2;
 +         let mut _3: &fn() -> ! {sleep};
@@ -18,6 +19,10 @@
 +                 debug b => _6;
 +             }
 +         }
++         scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) {
++             scope 5 (inlined sleep) {
++             }
++         }
 +     }
   
       bb0: {
@@ -29,40 +34,13 @@
 +         StorageLive(_4);
 +         StorageLive(_3);
 +         _3 = &_2;
-+         _4 = <fn() -> ! {sleep} as Fn<()>>::call(move _3, const ()) -> [return: bb1, unwind: bb5];
++         StorageLive(_8);
++         _8 = const ();
++         goto -> bb1;
 +     }
 + 
 +     bb1: {
-+         StorageDead(_3);
-+         StorageLive(_5);
-+         _5 = &_2;
-+         _6 = <fn() -> ! {sleep} as Fn<()>>::call(move _5, const ()) -> [return: bb2, unwind: bb4];
-+     }
-+ 
-+     bb2: {
-+         StorageDead(_5);
-+         StorageLive(_7);
-+         _7 = move _4;
-+         _1 = (move _7, copy _6);
-+         StorageDead(_7);
-+         StorageDead(_4);
-+         drop(_2) -> [return: bb3, unwind continue];
-+     }
-+ 
-+     bb3: {
-+         unreachable;
-+     }
-+ 
-+     bb4 (cleanup): {
-+         drop(_4) -> [return: bb5, unwind terminate(cleanup)];
-+     }
-+ 
-+     bb5 (cleanup): {
-+         drop(_2) -> [return: bb6, unwind terminate(cleanup)];
-+     }
-+ 
-+     bb6 (cleanup): {
-+         resume;
++         goto -> bb1;
       }
   }
   
diff --git a/tests/mir-opt/inline/inline_diverging.rs b/tests/mir-opt/inline/inline_diverging.rs
index e1cea3618f176..04ff943e74657 100644
--- a/tests/mir-opt/inline/inline_diverging.rs
+++ b/tests/mir-opt/inline/inline_diverging.rs
@@ -26,7 +26,8 @@ pub fn g(i: i32) -> u32 {
 pub fn h() {
     // CHECK-LABEL: fn h(
     // CHECK: (inlined call_twice::<!, fn() -> ! {sleep}>)
-    // CHECK-NOT: inlined
+    // CHECK: (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep}))
+    // CHECK: (inlined sleep)
     call_twice(sleep);
 }
 
diff --git a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff
index b9f268df35150..14a0c639c3abd 100644
--- a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff
@@ -9,6 +9,10 @@
       let _4: fn() {foo};
       let mut _5: ();
 +     scope 1 (inlined hide_foo) {
++     }
++     scope 2 (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo})) {
++         scope 3 (inlined foo) {
++         }
 +     }
   
       bb0: {
@@ -23,22 +27,20 @@
           StorageLive(_5);
           _5 = ();
 -         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind unreachable];
-+         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb1, unwind unreachable];
-      }
-  
+-     }
+- 
 -     bb2: {
-+     bb1: {
           StorageDead(_5);
           StorageDead(_3);
           StorageDead(_4);
           StorageDead(_2);
           _0 = const ();
 -         drop(_1) -> [return: bb3, unwind unreachable];
-+         drop(_1) -> [return: bb2, unwind unreachable];
++         drop(_1) -> [return: bb1, unwind unreachable];
       }
   
 -     bb3: {
-+     bb2: {
++     bb1: {
           return;
       }
   }
diff --git a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff
index 8495164df9c62..e0a273eb13f50 100644
--- a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff
@@ -9,6 +9,10 @@
       let _4: fn() {foo};
       let mut _5: ();
 +     scope 1 (inlined hide_foo) {
++     }
++     scope 2 (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo})) {
++         scope 3 (inlined foo) {
++         }
 +     }
   
       bb0: {
@@ -23,33 +27,29 @@
           StorageLive(_5);
           _5 = ();
 -         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4];
-+         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb1, unwind: bb3];
-      }
-  
+-     }
+- 
 -     bb2: {
-+     bb1: {
           StorageDead(_5);
           StorageDead(_3);
           StorageDead(_4);
           StorageDead(_2);
           _0 = const ();
 -         drop(_1) -> [return: bb3, unwind: bb5];
-+         drop(_1) -> [return: bb2, unwind: bb4];
++         drop(_1) -> [return: bb1, unwind: bb2];
       }
   
 -     bb3: {
-+     bb2: {
++     bb1: {
           return;
       }
   
 -     bb4 (cleanup): {
 -         drop(_1) -> [return: bb5, unwind terminate(cleanup)];
-+     bb3 (cleanup): {
-+         drop(_1) -> [return: bb4, unwind terminate(cleanup)];
-      }
-  
+-     }
+- 
 -     bb5 (cleanup): {
-+     bb4 (cleanup): {
++     bb2 (cleanup): {
           resume;
       }
   }
diff --git a/tests/mir-opt/inline/issue_78442.rs b/tests/mir-opt/inline/issue_78442.rs
index 4eb5c142034c2..a142d45737748 100644
--- a/tests/mir-opt/inline/issue_78442.rs
+++ b/tests/mir-opt/inline/issue_78442.rs
@@ -9,10 +9,9 @@ pub fn bar<P>(
     _baz: P,
 ) {
     // CHECK-LABEL: fn bar(
-    // CHECK: let mut {{.*}}: &fn() {foo};
-    // CHECK: let {{.*}}: fn() {foo};
     // CHECK: (inlined hide_foo)
-    // CHECK-NOT: inlined
+    // CHECK: (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo}))
+    // CHECK: (inlined foo)
     hide_foo()();
 }
 
diff --git a/tests/mir-opt/inline_fn_call_for_fn_def.rs b/tests/mir-opt/inline_fn_call_for_fn_def.rs
new file mode 100644
index 0000000000000..7601feda57325
--- /dev/null
+++ b/tests/mir-opt/inline_fn_call_for_fn_def.rs
@@ -0,0 +1,19 @@
+//@ test-mir-pass: Inline
+//@ compile-flags: --crate-type=lib -C panic=abort
+
+// EMIT_MIR inline_fn_call_for_fn_def.test.Inline.diff
+
+fn inline_fn(x: impl FnOnce() -> i32) -> i32 {
+    x()
+}
+
+fn yield_number() -> i32 {
+    64
+}
+
+fn test() -> i32 {
+    // CHECK: (inlined inline_fn::<fn() -> i32 {yield_number}>)
+    // CHECK: (inlined <fn() -> i32 {yield_number} as FnOnce<()>>::call_once - shim(fn() -> i32 {yield_number}))
+    // CHECK: (inlined yield_number)
+    inline_fn(yield_number)
+}
diff --git a/tests/mir-opt/inline_fn_call_for_fn_def.test.Inline.diff b/tests/mir-opt/inline_fn_call_for_fn_def.test.Inline.diff
new file mode 100644
index 0000000000000..aef7aa2397095
--- /dev/null
+++ b/tests/mir-opt/inline_fn_call_for_fn_def.test.Inline.diff
@@ -0,0 +1,34 @@
+- // MIR for `test` before Inline
++ // MIR for `test` after Inline
+  
+  fn test() -> i32 {
+      let mut _0: i32;
+- 
+-     bb0: {
+-         _0 = inline_fn::<fn() -> i32 {yield_number}>(yield_number) -> [return: bb1, unwind unreachable];
++     let mut _1: fn() -> i32 {yield_number};
++     scope 1 (inlined inline_fn::<fn() -> i32 {yield_number}>) {
++         let mut _2: fn() -> i32 {yield_number};
++         let mut _3: ();
++         scope 2 (inlined <fn() -> i32 {yield_number} as FnOnce<()>>::call_once - shim(fn() -> i32 {yield_number})) {
++             scope 3 (inlined yield_number) {
++             }
++         }
+      }
+  
+-     bb1: {
++     bb0: {
++         StorageLive(_1);
++         _1 = yield_number;
++         StorageLive(_2);
++         _2 = move _1;
++         StorageLive(_3);
++         _3 = ();
++         _0 = const 64_i32;
++         StorageDead(_3);
++         StorageDead(_2);
++         StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir
similarity index 100%
rename from tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir
rename to tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir
diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir
similarity index 100%
rename from tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir
rename to tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir
diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir
new file mode 100644
index 0000000000000..5876c55c52b94
--- /dev/null
+++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir
@@ -0,0 +1,68 @@
+// MIR for `num_to_digit` after PreCodegen
+
+fn num_to_digit(_1: char) -> u32 {
+    debug num => _1;
+    let mut _0: u32;
+    let mut _4: std::option::Option<u32>;
+    scope 1 (inlined char::methods::<impl char>::is_digit) {
+        let _2: std::option::Option<u32>;
+        scope 2 (inlined Option::<u32>::is_some) {
+            let mut _3: isize;
+        }
+    }
+    scope 3 (inlined #[track_caller] Option::<u32>::unwrap) {
+        let mut _5: isize;
+        let mut _6: !;
+        scope 4 {
+        }
+    }
+
+    bb0: {
+        StorageLive(_2);
+        _2 = char::methods::<impl char>::to_digit(copy _1, const 8_u32) -> [return: bb1, unwind unreachable];
+    }
+
+    bb1: {
+        StorageLive(_3);
+        _3 = discriminant(_2);
+        StorageDead(_2);
+        switchInt(move _3) -> [1: bb2, otherwise: bb7];
+    }
+
+    bb2: {
+        StorageDead(_3);
+        StorageLive(_4);
+        _4 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb3, unwind unreachable];
+    }
+
+    bb3: {
+        StorageLive(_5);
+        _5 = discriminant(_4);
+        switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb6];
+    }
+
+    bb4: {
+        _6 = option::unwrap_failed() -> unwind unreachable;
+    }
+
+    bb5: {
+        _0 = move ((_4 as Some).0: u32);
+        StorageDead(_5);
+        StorageDead(_4);
+        goto -> bb8;
+    }
+
+    bb6: {
+        unreachable;
+    }
+
+    bb7: {
+        StorageDead(_3);
+        _0 = const 0_u32;
+        goto -> bb8;
+    }
+
+    bb8: {
+        return;
+    }
+}
diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir
new file mode 100644
index 0000000000000..f1185353a43c8
--- /dev/null
+++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir
@@ -0,0 +1,68 @@
+// MIR for `num_to_digit` after PreCodegen
+
+fn num_to_digit(_1: char) -> u32 {
+    debug num => _1;
+    let mut _0: u32;
+    let mut _4: std::option::Option<u32>;
+    scope 1 (inlined char::methods::<impl char>::is_digit) {
+        let _2: std::option::Option<u32>;
+        scope 2 (inlined Option::<u32>::is_some) {
+            let mut _3: isize;
+        }
+    }
+    scope 3 (inlined #[track_caller] Option::<u32>::unwrap) {
+        let mut _5: isize;
+        let mut _6: !;
+        scope 4 {
+        }
+    }
+
+    bb0: {
+        StorageLive(_2);
+        _2 = char::methods::<impl char>::to_digit(copy _1, const 8_u32) -> [return: bb1, unwind continue];
+    }
+
+    bb1: {
+        StorageLive(_3);
+        _3 = discriminant(_2);
+        StorageDead(_2);
+        switchInt(move _3) -> [1: bb2, otherwise: bb7];
+    }
+
+    bb2: {
+        StorageDead(_3);
+        StorageLive(_4);
+        _4 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb3, unwind continue];
+    }
+
+    bb3: {
+        StorageLive(_5);
+        _5 = discriminant(_4);
+        switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb6];
+    }
+
+    bb4: {
+        _6 = option::unwrap_failed() -> unwind continue;
+    }
+
+    bb5: {
+        _0 = move ((_4 as Some).0: u32);
+        StorageDead(_5);
+        StorageDead(_4);
+        goto -> bb8;
+    }
+
+    bb6: {
+        unreachable;
+    }
+
+    bb7: {
+        StorageDead(_3);
+        _0 = const 0_u32;
+        goto -> bb8;
+    }
+
+    bb8: {
+        return;
+    }
+}
diff --git a/tests/mir-opt/issues/issue_59352.rs b/tests/mir-opt/issues/issue_59352.rs
index 9024dc976e494..516a712f1db16 100644
--- a/tests/mir-opt/issues/issue_59352.rs
+++ b/tests/mir-opt/issues/issue_59352.rs
@@ -1,4 +1,6 @@
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
 // This test is a mirror of codegen/issue-59352.rs.
 // The LLVM inliner doesn't inline `char::method::is_digit()` and so it doesn't recognize this case
 // as effectively `if x.is_some() { x.unwrap() } else { 0 }`.
diff --git a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir
index 4977f39ccefe8..d22ea54004c91 100644
--- a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir
@@ -29,6 +29,10 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
                 let mut _12: U;
                 scope 6 {
                     debug x => _10;
+                    scope 7 (inlined ops::function::impls::<impl FnOnce<(T,)> for &mut impl Fn(T) -> U>::call_once) {
+                        debug self => _8;
+                        debug args => _11;
+                    }
                 }
             }
         }
@@ -85,7 +89,7 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
         StorageLive(_12);
         StorageLive(_11);
         _11 = (copy _10,);
-        _12 = <&mut impl Fn(T) -> U as FnOnce<(T,)>>::call_once(move _8, move _11) -> [return: bb7, unwind: bb10];
+        _12 = <impl Fn(T) -> U as FnMut<(T,)>>::call_mut(move _8, move _11) -> [return: bb7, unwind: bb10];
     }
 
     bb7: {