1
Fork 0

enable A<Struct> -> A<Trait> downcasting

This commit is contained in:
Oliver Schneider 2016-09-21 18:00:04 +02:00
parent d5e44712a4
commit 145cbf844c
No known key found for this signature in database
GPG key ID: 56D6EEA0FC67AC46
2 changed files with 19 additions and 2 deletions

View file

@ -627,6 +627,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let src_pointee_ty = pointee_type(src_ty).unwrap();
let dest_pointee_ty = pointee_type(dest_ty).unwrap();
// A<Struct> -> A<Trait> conversion
let (src_pointee_ty, dest_pointee_ty) = self.tcx.struct_lockstep_tails(src_pointee_ty, dest_pointee_ty);
match (&src_pointee_ty.sty, &dest_pointee_ty.sty) {
(&ty::TyArray(_, length), &ty::TySlice(_)) => {
self.memory.write_usize(extra, length as u64)?;
@ -881,7 +884,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
use rustc::mir::repr::ProjectionElem::*;
match proj.elem {
Field(field, _) => {
Field(field, field_ty) => {
use rustc::ty::layout::Layout::*;
let variant = match *base_layout {
Univariant { ref variant, .. } => variant,
@ -901,7 +904,15 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
};
let offset = variant.field_offset(field.index()).bytes();
base.ptr.offset(offset as isize)
let ptr = base.ptr.offset(offset as isize);
match (&field_ty.sty, base.extra) {
(&ty::TyTrait(_), extra @ LvalueExtra::Vtable(_)) => return Ok(Lvalue {
ptr: ptr,
extra: extra,
}),
(&ty::TyTrait(_), _) => bug!("trait field without vtable"),
_ => ptr,
}
},
Downcast(_, variant) => {
@ -922,6 +933,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
Deref => {
let pointee_ty = pointee_type(base_ty).expect("Deref of non-pointer");
let pointee_ty = self.tcx.struct_tail(pointee_ty);
let ptr = self.memory.read_ptr(base.ptr)?;
let extra = match pointee_ty.sty {
ty::TySlice(_) | ty::TyStr => {

View file

@ -10,9 +10,14 @@ impl Trait for Struct {
}
}
struct Foo<T: ?Sized>(T);
fn main() {
let y: &Trait = &Struct(42);
y.method();
let x: Foo<Struct> = Foo(Struct(42));
let y: &Foo<Trait> = &x;
y.0.method();
/*
let x: Box<Fn(i32) -> i32> = Box::new(|x| x * 2);
assert_eq!(x(21), 42);