Skip to content

Commit 0f91b86

Browse files
committed
Auto merge of rust-lang#137915 - compiler-errors:inliner-experiment-2, r=<try>
[do not merge] Inliner experiment 2 cc rust-lang#137907 (comment) r? `@ghost`
2 parents 81d8edc + f335219 commit 0f91b86

File tree

2 files changed

+24
-19
lines changed

2 files changed

+24
-19
lines changed

compiler/rustc_mir_transform/src/inline.rs

+21-19
Original file line numberDiff line numberDiff line change
@@ -606,14 +606,14 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
606606
ty::EarlyBinder::bind(callee_body.clone()),
607607
) else {
608608
debug!("failed to normalize callee body");
609-
return Err("implementation limitation");
609+
return Err("implementation limitation -- could not normalize callee body");
610610
};
611611

612612
// Normally, this shouldn't be required, but trait normalization failure can create a
613613
// validation ICE.
614614
if !validate_types(tcx, inliner.typing_env(), &callee_body, &caller_body).is_empty() {
615615
debug!("failed to validate callee body");
616-
return Err("implementation limitation");
616+
return Err("implementation limitation -- callee body failed validation");
617617
}
618618

619619
// Check call signature compatibility.
@@ -622,16 +622,14 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
622622
let output_type = callee_body.return_ty();
623623
if !util::sub_types(tcx, inliner.typing_env(), output_type, destination_ty) {
624624
trace!(?output_type, ?destination_ty);
625-
debug!("failed to normalize return type");
626-
return Err("implementation limitation");
625+
return Err("implementation limitation -- return type mismatch");
627626
}
628627
if callsite.fn_sig.abi() == ExternAbi::RustCall {
629-
// FIXME: Don't inline user-written `extern "rust-call"` functions,
630-
// since this is generally perf-negative on rustc, and we hope that
631-
// LLVM will inline these functions instead.
632-
if callee_body.spread_arg.is_some() {
633-
return Err("user-written rust-call functions");
634-
}
628+
/* match callsite.callee.def {
629+
InstanceKind::Item(def_id) if tcx.is_closure_like(def_id) => {}
630+
InstanceKind::FnPtrShim(..) | InstanceKind::ClosureOnceShim { .. } => {}
631+
_ => return Err("not inlining non-builtin call"),
632+
} */
635633

636634
let (self_arg, arg_tuple) = match &args[..] {
637635
[arg_tuple] => (None, arg_tuple),
@@ -642,12 +640,17 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
642640
let self_arg_ty = self_arg.map(|self_arg| self_arg.node.ty(&caller_body.local_decls, tcx));
643641

644642
let arg_tuple_ty = arg_tuple.node.ty(&caller_body.local_decls, tcx);
645-
let ty::Tuple(arg_tuple_tys) = *arg_tuple_ty.kind() else {
646-
bug!("Closure arguments are not passed as a tuple");
643+
let arg_tys = if callee_body.spread_arg.is_some() {
644+
std::slice::from_ref(&arg_tuple_ty)
645+
} else {
646+
let ty::Tuple(arg_tuple_tys) = *arg_tuple_ty.kind() else {
647+
bug!("Closure arguments are not passed as a tuple");
648+
};
649+
arg_tuple_tys.as_slice()
647650
};
648651

649652
for (arg_ty, input) in
650-
self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter())
653+
self_arg_ty.into_iter().chain(arg_tys.iter().copied()).zip(callee_body.args_iter())
651654
{
652655
let input_type = callee_body.local_decls[input].ty;
653656
if !util::sub_types(tcx, inliner.typing_env(), input_type, arg_ty) {
@@ -663,7 +666,7 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
663666
if !util::sub_types(tcx, inliner.typing_env(), input_type, arg_ty) {
664667
trace!(?arg_ty, ?input_type);
665668
debug!("failed to normalize argument type");
666-
return Err("implementation limitation");
669+
return Err("implementation limitation -- arg mismatch");
667670
}
668671
}
669672
}
@@ -693,13 +696,13 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>(
693696
// won't cause cycles on this.
694697
if !inliner.tcx().is_mir_available(callee_def_id) {
695698
debug!("item MIR unavailable");
696-
return Err("implementation limitation");
699+
return Err("implementation limitation -- MIR unavailable");
697700
}
698701
}
699702
// These have no own callable MIR.
700703
InstanceKind::Intrinsic(_) | InstanceKind::Virtual(..) => {
701704
debug!("instance without MIR (intrinsic / virtual)");
702-
return Err("implementation limitation");
705+
return Err("implementation limitation -- cannot inline intrinsic");
703706
}
704707

705708
// FIXME(#127030): `ConstParamHasTy` has bad interactions with
@@ -709,7 +712,7 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>(
709712
// substituted.
710713
InstanceKind::DropGlue(_, Some(ty)) if ty.has_type_flags(TypeFlags::HAS_CT_PARAM) => {
711714
debug!("still needs substitution");
712-
return Err("implementation limitation");
715+
return Err("implementation limitation -- HACK for dropping polymorphic type");
713716
}
714717

715718
// This cannot result in an immediate cycle since the callee MIR is a shim, which does
@@ -1060,8 +1063,7 @@ fn make_call_args<'tcx, I: Inliner<'tcx>>(
10601063

10611064
closure_ref_arg.chain(tuple_tmp_args).collect()
10621065
} else {
1063-
// FIXME(edition_2024): switch back to a normal method call.
1064-
<_>::into_iter(args)
1066+
args.into_iter()
10651067
.map(|a| create_temp_if_necessary(inliner, a.node, callsite, caller_body, return_block))
10661068
.collect()
10671069
}

library/alloc/src/boxed.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1968,20 +1968,23 @@ impl<T: ?Sized, A: Allocator> LegacyReceiver for Box<T, A> {}
19681968
impl<Args: Tuple, F: FnOnce<Args> + ?Sized, A: Allocator> FnOnce<Args> for Box<F, A> {
19691969
type Output = <F as FnOnce<Args>>::Output;
19701970

1971+
#[inline(never)]
19711972
extern "rust-call" fn call_once(self, args: Args) -> Self::Output {
19721973
<F as FnOnce<Args>>::call_once(*self, args)
19731974
}
19741975
}
19751976

19761977
#[stable(feature = "boxed_closure_impls", since = "1.35.0")]
19771978
impl<Args: Tuple, F: FnMut<Args> + ?Sized, A: Allocator> FnMut<Args> for Box<F, A> {
1979+
#[inline(never)]
19781980
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output {
19791981
<F as FnMut<Args>>::call_mut(self, args)
19801982
}
19811983
}
19821984

19831985
#[stable(feature = "boxed_closure_impls", since = "1.35.0")]
19841986
impl<Args: Tuple, F: Fn<Args> + ?Sized, A: Allocator> Fn<Args> for Box<F, A> {
1987+
#[inline(never)]
19851988
extern "rust-call" fn call(&self, args: Args) -> Self::Output {
19861989
<F as Fn<Args>>::call(self, args)
19871990
}

0 commit comments

Comments
 (0)