fix size_of_val on unsized tuples
This commit is contained in:
parent
8deb9387e9
commit
c533cf8496
2 changed files with 17 additions and 5 deletions
|
@ -280,13 +280,13 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
||||||
pub fn size_and_align_of_dst(
|
pub fn size_and_align_of_dst(
|
||||||
&mut self,
|
&mut self,
|
||||||
ty: ty::Ty<'tcx>,
|
ty: ty::Ty<'tcx>,
|
||||||
value: Value,
|
value: Value, // This has to be a fat ptr; we only care about the "extra" data in it.
|
||||||
) -> EvalResult<'tcx, (u64, u64)> {
|
) -> EvalResult<'tcx, (u64, u64)> {
|
||||||
if let Some(size) = self.type_size(ty)? {
|
if let Some(size) = self.type_size(ty)? {
|
||||||
Ok((size as u64, self.type_align(ty)? as u64))
|
Ok((size as u64, self.type_align(ty)? as u64))
|
||||||
} else {
|
} else {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TyAdt(def, substs) => {
|
ty::TyAdt(..) | ty::TyTuple(..) => {
|
||||||
// First get the size of all statically known fields.
|
// First get the size of all statically known fields.
|
||||||
// Don't use type_of::sizing_type_of because that expects t to be sized,
|
// Don't use type_of::sizing_type_of because that expects t to be sized,
|
||||||
// and it also rounds up to alignment, which we want to avoid,
|
// 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> {
|
||||||
|
|
||||||
// Recurse to get the size of the dynamically sized field (must be
|
// Recurse to get the size of the dynamically sized field (must be
|
||||||
// the last field).
|
// the last field).
|
||||||
let last_field = def.struct_variant().fields.last().unwrap();
|
let (unsized_size, unsized_align) = match ty.sty {
|
||||||
let field_ty = self.field_ty(substs, last_field);
|
ty::TyAdt(def, substs) => {
|
||||||
let (unsized_size, unsized_align) = self.size_and_align_of_dst(field_ty, value)?;
|
let last_field = def.struct_variant().fields.last().unwrap();
|
||||||
|
let field_ty = self.field_ty(substs, last_field);
|
||||||
|
self.size_and_align_of_dst(field_ty, value)?
|
||||||
|
}
|
||||||
|
ty::TyTuple(ref types, _) => {
|
||||||
|
let field_ty = types.last().unwrap();
|
||||||
|
let field_ty = self.tcx.normalize_associated_type(field_ty);
|
||||||
|
self.size_and_align_of_dst(field_ty, value)?
|
||||||
|
}
|
||||||
|
_ => bug!("We already checked that we know this type"),
|
||||||
|
};
|
||||||
|
|
||||||
// FIXME (#26403, #27023): We should be adding padding
|
// FIXME (#26403, #27023): We should be adding padding
|
||||||
// to `sized_size` (to accommodate the `unsized_align`
|
// to `sized_size` (to accommodate the `unsized_align`
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![feature(unsized_tuple_coercion)]
|
#![feature(unsized_tuple_coercion)]
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x : &(i32, i32, [i32]) = &(0, 1, [2, 3]);
|
let x : &(i32, i32, [i32]) = &(0, 1, [2, 3]);
|
||||||
|
@ -18,4 +19,5 @@ fn main() {
|
||||||
assert_eq!(a, [x, y]);
|
assert_eq!(a, [x, y]);
|
||||||
|
|
||||||
assert_eq!(&format!("{:?}", a), "[(0, 1, [2, 3]), (0, 1, [2, 3, 4])]");
|
assert_eq!(&format!("{:?}", a), "[(0, 1, [2, 3]), (0, 1, [2, 3, 4])]");
|
||||||
|
assert_eq!(mem::size_of_val(x), 16);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue