Skip to content

Commit ba484de

Browse files
committed
Move some code around
1 parent da0309c commit ba484de

File tree

1 file changed

+76
-55
lines changed

1 file changed

+76
-55
lines changed

compiler/rustc_middle/src/ty/layout.rs

Lines changed: 76 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2514,7 +2514,7 @@ where
25142514
extra_args: &[Ty<'tcx>],
25152515
caller_location: Option<Ty<'tcx>>,
25162516
codegen_fn_attr_flags: CodegenFnAttrFlags,
2517-
mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgAbi<'tcx, Ty<'tcx>>,
2517+
make_self_ptr_thin: bool,
25182518
) -> Self;
25192519
fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi);
25202520
}
@@ -2574,9 +2574,7 @@ where
25742574
// Assume that fn pointers may always unwind
25752575
let codegen_fn_attr_flags = CodegenFnAttrFlags::UNWIND;
25762576

2577-
call::FnAbi::new_internal(cx, sig, extra_args, None, codegen_fn_attr_flags, |ty, _| {
2578-
ArgAbi::new(cx.layout_of(ty))
2579-
})
2577+
call::FnAbi::new_internal(cx, sig, extra_args, None, codegen_fn_attr_flags, false)
25802578
}
25812579

25822580
fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
@@ -2590,55 +2588,14 @@ where
25902588

25912589
let attrs = cx.tcx().codegen_fn_attrs(instance.def_id()).flags;
25922590

2593-
call::FnAbi::new_internal(cx, sig, extra_args, caller_location, attrs, |ty, arg_idx| {
2594-
let mut layout = cx.layout_of(ty);
2595-
// Don't pass the vtable, it's not an argument of the virtual fn.
2596-
// Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
2597-
// or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen
2598-
if let (ty::InstanceDef::Virtual(..), Some(0)) = (&instance.def, arg_idx) {
2599-
let fat_pointer_ty = if layout.is_unsized() {
2600-
// unsized `self` is passed as a pointer to `self`
2601-
// FIXME (mikeyhew) change this to use &own if it is ever added to the language
2602-
cx.tcx().mk_mut_ptr(layout.ty)
2603-
} else {
2604-
match layout.abi {
2605-
Abi::ScalarPair(..) => (),
2606-
_ => bug!("receiver type has unsupported layout: {:?}", layout),
2607-
}
2608-
2609-
// In the case of Rc<Self>, we need to explicitly pass a *mut RcBox<Self>
2610-
// with a Scalar (not ScalarPair) ABI. This is a hack that is understood
2611-
// elsewhere in the compiler as a method on a `dyn Trait`.
2612-
// To get the type `*mut RcBox<Self>`, we just keep unwrapping newtypes until we
2613-
// get a built-in pointer type
2614-
let mut fat_pointer_layout = layout;
2615-
'descend_newtypes: while !fat_pointer_layout.ty.is_unsafe_ptr()
2616-
&& !fat_pointer_layout.ty.is_region_ptr()
2617-
{
2618-
for i in 0..fat_pointer_layout.fields.count() {
2619-
let field_layout = fat_pointer_layout.field(cx, i);
2620-
2621-
if !field_layout.is_zst() {
2622-
fat_pointer_layout = field_layout;
2623-
continue 'descend_newtypes;
2624-
}
2625-
}
2626-
2627-
bug!("receiver has no non-zero-sized fields {:?}", fat_pointer_layout);
2628-
}
2629-
2630-
fat_pointer_layout.ty
2631-
};
2632-
2633-
// we now have a type like `*mut RcBox<dyn Trait>`
2634-
// change its layout to that of `*mut ()`, a thin pointer, but keep the same type
2635-
// this is understood as a special case elsewhere in the compiler
2636-
let unit_pointer_ty = cx.tcx().mk_mut_ptr(cx.tcx().mk_unit());
2637-
layout = cx.layout_of(unit_pointer_ty);
2638-
layout.ty = fat_pointer_ty;
2639-
}
2640-
ArgAbi::new(layout)
2641-
})
2591+
call::FnAbi::new_internal(
2592+
cx,
2593+
sig,
2594+
extra_args,
2595+
caller_location,
2596+
attrs,
2597+
matches!(instance.def, ty::InstanceDef::Virtual(..)),
2598+
)
26422599
}
26432600

