}
(_, &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)
pub(crate) stack: Vec<Frame<'mir, 'tcx, M::PointerTag>>,
/// 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.
pub fn get_vtable(
&mut self,
ty: Ty<'tcx>,
- trait_ref: ty::PolyTraitRef<'tcx>,
+ poly_trait_ref: ty::PolyExistentialTraitRef<'tcx>,
) -> EvalResult<'tcx, Pointer<M::PointerTag>> {
- 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,
}
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)
}