Skip to content

Commit 14d7501

Browse files
authored
Merge pull request rust-lang#128 from oli-obk/align_thyself
fix size of dst in size_of_val intrinsic
2 parents bc5d9b6 + d23c3ae commit 14d7501

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

src/terminator/intrinsic.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc::hir::def_id::DefId;
22
use rustc::mir;
3-
use rustc::ty::layout::Layout;
3+
use rustc::ty::layout::{Layout, Size, Align};
44
use rustc::ty::subst::Substs;
55
use rustc::ty::{self, Ty};
66

@@ -426,17 +426,14 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
426426

427427
let (sized_size, sized_align) = match *layout {
428428
ty::layout::Layout::Univariant { ref variant, .. } => {
429-
// The offset of the start of the last field gives the size of the
430-
// sized part of the type.
431-
let size = variant.offsets.last().map_or(0, |f| f.bytes());
432-
(size, variant.align.abi())
429+
(variant.offsets.last().map_or(0, |o| o.bytes()), variant.align)
433430
}
434431
_ => {
435432
bug!("size_and_align_of_dst: expcted Univariant for `{}`, found {:#?}",
436433
ty, layout);
437434
}
438435
};
439-
debug!("DST {} statically sized prefix size: {} align: {}",
436+
debug!("DST {} statically sized prefix size: {} align: {:?}",
440437
ty, sized_size, sized_align);
441438

442439
// Recurse to get the size of the dynamically sized field (must be
@@ -457,7 +454,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
457454

458455
// Choose max of two known alignments (combined value must
459456
// be aligned according to more restrictive of the two).
460-
let align = ::std::cmp::max(sized_align, unsized_align);
457+
let align = sized_align.max(Align::from_bytes(unsized_align, unsized_align).unwrap());
461458

462459
// Issue #27023: must add any necessary padding to `size`
463460
// (to make it a multiple of `align`) before returning it.
@@ -470,11 +467,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
470467
//
471468
// `(size + (align-1)) & -align`
472469

473-
if size & (align - 1) != 0 {
474-
Ok((size + align, align))
475-
} else {
476-
Ok((size, align))
477-
}
470+
let size = Size::from_bytes(size).abi_align(align).bytes();
471+
Ok((size, align.abi()))
478472
}
479473
ty::TyDynamic(..) => {
480474
let (_, vtable) = value.expect_ptr_vtable_pair(&self.memory)?;

tests/run-pass/issue-35815.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![allow(dead_code)]
12+
13+
use std::mem;
14+
15+
struct Foo<T: ?Sized> {
16+
a: i64,
17+
b: bool,
18+
c: T,
19+
}
20+
21+
fn main() {
22+
let foo: &Foo<i32> = &Foo { a: 1, b: false, c: 2i32 };
23+
let foo_unsized: &Foo<Send> = foo;
24+
assert_eq!(mem::size_of_val(foo), mem::size_of_val(foo_unsized));
25+
}

0 commit comments

Comments
 (0)