Skip to content

Commit

Permalink
Merge pull request rust-lang#125 from oli-obk/master
Browse files Browse the repository at this point in the history
compute the offset of dst fields by checking the vtable
  • Loading branch information
solson authored Feb 9, 2017
2 parents d6bc508 + 8030800 commit fad6086
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
12 changes: 10 additions & 2 deletions src/lvalue.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use rustc::hir::def_id::DefId;
use rustc::mir;
use rustc::ty::layout::Size;
use rustc::ty::layout::{Size, Align};
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty};
use rustc_data_structures::indexed_vec::Idx;
Expand Down Expand Up @@ -214,7 +214,15 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
_ => bug!("field access on non-product type: {:?}", base_layout),
};

let ptr = base_ptr.offset(offset.bytes());
let offset = match base_extra {
LvalueExtra::Vtable(tab) => {
let (_, align) = self.size_and_align_of_dst(base_ty, Value::ByValPair(PrimVal::Ptr(base_ptr), PrimVal::Ptr(tab)))?;
offset.abi_align(Align::from_bytes(align, align).unwrap()).bytes()
}
_ => offset.bytes(),
};

let ptr = base_ptr.offset(offset);

if packed {
let size = self.type_size(field_ty)?.expect("packed struct must be sized");
Expand Down
2 changes: 1 addition & 1 deletion src/terminator/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
Ok(())
}

fn size_and_align_of_dst(
pub fn size_and_align_of_dst(
&self,
ty: ty::Ty<'tcx>,
value: Value,
Expand Down
30 changes: 30 additions & 0 deletions tests/run-pass/dst-field-align.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2015 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.

#![allow(dead_code)]

struct Foo<T: ?Sized> {
a: u16,
b: T
}

trait Bar {
fn get(&self) -> usize;
}

impl Bar for usize {
fn get(&self) -> usize { *self }
}

fn main() {
let f : Foo<usize> = Foo { a: 0, b: 11 };
let f : &Foo<Bar> = &f;
assert_eq!(f.b.get(), 11);
}

0 comments on commit fad6086

Please sign in to comment.