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) => {
|
Rvalue::Cast(CastKind::Misc, operand, to_ty) => {
|
||||||
let operand = trans_operand(fx, operand);
|
let operand = trans_operand(fx, operand);
|
||||||
let from_ty = operand.layout().ty;
|
let from_ty = operand.layout().ty;
|
||||||
|
let to_ty = fx.monomorphize(to_ty);
|
||||||
|
|
||||||
fn is_fat_ptr<'tcx>(
|
fn is_fat_ptr<'tcx>(
|
||||||
fx: &FunctionCx<'_, 'tcx, impl Backend>,
|
fx: &FunctionCx<'_, 'tcx, impl Backend>,
|
||||||
|
@ -375,9 +376,7 @@ fn trans_stmt<'tcx>(
|
||||||
|ty::TypeAndMut {
|
|ty::TypeAndMut {
|
||||||
ty: pointee_ty,
|
ty: pointee_ty,
|
||||||
mutbl: _,
|
mutbl: _,
|
||||||
}| {
|
}| has_ptr_meta(fx.tcx, pointee_ty),
|
||||||
fx.layout_of(pointee_ty).is_unsized()
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
.unwrap_or(false)
|
.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,
|
FloatTy::F64 => types::F64,
|
||||||
},
|
},
|
||||||
ty::FnPtr(_) => pointer_ty(tcx),
|
ty::FnPtr(_) => pointer_ty(tcx),
|
||||||
ty::RawPtr(TypeAndMut { ty, mutbl: _ }) | ty::Ref(_, ty, _) => {
|
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => {
|
||||||
if ty.is_sized(tcx.at(DUMMY_SP), ParamEnv::reveal_all()) {
|
if has_ptr_meta(tcx, pointee_ty) {
|
||||||
pointer_ty(tcx)
|
|
||||||
} else {
|
|
||||||
return None;
|
return None;
|
||||||
|
} else {
|
||||||
|
pointer_ty(tcx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Param(_) => bug!("ty param {:?}", ty),
|
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 {
|
pub fn codegen_select(bcx: &mut FunctionBuilder, cond: Value, lhs: Value, rhs: Value) -> Value {
|
||||||
let lhs_ty = bcx.func.dfg.value_type(lhs);
|
let lhs_ty = bcx.func.dfg.value_type(lhs);
|
||||||
let rhs_ty = bcx.func.dfg.value_type(rhs);
|
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_lhs: CValue<'tcx>,
|
||||||
in_rhs: CValue<'tcx>,
|
in_rhs: CValue<'tcx>,
|
||||||
) -> CValue<'tcx> {
|
) -> CValue<'tcx> {
|
||||||
let not_fat = match in_lhs.layout().ty.sty {
|
let pointee_ty = in_lhs.layout().ty.builtin_deref(true).unwrap().ty;
|
||||||
ty::RawPtr(TypeAndMut { ty, mutbl: _ }) => {
|
|
||||||
ty.is_sized(fx.tcx.at(DUMMY_SP), ParamEnv::reveal_all())
|
if !has_ptr_meta(fx.tcx, pointee_ty) {
|
||||||
}
|
|
||||||
ty::FnPtr(..) => true,
|
|
||||||
_ => bug!("trans_ptr_binop on non ptr"),
|
|
||||||
};
|
|
||||||
if not_fat {
|
|
||||||
match bin_op {
|
match bin_op {
|
||||||
BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
|
BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
|
||||||
let lhs = in_lhs.load_scalar(fx);
|
let lhs = in_lhs.load_scalar(fx);
|
||||||
|
@ -364,7 +359,6 @@ pub fn trans_ptr_binop<'tcx>(
|
||||||
}
|
}
|
||||||
BinOp::Offset => {
|
BinOp::Offset => {
|
||||||
let (base, offset) = (in_lhs, in_rhs.load_scalar(fx));
|
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 pointee_size = fx.layout_of(pointee_ty).size.bytes();
|
||||||
let ptr_diff = fx.bcx.ins().imul_imm(offset, pointee_size as i64);
|
let ptr_diff = fx.bcx.ins().imul_imm(offset, pointee_size as i64);
|
||||||
let base_val = base.load_scalar(fx);
|
let base_val = base.load_scalar(fx);
|
||||||
|
|
|
@ -136,7 +136,7 @@ impl<'tcx> CValue<'tcx> {
|
||||||
CValueInner::ByRef(addr) => {
|
CValueInner::ByRef(addr) => {
|
||||||
let (a_scalar, b_scalar) = match &layout.abi {
|
let (a_scalar, b_scalar) = match &layout.abi {
|
||||||
layout::Abi::ScalarPair(a, b) => (a, b),
|
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 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());
|
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> {
|
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);
|
let inner_layout = fx.layout_of(self.layout().ty.builtin_deref(true).unwrap().ty);
|
||||||
if !inner_layout.is_unsized() {
|
if has_ptr_meta(fx.tcx, inner_layout.ty) {
|
||||||
CPlace::for_addr(self.to_cvalue(fx).load_scalar(fx), inner_layout)
|
|
||||||
} else {
|
|
||||||
let (addr, extra) = self.to_cvalue(fx).load_scalar_pair(fx);
|
let (addr, extra) = self.to_cvalue(fx).load_scalar_pair(fx);
|
||||||
CPlace::for_addr_with_extra(addr, extra, inner_layout)
|
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>) {
|
pub fn write_place_ref(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>, dest: CPlace<'tcx>) {
|
||||||
if !self.layout().is_unsized() {
|
if has_ptr_meta(fx.tcx, self.layout().ty) {
|
||||||
let ptr = CValue::by_val(self.to_addr(fx), dest.layout());
|
|
||||||
dest.write_cvalue(fx, ptr);
|
|
||||||
} else {
|
|
||||||
let (value, extra) = self.to_addr_maybe_unsized(fx);
|
let (value, extra) = self.to_addr_maybe_unsized(fx);
|
||||||
let ptr = CValue::by_val_pair(
|
let ptr = CValue::by_val_pair(
|
||||||
value,
|
value,
|
||||||
|
@ -516,6 +513,9 @@ impl<'tcx> CPlace<'tcx> {
|
||||||
dest.layout(),
|
dest.layout(),
|
||||||
);
|
);
|
||||||
dest.write_cvalue(fx, ptr);
|
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