Skip to content

Commit c34ada7

Browse files
committed
Fix foreign type handling
1 parent b267995 commit c34ada7

File tree

4 files changed

+27
-24
lines changed

4 files changed

+27
-24
lines changed

src/base.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ fn trans_stmt<'tcx>(
365365
Rvalue::Cast(CastKind::Misc, operand, to_ty) => {
366366
let operand = trans_operand(fx, operand);
367367
let from_ty = operand.layout().ty;
368+
let to_ty = fx.monomorphize(to_ty);
368369

369370
fn is_fat_ptr<'tcx>(
370371
fx: &FunctionCx<'_, 'tcx, impl Backend>,
@@ -375,9 +376,7 @@ fn trans_stmt<'tcx>(
375376
|ty::TypeAndMut {
376377
ty: pointee_ty,
377378
mutbl: _,
378-
}| {
379-
fx.layout_of(pointee_ty).is_unsized()
380-
},
379+
}| has_ptr_meta(fx.tcx, pointee_ty),
381380
)
382381
.unwrap_or(false)
383382
}

src/common.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,28 @@ pub fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types:
6060
FloatTy::F64 => types::F64,
6161
},
6262
ty::FnPtr(_) => pointer_ty(tcx),
63-
ty::RawPtr(TypeAndMut { ty, mutbl: _ }) | ty::Ref(_, ty, _) => {
64-
if ty.is_sized(tcx.at(DUMMY_SP), ParamEnv::reveal_all()) {
65-
pointer_ty(tcx)
66-
} else {
63+
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => {
64+
if has_ptr_meta(tcx, pointee_ty) {
6765
return None;
66+
} else {
67+
pointer_ty(tcx)
6868
}
6969
}
7070
ty::Param(_) => bug!("ty param {:?}", ty),
7171
_ => return None,
7272
})
7373
}
7474

75+
/// Is a pointer to this type a fat ptr?
76+
pub fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
77+
let ptr_ty = tcx.mk_ptr(TypeAndMut { ty, mutbl: rustc::hir::Mutability::MutImmutable });
78+
match &tcx.layout_of(ParamEnv::reveal_all().and(ptr_ty)).unwrap().abi {
79+
Abi::Scalar(_) => false,
80+
Abi::ScalarPair(_, _) => true,
81+
abi => unreachable!("Abi of ptr to {:?} is {:?}???", ty, abi),
82+
}
83+
}
84+
7585
pub fn codegen_select(bcx: &mut FunctionBuilder, cond: Value, lhs: Value, rhs: Value) -> Value {
7686
let lhs_ty = bcx.func.dfg.value_type(lhs);
7787
let rhs_ty = bcx.func.dfg.value_type(rhs);

src/num.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -347,14 +347,9 @@ pub fn trans_ptr_binop<'tcx>(
347347
in_lhs: CValue<'tcx>,
348348
in_rhs: CValue<'tcx>,
349349
) -> CValue<'tcx> {
350-
let not_fat = match in_lhs.layout().ty.sty {
351-
ty::RawPtr(TypeAndMut { ty, mutbl: _ }) => {
352-
ty.is_sized(fx.tcx.at(DUMMY_SP), ParamEnv::reveal_all())
353-
}
354-
ty::FnPtr(..) => true,
355-
_ => bug!("trans_ptr_binop on non ptr"),
356-
};
357-
if not_fat {
350+
let pointee_ty = in_lhs.layout().ty.builtin_deref(true).unwrap().ty;
351+
352+
if !has_ptr_meta(fx.tcx, pointee_ty) {
358353
match bin_op {
359354
BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
360355
let lhs = in_lhs.load_scalar(fx);
@@ -364,7 +359,6 @@ pub fn trans_ptr_binop<'tcx>(
364359
}
365360
BinOp::Offset => {
366361
let (base, offset) = (in_lhs, in_rhs.load_scalar(fx));
367-
let pointee_ty = base.layout().ty.builtin_deref(true).unwrap().ty;
368362
let pointee_size = fx.layout_of(pointee_ty).size.bytes();
369363
let ptr_diff = fx.bcx.ins().imul_imm(offset, pointee_size as i64);
370364
let base_val = base.load_scalar(fx);

src/value_and_place.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ impl<'tcx> CValue<'tcx> {
136136
CValueInner::ByRef(addr) => {
137137
let (a_scalar, b_scalar) = match &layout.abi {
138138
layout::Abi::ScalarPair(a, b) => (a, b),
139-
_ => unreachable!(),
139+
_ => unreachable!("load_scalar_pair({:?})", self),
140140
};
141141
let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar);
142142
let clif_ty1 = scalar_to_clif_type(fx.tcx, a_scalar.clone());
@@ -496,26 +496,26 @@ impl<'tcx> CPlace<'tcx> {
496496

497497
pub fn place_deref(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>) -> CPlace<'tcx> {
498498
let inner_layout = fx.layout_of(self.layout().ty.builtin_deref(true).unwrap().ty);
499-
if !inner_layout.is_unsized() {
500-
CPlace::for_addr(self.to_cvalue(fx).load_scalar(fx), inner_layout)
501-
} else {
499+
if has_ptr_meta(fx.tcx, inner_layout.ty) {
502500
let (addr, extra) = self.to_cvalue(fx).load_scalar_pair(fx);
503501
CPlace::for_addr_with_extra(addr, extra, inner_layout)
502+
} else {
503+
CPlace::for_addr(self.to_cvalue(fx).load_scalar(fx), inner_layout)
504504
}
505505
}
506506

507507
pub fn write_place_ref(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>, dest: CPlace<'tcx>) {
508-
if !self.layout().is_unsized() {
509-
let ptr = CValue::by_val(self.to_addr(fx), dest.layout());
510-
dest.write_cvalue(fx, ptr);
511-
} else {
508+
if has_ptr_meta(fx.tcx, self.layout().ty) {
512509
let (value, extra) = self.to_addr_maybe_unsized(fx);
513510
let ptr = CValue::by_val_pair(
514511
value,
515512
extra.expect("unsized type without metadata"),
516513
dest.layout(),
517514
);
518515
dest.write_cvalue(fx, ptr);
516+
} else {
517+
let ptr = CValue::by_val(self.to_addr(fx), dest.layout());
518+
dest.write_cvalue(fx, ptr);
519519
}
520520
}
521521

0 commit comments

Comments
 (0)