Synchronize get_vtable with the codegen_llvm
one
This commit is contained in:
parent
80feed380d
commit
8ac7fa414b
3 changed files with 14 additions and 13 deletions
|
@ -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)
|
||||
|
|
|
@ -53,7 +53,7 @@ pub struct EvalContext<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> {
|
|||
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.
|
||||
|
|
|
@ -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<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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue