Skip to content

Commit c533cf8

Browse files
committed
fix size_of_val on unsized tuples
1 parent 8deb938 commit c533cf8

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

src/librustc_mir/interpret/eval_context.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -280,13 +280,13 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
280280
pub fn size_and_align_of_dst(
281281
&mut self,
282282
ty: ty::Ty<'tcx>,
283-
value: Value,
283+
value: Value, // This has to be a fat ptr; we only care about the "extra" data in it.
284284
) -> EvalResult<'tcx, (u64, u64)> {
285285
if let Some(size) = self.type_size(ty)? {
286286
Ok((size as u64, self.type_align(ty)? as u64))
287287
} else {
288288
match ty.sty {
289-
ty::TyAdt(def, substs) => {
289+
ty::TyAdt(..) | ty::TyTuple(..) => {
290290
// First get the size of all statically known fields.
291291
// Don't use type_of::sizing_type_of because that expects t to be sized,
292292
// and it also rounds up to alignment, which we want to avoid,
@@ -309,9 +309,19 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
309309

310310
// Recurse to get the size of the dynamically sized field (must be
311311
// the last field).
312-
let last_field = def.struct_variant().fields.last().unwrap();
313-
let field_ty = self.field_ty(substs, last_field);
314-
let (unsized_size, unsized_align) = self.size_and_align_of_dst(field_ty, value)?;
312+
let (unsized_size, unsized_align) = match ty.sty {
313+
ty::TyAdt(def, substs) => {
314+
let last_field = def.struct_variant().fields.last().unwrap();
315+
let field_ty = self.field_ty(substs, last_field);
316+
self.size_and_align_of_dst(field_ty, value)?
317+
}
318+
ty::TyTuple(ref types, _) => {
319+
let field_ty = types.last().unwrap();
320+
let field_ty = self.tcx.normalize_associated_type(field_ty);
321+
self.size_and_align_of_dst(field_ty, value)?
322+
}
323+
_ => bug!("We already checked that we know this type"),
324+
};
315325

316326
// FIXME (#26403, #27023): We should be adding padding
317327
// to `sized_size` (to accommodate the `unsized_align`

tests/run-pass-fullmir/unsized-tuple-impls.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
#![feature(unsized_tuple_coercion)]
12+
use std::mem;
1213

1314
fn main() {
1415
let x : &(i32, i32, [i32]) = &(0, 1, [2, 3]);
@@ -18,4 +19,5 @@ fn main() {
1819
assert_eq!(a, [x, y]);
1920

2021
assert_eq!(&format!("{:?}", a), "[(0, 1, [2, 3]), (0, 1, [2, 3, 4])]");
22+
assert_eq!(mem::size_of_val(x), 16);
2123
}

0 commit comments

Comments
 (0)