Fix foreign type handling
This commit is contained in:
parent
b267995f39
commit
c34ada7cca
4 changed files with 27 additions and 24 deletions
|
@ -365,6 +365,7 @@ fn trans_stmt<'tcx>(
|
|||
Rvalue::Cast(CastKind::Misc, operand, to_ty) => {
|
||||
let operand = trans_operand(fx, operand);
|
||||
let from_ty = operand.layout().ty;
|
||||
let to_ty = fx.monomorphize(to_ty);
|
||||
|
||||
fn is_fat_ptr<'tcx>(
|
||||
fx: &FunctionCx<'_, 'tcx, impl Backend>,
|
||||
|
@ -375,9 +376,7 @@ fn trans_stmt<'tcx>(
|
|||
|ty::TypeAndMut {
|
||||
ty: pointee_ty,
|
||||
mutbl: _,
|
||||
}| {
|
||||
fx.layout_of(pointee_ty).is_unsized()
|
||||
},
|
||||
}| has_ptr_meta(fx.tcx, pointee_ty),
|
||||
)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
|
|
@ -60,11 +60,11 @@ pub fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types:
|
|||
FloatTy::F64 => types::F64,
|
||||
},
|
||||
ty::FnPtr(_) => pointer_ty(tcx),
|
||||
ty::RawPtr(TypeAndMut { ty, mutbl: _ }) | ty::Ref(_, ty, _) => {
|
||||
if ty.is_sized(tcx.at(DUMMY_SP), ParamEnv::reveal_all()) {
|
||||
pointer_ty(tcx)
|
||||
} else {
|
||||
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => {
|
||||
if has_ptr_meta(tcx, pointee_ty) {
|
||||
return None;
|
||||
} else {
|
||||
pointer_ty(tcx)
|
||||
}
|
||||
}
|
||||
ty::Param(_) => bug!("ty param {:?}", ty),
|
||||
|
@ -72,6 +72,16 @@ pub fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types:
|
|||
})
|
||||
}
|
||||
|
||||
/// Is a pointer to this type a fat ptr?
|
||||
pub fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
let ptr_ty = tcx.mk_ptr(TypeAndMut { ty, mutbl: rustc::hir::Mutability::MutImmutable });
|
||||
match &tcx.layout_of(ParamEnv::reveal_all().and(ptr_ty)).unwrap().abi {
|
||||
Abi::Scalar(_) => false,
|
||||
Abi::ScalarPair(_, _) => true,
|
||||
abi => unreachable!("Abi of ptr to {:?} is {:?}???", ty, abi),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn codegen_select(bcx: &mut FunctionBuilder, cond: Value, lhs: Value, rhs: Value) -> Value {
|
||||
let lhs_ty = bcx.func.dfg.value_type(lhs);
|
||||
let rhs_ty = bcx.func.dfg.value_type(rhs);
|
||||
|
|
12
src/num.rs
12
src/num.rs
|
@ -347,14 +347,9 @@ pub fn trans_ptr_binop<'tcx>(
|
|||
in_lhs: CValue<'tcx>,
|
||||
in_rhs: CValue<'tcx>,
|
||||
) -> CValue<'tcx> {
|
||||
let not_fat = match in_lhs.layout().ty.sty {
|
||||
ty::RawPtr(TypeAndMut { ty, mutbl: _ }) => {
|
||||
ty.is_sized(fx.tcx.at(DUMMY_SP), ParamEnv::reveal_all())
|
||||
}
|
||||
ty::FnPtr(..) => true,
|
||||
_ => bug!("trans_ptr_binop on non ptr"),
|
||||
};
|
||||
if not_fat {
|
||||
let pointee_ty = in_lhs.layout().ty.builtin_deref(true).unwrap().ty;
|
||||
|
||||
if !has_ptr_meta(fx.tcx, pointee_ty) {
|
||||
match bin_op {
|
||||
BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
|
||||
let lhs = in_lhs.load_scalar(fx);
|
||||
|
@ -364,7 +359,6 @@ pub fn trans_ptr_binop<'tcx>(
|
|||
}
|
||||
BinOp::Offset => {
|
||||
let (base, offset) = (in_lhs, in_rhs.load_scalar(fx));
|
||||
let pointee_ty = base.layout().ty.builtin_deref(true).unwrap().ty;
|
||||
let pointee_size = fx.layout_of(pointee_ty).size.bytes();
|
||||
let ptr_diff = fx.bcx.ins().imul_imm(offset, pointee_size as i64);
|
||||
let base_val = base.load_scalar(fx);
|
||||
|
|
|
@ -136,7 +136,7 @@ impl<'tcx> CValue<'tcx> {
|
|||
CValueInner::ByRef(addr) => {
|
||||
let (a_scalar, b_scalar) = match &layout.abi {
|
||||
layout::Abi::ScalarPair(a, b) => (a, b),
|
||||
_ => unreachable!(),
|
||||
_ => unreachable!("load_scalar_pair({:?})", self),
|
||||
};
|
||||
let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar);
|
||||
let clif_ty1 = scalar_to_clif_type(fx.tcx, a_scalar.clone());
|
||||
|
@ -496,19 +496,16 @@ impl<'tcx> CPlace<'tcx> {
|
|||
|
||||
pub fn place_deref(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>) -> CPlace<'tcx> {
|
||||
let inner_layout = fx.layout_of(self.layout().ty.builtin_deref(true).unwrap().ty);
|
||||
if !inner_layout.is_unsized() {
|
||||
CPlace::for_addr(self.to_cvalue(fx).load_scalar(fx), inner_layout)
|
||||
} else {
|
||||
if has_ptr_meta(fx.tcx, inner_layout.ty) {
|
||||
let (addr, extra) = self.to_cvalue(fx).load_scalar_pair(fx);
|
||||
CPlace::for_addr_with_extra(addr, extra, inner_layout)
|
||||
} else {
|
||||
CPlace::for_addr(self.to_cvalue(fx).load_scalar(fx), inner_layout)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_place_ref(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>, dest: CPlace<'tcx>) {
|
||||
if !self.layout().is_unsized() {
|
||||
let ptr = CValue::by_val(self.to_addr(fx), dest.layout());
|
||||
dest.write_cvalue(fx, ptr);
|
||||
} else {
|
||||
if has_ptr_meta(fx.tcx, self.layout().ty) {
|
||||
let (value, extra) = self.to_addr_maybe_unsized(fx);
|
||||
let ptr = CValue::by_val_pair(
|
||||
value,
|
||||
|
@ -516,6 +513,9 @@ impl<'tcx> CPlace<'tcx> {
|
|||
dest.layout(),
|
||||
);
|
||||
dest.write_cvalue(fx, ptr);
|
||||
} else {
|
||||
let ptr = CValue::by_val(self.to_addr(fx), dest.layout());
|
||||
dest.write_cvalue(fx, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue