enable A<Struct> -> A<Trait> downcasting
This commit is contained in:
parent
d5e44712a4
commit
145cbf844c
2 changed files with 19 additions and 2 deletions
|
@ -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 => {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue