From 402e6051a2372ff7f30a7224f9c593d73b94217c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 3 Mar 2025 03:16:53 +0000 Subject: [PATCH 1/3] Better reasons for inline failure --- compiler/rustc_mir_transform/src/inline.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 5981b5031c649..c043a9850dd86 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,8 +622,7 @@ 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, @@ -653,7 +652,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 tuple argument type"); - return Err("implementation limitation"); + return Err("implementation limitation -- arg mismatch"); } } } else { @@ -663,7 +662,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 +692,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 +708,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 From c5072954ed3d8288197301b0c138da187142c6d8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 3 Mar 2025 02:12:28 +0000 Subject: [PATCH 2/3] Inline FnOnce once again --- compiler/rustc_mir_transform/src/inline.rs | 23 ++++++++++------------ 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index c043a9850dd86..0183ba19475c1 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -625,13 +625,6 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>( 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), @@ -641,18 +634,23 @@ 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) { trace!(?arg_ty, ?input_type); debug!("failed to normalize tuple argument type"); - return Err("implementation limitation -- arg mismatch"); + return Err("implementation limitation"); } } } else { @@ -1059,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() } From f33521936d01e55f003dc89b3c6b7bb5c4ec6691 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 3 Mar 2025 19:21:54 +0000 Subject: [PATCH 3/3] wasjhdhjasd --- compiler/rustc_mir_transform/src/inline.rs | 6 ++++++ library/alloc/src/boxed.rs | 3 +++ 2 files changed, 9 insertions(+) diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 0183ba19475c1..23ffedd97e057 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -625,6 +625,12 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>( return Err("implementation limitation -- return type mismatch"); } if callsite.fn_sig.abi() == ExternAbi::RustCall { + /* match callsite.callee.def { + InstanceKind::Item(def_id) if tcx.is_closure_like(def_id) => {} + InstanceKind::FnPtrShim(..) | InstanceKind::ClosureOnceShim { .. } => {} + _ => return Err("not inlining non-builtin call"), + } */ + let (self_arg, arg_tuple) = match &args[..] { [arg_tuple] => (None, arg_tuple), [self_arg, arg_tuple] => (Some(self_arg), arg_tuple), diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index c3f5806e1aa90..354e7aaf3228d 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1968,6 +1968,7 @@ impl LegacyReceiver for Box {} impl + ?Sized, A: Allocator> FnOnce for Box { type Output = >::Output; + #[inline(never)] extern "rust-call" fn call_once(self, args: Args) -> Self::Output { >::call_once(*self, args) } @@ -1975,6 +1976,7 @@ impl + ?Sized, A: Allocator> FnOnce for Box + ?Sized, A: Allocator> FnMut for Box { + #[inline(never)] extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output { >::call_mut(self, args) } @@ -1982,6 +1984,7 @@ impl + ?Sized, A: Allocator> FnMut for Box + ?Sized, A: Allocator> Fn for Box { + #[inline(never)] extern "rust-call" fn call(&self, args: Args) -> Self::Output { >::call(self, args) }