interpret: refactor dyn trait handling
We can check that the vtable is for the right trait very early, and then just pass the type around.
This commit is contained in:
@@ -867,19 +867,28 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
.ok_or_else(|| err_ub!(InvalidFunctionPointer(Pointer::new(alloc_id, offset))).into())
|
||||
}
|
||||
|
||||
pub fn get_ptr_vtable(
|
||||
/// Get the dynamic type of the given vtable pointer.
|
||||
/// If `expected_trait` is `Some`, it must be a vtable for the given trait.
|
||||
pub fn get_ptr_vtable_ty(
|
||||
&self,
|
||||
ptr: Pointer<Option<M::Provenance>>,
|
||||
) -> InterpResult<'tcx, (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>)> {
|
||||
expected_trait: Option<&'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>>,
|
||||
) -> InterpResult<'tcx, Ty<'tcx>> {
|
||||
trace!("get_ptr_vtable({:?})", ptr);
|
||||
let (alloc_id, offset, _tag) = self.ptr_get_alloc_id(ptr)?;
|
||||
if offset.bytes() != 0 {
|
||||
throw_ub!(InvalidVTablePointer(Pointer::new(alloc_id, offset)))
|
||||
}
|
||||
match self.tcx.try_get_global_alloc(alloc_id) {
|
||||
Some(GlobalAlloc::VTable(ty, trait_ref)) => Ok((ty, trait_ref)),
|
||||
_ => throw_ub!(InvalidVTablePointer(Pointer::new(alloc_id, offset))),
|
||||
let Some(GlobalAlloc::VTable(ty, vtable_trait)) = self.tcx.try_get_global_alloc(alloc_id)
|
||||
else {
|
||||
throw_ub!(InvalidVTablePointer(Pointer::new(alloc_id, offset)))
|
||||
};
|
||||
if let Some(expected_trait) = expected_trait {
|
||||
if vtable_trait != expected_trait.principal() {
|
||||
throw_ub!(InvalidVTableTrait { expected_trait, vtable_trait });
|
||||
}
|
||||
}
|
||||
Ok(ty)
|
||||
}
|
||||
|
||||
pub fn alloc_mark_immutable(&mut self, id: AllocId) -> InterpResult<'tcx> {
|
||||
|
||||
Reference in New Issue
Block a user