type_size
now returns None
for unsized types
This commit is contained in:
parent
921f5af1fe
commit
b2d476eb38
4 changed files with 31 additions and 22 deletions
|
@ -182,7 +182,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
ty: Ty<'tcx>,
|
||||
substs: &'tcx Substs<'tcx>
|
||||
) -> EvalResult<'tcx, Pointer> {
|
||||
let size = self.type_size_with_substs(ty, substs);
|
||||
let size = self.type_size_with_substs(ty, substs).expect("cannot alloc memory for unsized type");
|
||||
let align = self.type_align_with_substs(ty, substs);
|
||||
self.memory.allocate(size, align)
|
||||
}
|
||||
|
@ -290,7 +290,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
self.tcx.normalize_associated_type(&substituted)
|
||||
}
|
||||
|
||||
fn type_size(&self, ty: Ty<'tcx>) -> usize {
|
||||
fn type_size(&self, ty: Ty<'tcx>) -> Option<usize> {
|
||||
self.type_size_with_substs(ty, self.substs())
|
||||
}
|
||||
|
||||
|
@ -298,8 +298,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
self.type_align_with_substs(ty, self.substs())
|
||||
}
|
||||
|
||||
fn type_size_with_substs(&self, ty: Ty<'tcx>, substs: &'tcx Substs<'tcx>) -> usize {
|
||||
self.type_layout_with_substs(ty, substs).size(&self.tcx.data_layout).bytes() as usize
|
||||
fn type_size_with_substs(&self, ty: Ty<'tcx>, substs: &'tcx Substs<'tcx>) -> Option<usize> {
|
||||
let layout = self.type_layout_with_substs(ty, substs);
|
||||
if layout.is_unsized() {
|
||||
None
|
||||
} else {
|
||||
Some(layout.size(&self.tcx.data_layout).bytes() as usize)
|
||||
}
|
||||
}
|
||||
|
||||
fn type_align_with_substs(&self, ty: Ty<'tcx>, substs: &'tcx Substs<'tcx>) -> usize {
|
||||
|
@ -480,7 +485,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
|
||||
Array { .. } => {
|
||||
let elem_size = match dest_ty.sty {
|
||||
ty::TyArray(elem_ty, _) => self.type_size(elem_ty) as u64,
|
||||
ty::TyArray(elem_ty, _) => self.type_size(elem_ty).expect("array elements are sized") as u64,
|
||||
_ => bug!("tried to assign {:?} to non-array type {:?}", kind, dest_ty),
|
||||
};
|
||||
let offsets = (0..).map(|i| i * elem_size);
|
||||
|
@ -534,7 +539,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
} else {
|
||||
for operand in operands {
|
||||
let operand_ty = self.operand_ty(operand);
|
||||
assert_eq!(self.type_size(operand_ty), 0);
|
||||
assert_eq!(self.type_size(operand_ty), Some(0));
|
||||
}
|
||||
let offset = self.nonnull_offset(dest_ty, nndiscr, discrfield)?;
|
||||
|
||||
|
@ -576,7 +581,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
ty::TyArray(elem_ty, n) => (elem_ty, n),
|
||||
_ => bug!("tried to assign array-repeat to non-array type {:?}", dest_ty),
|
||||
};
|
||||
let elem_size = self.type_size(elem_ty);
|
||||
let elem_size = self.type_size(elem_ty).expect("repeat element type must be sized");
|
||||
let value = self.eval_operand(operand)?;
|
||||
|
||||
// FIXME(solson)
|
||||
|
@ -991,7 +996,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
let (base_ptr, _) = base.to_ptr_and_extra();
|
||||
|
||||
let (elem_ty, len) = base.elem_ty_and_len(base_ty);
|
||||
let elem_size = self.type_size(elem_ty);
|
||||
let elem_size = self.type_size(elem_ty).expect("slice element must be sized");
|
||||
let n_ptr = self.eval_operand(operand)?;
|
||||
let usize = self.tcx.types.usize;
|
||||
let n = self.value_to_primval(n_ptr, usize)?
|
||||
|
@ -1007,7 +1012,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
let (base_ptr, _) = base.to_ptr_and_extra();
|
||||
|
||||
let (elem_ty, n) = base.elem_ty_and_len(base_ty);
|
||||
let elem_size = self.type_size(elem_ty);
|
||||
let elem_size = self.type_size(elem_ty).expect("sequence element must be sized");
|
||||
assert!(n >= min_length as u64);
|
||||
|
||||
let index = if from_end {
|
||||
|
@ -1026,7 +1031,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
let (base_ptr, _) = base.to_ptr_and_extra();
|
||||
|
||||
let (elem_ty, n) = base.elem_ty_and_len(base_ty);
|
||||
let elem_size = self.type_size(elem_ty);
|
||||
let elem_size = self.type_size(elem_ty).expect("slice element must be sized");
|
||||
assert!((from as u64) <= n - (to as u64));
|
||||
let ptr = base_ptr.offset(from as isize * elem_size as isize);
|
||||
let extra = LvalueExtra::Length(n - to as u64 - from as u64);
|
||||
|
@ -1046,7 +1051,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn copy(&mut self, src: Pointer, dest: Pointer, ty: Ty<'tcx>) -> EvalResult<'tcx, ()> {
|
||||
let size = self.type_size(ty);
|
||||
let size = self.type_size(ty).expect("cannot copy from an unsized type");
|
||||
let align = self.type_align(ty);
|
||||
self.memory.copy(src, dest, size, align)?;
|
||||
Ok(())
|
||||
|
@ -1512,7 +1517,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
for (i, (src_f, dst_f)) in iter {
|
||||
let src_fty = monomorphize_field_ty(self.tcx, src_f, substs_a);
|
||||
let dst_fty = monomorphize_field_ty(self.tcx, dst_f, substs_b);
|
||||
if self.type_size(dst_fty) == 0 {
|
||||
if self.type_size(dst_fty) == Some(0) {
|
||||
continue;
|
||||
}
|
||||
let src_field_offset = self.get_field_offset(src_ty, i)?.bytes() as isize;
|
||||
|
|
|
@ -96,7 +96,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
"copy_nonoverlapping" => {
|
||||
// FIXME: check whether overlapping occurs
|
||||
let elem_ty = substs.type_at(0);
|
||||
let elem_size = self.type_size(elem_ty);
|
||||
let elem_size = self.type_size(elem_ty).expect("cannot copy unsized value");
|
||||
let elem_align = self.type_align(elem_ty);
|
||||
let src = arg_vals[0].read_ptr(&self.memory)?;
|
||||
let dest = arg_vals[1].read_ptr(&self.memory)?;
|
||||
|
@ -230,7 +230,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
|
||||
"offset" => {
|
||||
let pointee_ty = substs.type_at(0);
|
||||
let pointee_size = self.type_size(pointee_ty) as isize;
|
||||
let pointee_size = self.type_size(pointee_ty).expect("cannot offset a pointer to an unsized type") as isize;
|
||||
let offset = self.value_to_primval(arg_vals[1], isize)?
|
||||
.expect_int("offset second arg not isize");
|
||||
|
||||
|
@ -281,7 +281,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
|
||||
"size_of" => {
|
||||
let ty = substs.type_at(0);
|
||||
let size = self.type_size(ty) as u64;
|
||||
// FIXME: change the `box_free` lang item to take `T: ?Sized` and have it use the
|
||||
// `size_of_val` intrinsic, then change this back to
|
||||
// .expect("size_of intrinsic called on unsized value")
|
||||
// see https://github.com/rust-lang/rust/pull/37708
|
||||
let size = self.type_size(ty).unwrap_or(!0) as u64;
|
||||
let size_val = self.usize_primval(size);
|
||||
self.write_primval(dest, size_val)?;
|
||||
}
|
||||
|
@ -360,8 +364,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
value: Value,
|
||||
) -> EvalResult<'tcx, (u64, u64)> {
|
||||
let pointer_size = self.memory.pointer_size();
|
||||
if self.type_is_sized(ty) {
|
||||
Ok((self.type_size(ty) as u64, self.type_align(ty) as u64))
|
||||
if let Some(size) = self.type_size(ty) {
|
||||
Ok((size as u64, self.type_align(ty) as u64))
|
||||
} else {
|
||||
match ty.sty {
|
||||
ty::TyAdt(def, substs) => {
|
||||
|
@ -435,7 +439,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
|
||||
ty::TySlice(_) | ty::TyStr => {
|
||||
let elem_ty = ty.sequence_element_type(self.tcx);
|
||||
let elem_size = self.type_size(elem_ty) as u64;
|
||||
let elem_size = self.type_size(elem_ty).expect("slice element must be sized") as u64;
|
||||
let len = value.expect_slice_len(&self.memory)?;
|
||||
let align = self.type_align(elem_ty);
|
||||
Ok((len * elem_size, align as u64))
|
||||
|
|
|
@ -193,7 +193,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
|
||||
Abi::C => {
|
||||
let ty = fn_ty.sig.0.output;
|
||||
let size = self.type_size(ty);
|
||||
let size = self.type_size(ty).expect("function return type cannot be unsized");
|
||||
let (ret, target) = destination.unwrap();
|
||||
self.call_c_abi(def_id, arg_operands, ret, size)?;
|
||||
self.goto_block(target);
|
||||
|
@ -655,7 +655,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
Lvalue::Ptr { ptr, extra: LvalueExtra::Length(len) } => (ptr, len as isize),
|
||||
_ => bug!("expected an lvalue with a length"),
|
||||
};
|
||||
let size = self.type_size(elem_ty) as isize;
|
||||
let size = self.type_size(elem_ty).expect("slice element must be sized") as isize;
|
||||
// FIXME: this creates a lot of stack frames if the element type has
|
||||
// a drop impl
|
||||
for i in 0..len {
|
||||
|
@ -668,7 +668,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
Lvalue::Ptr { ptr, extra } => (ptr, extra),
|
||||
_ => bug!("expected an lvalue with optional extra data"),
|
||||
};
|
||||
let size = self.type_size(elem_ty) as isize;
|
||||
let size = self.type_size(elem_ty).expect("array element cannot be unsized") as isize;
|
||||
// FIXME: this creates a lot of stack frames if the element type has
|
||||
// a drop impl
|
||||
for i in 0..len {
|
||||
|
|
|
@ -78,7 +78,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
}
|
||||
}).collect();
|
||||
|
||||
let size = self.type_size(trait_ref.self_ty());
|
||||
let size = self.type_size(trait_ref.self_ty()).expect("can't create a vtable for an unsized type");
|
||||
let align = self.type_align(trait_ref.self_ty());
|
||||
|
||||
let ptr_size = self.memory.pointer_size();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue