diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs
index f4ddfa5293e..f5e824b7628 100644
--- a/src/librustc_mir/interpret/cast.rs
+++ b/src/librustc_mir/interpret/cast.rs
@@ -327,12 +327,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
}
(_, &ty::Dynamic(ref data, _)) => {
// Initial cast from sized to dyn trait
- let trait_ref = data.principal().with_self_ty(
- *self.tcx,
- src_pointee_ty,
- );
- let trait_ref = self.tcx.erase_regions(&trait_ref);
- let vtable = self.get_vtable(src_pointee_ty, trait_ref)?;
+ let vtable = self.get_vtable(src_pointee_ty, data.principal())?;
let ptr = self.read_value(src)?.to_scalar_ptr()?;
let val = Value::new_dyn_trait(ptr, vtable);
self.write_value(val, dest)
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index be9f2b8f658..13b6fa44de2 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -53,7 +53,7 @@ pub struct EvalContext<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> {
pub(crate) stack: Vec>,
/// A cache for deduplicating vtables
- pub(super) vtables: FxHashMap<(Ty<'tcx>, ty::PolyTraitRef<'tcx>), AllocId>,
+ pub(super) vtables: FxHashMap<(Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>), AllocId>,
}
/// A stack frame.
diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs
index b4c73ad02c3..30591a4ff5a 100644
--- a/src/librustc_mir/interpret/traits.rs
+++ b/src/librustc_mir/interpret/traits.rs
@@ -24,22 +24,28 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
pub fn get_vtable(
&mut self,
ty: Ty<'tcx>,
- trait_ref: ty::PolyTraitRef<'tcx>,
+ poly_trait_ref: ty::PolyExistentialTraitRef<'tcx>,
) -> EvalResult<'tcx, Pointer> {
- debug!("get_vtable(trait_ref={:?})", trait_ref);
+ debug!("get_vtable(trait_ref={:?})", poly_trait_ref);
- if let Some(&vtable) = self.vtables.get(&(ty, trait_ref)) {
+ let (ty, poly_trait_ref) = self.tcx.erase_regions(&(ty, poly_trait_ref));
+
+ if let Some(&vtable) = self.vtables.get(&(ty, poly_trait_ref)) {
return Ok(Pointer::from(vtable).with_default_tag());
}
- let layout = self.layout_of(trait_ref.self_ty())?;
+ let trait_ref = poly_trait_ref.with_self_ty(*self.tcx, ty);
+ let trait_ref = self.tcx.erase_regions(&trait_ref);
+
+ let methods = self.tcx.vtable_methods(trait_ref);
+
+ let layout = self.layout_of(ty)?;
assert!(!layout.is_unsized(), "can't create a vtable for an unsized type");
let size = layout.size.bytes();
let align = layout.align.abi();
let ptr_size = self.pointer_size();
let ptr_align = self.tcx.data_layout.pointer_align;
- let methods = self.tcx.vtable_methods(trait_ref);
let vtable = self.memory.allocate(
ptr_size * (3 + methods.len() as u64),
ptr_align,
@@ -66,7 +72,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
}
self.memory.mark_immutable(vtable.alloc_id)?;
- assert!(self.vtables.insert((ty, trait_ref), vtable.alloc_id).is_none());
+ assert!(self.vtables.insert((ty, poly_trait_ref), vtable.alloc_id).is_none());
Ok(vtable)
}