Merge commit '9a0c32934e
' into sync_cg_clif-2021-03-05
This commit is contained in:
commit
7a6ea77473
73 changed files with 1145 additions and 2596 deletions
|
@ -13,19 +13,18 @@ use crate::prelude::*;
|
|||
/// in an upcast, where the new vtable for an object will be derived
|
||||
/// from the old one.
|
||||
pub(crate) fn unsized_info<'tcx>(
|
||||
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
source: Ty<'tcx>,
|
||||
target: Ty<'tcx>,
|
||||
old_info: Option<Value>,
|
||||
) -> Value {
|
||||
let (source, target) =
|
||||
fx.tcx
|
||||
.struct_lockstep_tails_erasing_lifetimes(source, target, ParamEnv::reveal_all());
|
||||
fx.tcx.struct_lockstep_tails_erasing_lifetimes(source, target, ParamEnv::reveal_all());
|
||||
match (&source.kind(), &target.kind()) {
|
||||
(&ty::Array(_, len), &ty::Slice(_)) => fx.bcx.ins().iconst(
|
||||
fx.pointer_type,
|
||||
len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64,
|
||||
),
|
||||
(&ty::Array(_, len), &ty::Slice(_)) => fx
|
||||
.bcx
|
||||
.ins()
|
||||
.iconst(fx.pointer_type, len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64),
|
||||
(&ty::Dynamic(..), &ty::Dynamic(..)) => {
|
||||
// For now, upcasts are limited to changes in marker
|
||||
// traits, and hence never actually require an actual
|
||||
|
@ -35,17 +34,13 @@ pub(crate) fn unsized_info<'tcx>(
|
|||
(_, &ty::Dynamic(ref data, ..)) => {
|
||||
crate::vtable::get_vtable(fx, fx.layout_of(source), data.principal())
|
||||
}
|
||||
_ => bug!(
|
||||
"unsized_info: invalid unsizing {:?} -> {:?}",
|
||||
source,
|
||||
target
|
||||
),
|
||||
_ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target),
|
||||
}
|
||||
}
|
||||
|
||||
/// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer.
|
||||
fn unsize_thin_ptr<'tcx>(
|
||||
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
src: Value,
|
||||
src_layout: TyAndLayout<'tcx>,
|
||||
dst_layout: TyAndLayout<'tcx>,
|
||||
|
@ -89,24 +84,22 @@ fn unsize_thin_ptr<'tcx>(
|
|||
/// Coerce `src`, which is a reference to a value of type `src_ty`,
|
||||
/// to a value of type `dst_ty` and store the result in `dst`
|
||||
pub(crate) fn coerce_unsized_into<'tcx>(
|
||||
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
src: CValue<'tcx>,
|
||||
dst: CPlace<'tcx>,
|
||||
) {
|
||||
let src_ty = src.layout().ty;
|
||||
let dst_ty = dst.layout().ty;
|
||||
let mut coerce_ptr = || {
|
||||
let (base, info) = if fx
|
||||
.layout_of(src.layout().ty.builtin_deref(true).unwrap().ty)
|
||||
.is_unsized()
|
||||
{
|
||||
// fat-ptr to fat-ptr unsize preserves the vtable
|
||||
// i.e., &'a fmt::Debug+Send => &'a fmt::Debug
|
||||
src.load_scalar_pair(fx)
|
||||
} else {
|
||||
let base = src.load_scalar(fx);
|
||||
unsize_thin_ptr(fx, base, src.layout(), dst.layout())
|
||||
};
|
||||
let (base, info) =
|
||||
if fx.layout_of(src.layout().ty.builtin_deref(true).unwrap().ty).is_unsized() {
|
||||
// fat-ptr to fat-ptr unsize preserves the vtable
|
||||
// i.e., &'a fmt::Debug+Send => &'a fmt::Debug
|
||||
src.load_scalar_pair(fx)
|
||||
} else {
|
||||
let base = src.load_scalar(fx);
|
||||
unsize_thin_ptr(fx, base, src.layout(), dst.layout())
|
||||
};
|
||||
dst.write_cvalue(fx, CValue::by_val_pair(base, info, dst.layout()));
|
||||
};
|
||||
match (&src_ty.kind(), &dst_ty.kind()) {
|
||||
|
@ -131,39 +124,26 @@ pub(crate) fn coerce_unsized_into<'tcx>(
|
|||
}
|
||||
}
|
||||
}
|
||||
_ => bug!(
|
||||
"coerce_unsized_into: invalid coercion {:?} -> {:?}",
|
||||
src_ty,
|
||||
dst_ty
|
||||
),
|
||||
_ => bug!("coerce_unsized_into: invalid coercion {:?} -> {:?}", src_ty, dst_ty),
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from https://github.com/rust-lang/rust/blob/2a663555ddf36f6b041445894a8c175cd1bc718c/src/librustc_codegen_ssa/glue.rs
|
||||
|
||||
pub(crate) fn size_and_align_of_dst<'tcx>(
|
||||
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
layout: TyAndLayout<'tcx>,
|
||||
info: Value,
|
||||
) -> (Value, Value) {
|
||||
if !layout.is_unsized() {
|
||||
let size = fx
|
||||
.bcx
|
||||
.ins()
|
||||
.iconst(fx.pointer_type, layout.size.bytes() as i64);
|
||||
let align = fx
|
||||
.bcx
|
||||
.ins()
|
||||
.iconst(fx.pointer_type, layout.align.abi.bytes() as i64);
|
||||
let size = fx.bcx.ins().iconst(fx.pointer_type, layout.size.bytes() as i64);
|
||||
let align = fx.bcx.ins().iconst(fx.pointer_type, layout.align.abi.bytes() as i64);
|
||||
return (size, align);
|
||||
}
|
||||
match layout.ty.kind() {
|
||||
ty::Dynamic(..) => {
|
||||
// load size/align from vtable
|
||||
(
|
||||
crate::vtable::size_of_obj(fx, info),
|
||||
crate::vtable::min_align_of_obj(fx, info),
|
||||
)
|
||||
(crate::vtable::size_of_obj(fx, info), crate::vtable::min_align_of_obj(fx, info))
|
||||
}
|
||||
ty::Slice(_) | ty::Str => {
|
||||
let unit = layout.field(fx, 0);
|
||||
|
@ -171,9 +151,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
|
|||
// times the unit size.
|
||||
(
|
||||
fx.bcx.ins().imul_imm(info, unit.size.bytes() as i64),
|
||||
fx.bcx
|
||||
.ins()
|
||||
.iconst(fx.pointer_type, unit.align.abi.bytes() as i64),
|
||||
fx.bcx.ins().iconst(fx.pointer_type, unit.align.abi.bytes() as i64),
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
|
@ -211,10 +189,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
|
|||
|
||||
// Choose max of two known alignments (combined value must
|
||||
// be aligned according to more restrictive of the two).
|
||||
let cmp = fx
|
||||
.bcx
|
||||
.ins()
|
||||
.icmp(IntCC::UnsignedGreaterThan, sized_align, unsized_align);
|
||||
let cmp = fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, sized_align, unsized_align);
|
||||
let align = fx.bcx.ins().select(cmp, sized_align, unsized_align);
|
||||
|
||||
// Issue #27023: must add any necessary padding to `size`
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue