From c34ada7cca0607831dfae955214bc0b95f2ec312 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 14 Sep 2019 17:53:36 +0200 Subject: [PATCH] Fix foreign type handling --- src/base.rs | 5 ++--- src/common.rs | 18 ++++++++++++++---- src/num.rs | 12 +++--------- src/value_and_place.rs | 16 ++++++++-------- 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/base.rs b/src/base.rs index f1840f20125..fe50d2a2dc4 100644 --- a/src/base.rs +++ b/src/base.rs @@ -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) } diff --git a/src/common.rs b/src/common.rs index fbb60713bd0..20449305609 100644 --- a/src/common.rs +++ b/src/common.rs @@ -60,11 +60,11 @@ pub fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option 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(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); diff --git a/src/num.rs b/src/num.rs index 417b9b5f717..442ff48550c 100644 --- a/src/num.rs +++ b/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); diff --git a/src/value_and_place.rs b/src/value_and_place.rs index d6ae021a44d..caf41bd1425 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -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); } }