Auto merge of #36351 - pnkfelix:fix-36278-size-miscalc, r=eddyb
When sizing DST, don't double-count nested struct prefixes. When computing size of `struct P<T>(Q<T>)`, don't double-count prefix added by `Q` Fix #36278. Fix #36294.
This commit is contained in:
commit
1fca1ab0e7
|
@ -348,9 +348,20 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
|
|||
let layout = ccx.layout_of(t);
|
||||
debug!("DST {} layout: {:?}", t, layout);
|
||||
|
||||
// Returns size in bytes of all fields except the last one
|
||||
// (we will be recursing on the last one).
|
||||
fn local_prefix_bytes(variant: &ty::layout::Struct) -> u64 {
|
||||
let fields = variant.offset_after_field.len();
|
||||
if fields > 1 {
|
||||
variant.offset_after_field[fields - 2].bytes()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
let (sized_size, sized_align) = match *layout {
|
||||
ty::layout::Layout::Univariant { ref variant, .. } => {
|
||||
(variant.min_size().bytes(), variant.align.abi())
|
||||
(local_prefix_bytes(variant), variant.align.abi())
|
||||
}
|
||||
_ => {
|
||||
bug!("size_and_align_of_dst: expcted Univariant for `{}`, found {:#?}",
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Issue 36278: On an unsized struct with >1 level of nontrivial
|
||||
// nesting, ensure we are computing dynamic size of prefix correctly.
|
||||
|
||||
use std::mem;
|
||||
|
||||
const SZ: usize = 100;
|
||||
struct P<T: ?Sized>([u8; SZ], T);
|
||||
|
||||
type Ack<T> = P<P<T>>;
|
||||
|
||||
fn main() {
|
||||
let size_of_sized; let size_of_unsized;
|
||||
let x: Box<Ack<[u8; 0]>> = Box::new(P([0; SZ], P([0; SZ], [0; 0])));
|
||||
size_of_sized = mem::size_of_val::<Ack<_>>(&x);
|
||||
let y: Box<Ack<[u8 ]>> = x;
|
||||
size_of_unsized = mem::size_of_val::<Ack<_>>(&y);
|
||||
assert_eq!(size_of_sized, size_of_unsized);
|
||||
}
|
Loading…
Reference in New Issue