26442601
fn new_internal(
@@ -2647,7 +2604,7 @@ where
26472604
extra_args: &[Ty<'tcx>],
26482605
caller_location: Option<Ty<'tcx>>,
26492606
codegen_fn_attr_flags: CodegenFnAttrFlags,
2650-
mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgAbi<'tcx, Ty<'tcx>>,
2607+
force_thin_self_ptr: bool,
26512608
) -> Self {
26522609
debug!("FnAbi::new_internal({:?}, {:?})", sig, extra_args);
26532610

@@ -2778,7 +2735,18 @@ where
27782735

27792736
let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| {
27802737
let is_return = arg_idx.is_none();
2781-
let mut arg = mk_arg_type(ty, arg_idx);
2738+
2739+
let layout = if force_thin_self_ptr && arg_idx == Some(0) {
2740+
// Don't pass the vtable, it's not an argument of the virtual fn.
2741+
// Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
2742+
// or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen
2743+
make_thin_self_ptr(cx, cx.layout_of(ty))
2744+
} else {
2745+
cx.layout_of(ty)
2746+
};
2747+
2748+
let mut arg = ArgAbi::new(layout);
2749+
27822750
if arg.layout.is_zst() {
27832751
// For some forsaken reason, x86_64-pc-windows-gnu
27842752
// doesn't ignore zero-sized struct arguments.
@@ -2912,3 +2880,56 @@ where
29122880
}
29132881
}
29142882
}
2883+
2884+
fn make_thin_self_ptr<'tcx, C>(
2885+
cx: &C,
2886+
mut layout: TyAndLayout<'tcx>,
2887+
) -> TyAndLayout<'tcx>
2888+
where C: LayoutOf<Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>>
2889+
//+ HasDataLayout
2890+
//+ HasTargetSpec
2891+
+ HasTyCtxt<'tcx>
2892+
+ HasParamEnv<'tcx>
2893+
{
2894+
let fat_pointer_ty = if layout.is_unsized() {
2895+
// unsized `self` is passed as a pointer to `self`
2896+
// FIXME (mikeyhew) change this to use &own if it is ever added to the language
2897+
cx.tcx().mk_mut_ptr(layout.ty)
2898+
} else {
2899+
match layout.abi {
2900+
Abi::ScalarPair(..) => (),
2901+
_ => bug!("receiver type has unsupported layout: {:?}", layout),
2902+
}
2903+
2904+
// In the case of Rc<Self>, we need to explicitly pass a *mut RcBox<Self>
2905+
// with a Scalar (not ScalarPair) ABI. This is a hack that is understood
2906+
// elsewhere in the compiler as a method on a `dyn Trait`.
2907+
// To get the type `*mut RcBox<Self>`, we just keep unwrapping newtypes until we
2908+
// get a built-in pointer type
2909+
let mut fat_pointer_layout = layout;
2910+
'descend_newtypes: while !fat_pointer_layout.ty.is_unsafe_ptr()
2911+
&& !fat_pointer_layout.ty.is_region_ptr()
2912+
{
2913+
for i in 0..fat_pointer_layout.fields.count() {
2914+
let field_layout = fat_pointer_layout.field(cx, i);
2915+
2916+
if !field_layout.is_zst() {
2917+
fat_pointer_layout = field_layout;
2918+
continue 'descend_newtypes;
2919+
}
2920+
}
2921+
2922+
bug!("receiver has no non-zero-sized fields {:?}", fat_pointer_layout);
2923+
}
2924+
2925+
fat_pointer_layout.ty
2926+
};
2927+
2928+
// we now have a type like `*mut RcBox<dyn Trait>`
2929+
// change its layout to that of `*mut ()`, a thin pointer, but keep the same type
2930+
// this is understood as a special case elsewhere in the compiler
2931+
let unit_pointer_ty = cx.tcx().mk_mut_ptr(cx.tcx().mk_unit());
2932+
layout = cx.layout_of(unit_pointer_ty);
2933+
layout.ty = fat_pointer_ty;
2934+
layout
2935+
}

0 commit comments

Comments
 (0)