about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_trans/glue.rs13
-rw-r--r--src/test/run-pass/issue-36278-prefix-nesting.rs28
2 files changed, 40 insertions, 1 deletions
diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs
index 34c92f334d0..967ecd9ba41 100644
--- a/src/librustc_trans/glue.rs
+++ b/src/librustc_trans/glue.rs
@@ -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 {:#?}",
diff --git a/src/test/run-pass/issue-36278-prefix-nesting.rs b/src/test/run-pass/issue-36278-prefix-nesting.rs
new file mode 100644
index 00000000000..95269d0569d
--- /dev/null
+++ b/src/test/run-pass/issue-36278-prefix-nesting.rs
@@ -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);
+}