Skip to content

Commit b2d476e

Browse files
committed
type_size now returns None for unsized types
1 parent 921f5af commit b2d476e

File tree

4 files changed

+31
-22
lines changed

4 files changed

+31
-22
lines changed

src/interpreter/mod.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
182182
ty: Ty<'tcx>,
183183
substs: &'tcx Substs<'tcx>
184184
) -> EvalResult<'tcx, Pointer> {
185-
let size = self.type_size_with_substs(ty, substs);
185+
let size = self.type_size_with_substs(ty, substs).expect("cannot alloc memory for unsized type");
186186
let align = self.type_align_with_substs(ty, substs);
187187
self.memory.allocate(size, align)
188188
}
@@ -290,16 +290,21 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
290290
self.tcx.normalize_associated_type(&substituted)
291291
}
292292

293-
fn type_size(&self, ty: Ty<'tcx>) -> usize {
293+
fn type_size(&self, ty: Ty<'tcx>) -> Option<usize> {
294294
self.type_size_with_substs(ty, self.substs())
295295
}
296296

297297
fn type_align(&self, ty: Ty<'tcx>) -> usize {
298298
self.type_align_with_substs(ty, self.substs())
299299
}
300300

301-
fn type_size_with_substs(&self, ty: Ty<'tcx>, substs: &'tcx Substs<'tcx>) -> usize {
302-
self.type_layout_with_substs(ty, substs).size(&self.tcx.data_layout).bytes() as usize
301+
fn type_size_with_substs(&self, ty: Ty<'tcx>, substs: &'tcx Substs<'tcx>) -> Option<usize> {
302+
let layout = self.type_layout_with_substs(ty, substs);
303+
if layout.is_unsized() {
304+
None
305+
} else {
306+
Some(layout.size(&self.tcx.data_layout).bytes() as usize)
307+
}
303308
}
304309

305310
fn type_align_with_substs(&self, ty: Ty<'tcx>, substs: &'tcx Substs<'tcx>) -> usize {
@@ -480,7 +485,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
480485

481486
Array { .. } => {
482487
let elem_size = match dest_ty.sty {
483-
ty::TyArray(elem_ty, _) => self.type_size(elem_ty) as u64,
488+
ty::TyArray(elem_ty, _) => self.type_size(elem_ty).expect("array elements are sized") as u64,
484489
_ => bug!("tried to assign {:?} to non-array type {:?}", kind, dest_ty),
485490
};
486491
let offsets = (0..).map(|i| i * elem_size);
@@ -534,7 +539,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
534539
} else {
535540
for operand in operands {
536541
let operand_ty = self.operand_ty(operand);
537-
assert_eq!(self.type_size(operand_ty), 0);
542+
assert_eq!(self.type_size(operand_ty), Some(0));
538543
}
539544
let offset = self.nonnull_offset(dest_ty, nndiscr, discrfield)?;
540545

@@ -576,7 +581,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
576581
ty::TyArray(elem_ty, n) => (elem_ty, n),
577582
_ => bug!("tried to assign array-repeat to non-array type {:?}", dest_ty),
578583
};
579-
let elem_size = self.type_size(elem_ty);
584+
let elem_size = self.type_size(elem_ty).expect("repeat element type must be sized");
580585
let value = self.eval_operand(operand)?;
581586

582587
// FIXME(solson)
@@ -991,7 +996,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
991996
let (base_ptr, _) = base.to_ptr_and_extra();
992997

993998
let (elem_ty, len) = base.elem_ty_and_len(base_ty);
994-
let elem_size = self.type_size(elem_ty);
999+
let elem_size = self.type_size(elem_ty).expect("slice element must be sized");
9951000
let n_ptr = self.eval_operand(operand)?;
9961001
let usize = self.tcx.types.usize;
9971002
let n = self.value_to_primval(n_ptr, usize)?
@@ -1007,7 +1012,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
10071012
let (base_ptr, _) = base.to_ptr_and_extra();
10081013

10091014
let (elem_ty, n) = base.elem_ty_and_len(base_ty);
1010-
let elem_size = self.type_size(elem_ty);
1015+
let elem_size = self.type_size(elem_ty).expect("sequence element must be sized");
10111016
assert!(n >= min_length as u64);
10121017

10131018
let index = if from_end {
@@ -1026,7 +1031,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
10261031
let (base_ptr, _) = base.to_ptr_and_extra();
10271032

10281033
let (elem_ty, n) = base.elem_ty_and_len(base_ty);
1029-
let elem_size = self.type_size(elem_ty);
1034+
let elem_size = self.type_size(elem_ty).expect("slice element must be sized");
10301035
assert!((from as u64) <= n - (to as u64));
10311036
let ptr = base_ptr.offset(from as isize * elem_size as isize);
10321037
let extra = LvalueExtra::Length(n - to as u64 - from as u64);
@@ -1046,7 +1051,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
10461051
}
10471052

10481053
fn copy(&mut self, src: Pointer, dest: Pointer, ty: Ty<'tcx>) -> EvalResult<'tcx, ()> {
1049-
let size = self.type_size(ty);
1054+
let size = self.type_size(ty).expect("cannot copy from an unsized type");
10501055
let align = self.type_align(ty);
10511056
self.memory.copy(src, dest, size, align)?;
10521057
Ok(())
@@ -1512,7 +1517,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
15121517
for (i, (src_f, dst_f)) in iter {
15131518
let src_fty = monomorphize_field_ty(self.tcx, src_f, substs_a);
15141519
let dst_fty = monomorphize_field_ty(self.tcx, dst_f, substs_b);
1515-
if self.type_size(dst_fty) == 0 {
1520+
if self.type_size(dst_fty) == Some(0) {
15161521
continue;
15171522
}
15181523
let src_field_offset = self.get_field_offset(src_ty, i)?.bytes() as isize;

src/interpreter/terminator/intrinsics.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
9696
"copy_nonoverlapping" => {
9797
// FIXME: check whether overlapping occurs
9898
let elem_ty = substs.type_at(0);
99-
let elem_size = self.type_size(elem_ty);
99+
let elem_size = self.type_size(elem_ty).expect("cannot copy unsized value");
100100
let elem_align = self.type_align(elem_ty);
101101
let src = arg_vals[0].read_ptr(&self.memory)?;
102102
let dest = arg_vals[1].read_ptr(&self.memory)?;
@@ -230,7 +230,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
230230

231231
"offset" => {
232232
let pointee_ty = substs.type_at(0);
233-
let pointee_size = self.type_size(pointee_ty) as isize;
233+
let pointee_size = self.type_size(pointee_ty).expect("cannot offset a pointer to an unsized type") as isize;
234234
let offset = self.value_to_primval(arg_vals[1], isize)?
235235
.expect_int("offset second arg not isize");
236236

@@ -281,7 +281,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
281281

282282
"size_of" => {
283283
let ty = substs.type_at(0);
284-
let size = self.type_size(ty) as u64;
284+
// FIXME: change the `box_free` lang item to take `T: ?Sized` and have it use the
285+
// `size_of_val` intrinsic, then change this back to
286+
// .expect("size_of intrinsic called on unsized value")
287+
// see https://github.com/rust-lang/rust/pull/37708
288+
let size = self.type_size(ty).unwrap_or(!0) as u64;
285289
let size_val = self.usize_primval(size);
286290
self.write_primval(dest, size_val)?;
287291
}
@@ -360,8 +364,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
360364
value: Value,
361365
) -> EvalResult<'tcx, (u64, u64)> {
362366
let pointer_size = self.memory.pointer_size();
363-
if self.type_is_sized(ty) {
364-
Ok((self.type_size(ty) as u64, self.type_align(ty) as u64))
367+
if let Some(size) = self.type_size(ty) {
368+
Ok((size as u64, self.type_align(ty) as u64))
365369
} else {
366370
match ty.sty {
367371
ty::TyAdt(def, substs) => {
@@ -435,7 +439,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
435439

436440
ty::TySlice(_) | ty::TyStr => {
437441
let elem_ty = ty.sequence_element_type(self.tcx);
438-
let elem_size = self.type_size(elem_ty) as u64;
442+
let elem_size = self.type_size(elem_ty).expect("slice element must be sized") as u64;
439443
let len = value.expect_slice_len(&self.memory)?;
440444
let align = self.type_align(elem_ty);
441445
Ok((len * elem_size, align as u64))

src/interpreter/terminator/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
193193

194194
Abi::C => {
195195
let ty = fn_ty.sig.0.output;
196-
let size = self.type_size(ty);
196+
let size = self.type_size(ty).expect("function return type cannot be unsized");
197197
let (ret, target) = destination.unwrap();
198198
self.call_c_abi(def_id, arg_operands, ret, size)?;
199199
self.goto_block(target);
@@ -655,7 +655,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
655655
Lvalue::Ptr { ptr, extra: LvalueExtra::Length(len) } => (ptr, len as isize),
656656
_ => bug!("expected an lvalue with a length"),
657657
};
658-
let size = self.type_size(elem_ty) as isize;
658+
let size = self.type_size(elem_ty).expect("slice element must be sized") as isize;
659659
// FIXME: this creates a lot of stack frames if the element type has
660660
// a drop impl
661661
for i in 0..len {
@@ -668,7 +668,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
668668
Lvalue::Ptr { ptr, extra } => (ptr, extra),
669669
_ => bug!("expected an lvalue with optional extra data"),
670670
};
671-
let size = self.type_size(elem_ty) as isize;
671+
let size = self.type_size(elem_ty).expect("array element cannot be unsized") as isize;
672672
// FIXME: this creates a lot of stack frames if the element type has
673673
// a drop impl
674674
for i in 0..len {

src/interpreter/vtable.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
7878
}
7979
}).collect();
8080

81-
let size = self.type_size(trait_ref.self_ty());
81+
let size = self.type_size(trait_ref.self_ty()).expect("can't create a vtable for an unsized type");
8282
let align = self.type_align(trait_ref.self_ty());
8383

8484
let ptr_size = self.memory.pointer_size();

0 commit comments

Comments
 (0)