1 use rustc_middle::mir::interpret::{InterpResult, Pointer};
2 use rustc_middle::ty::layout::LayoutOf;
3 use rustc_middle::ty::{self, Ty, TyCtxt};
4 use rustc_target::abi::{Align, Size};
6 use super::util::ensure_monomorphic_enough;
7 use super::{InterpCx, Machine};
9 impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
10 /// Creates a dynamic vtable for the given type and vtable origin. This is used only for
13 /// The `trait_ref` encodes the erased self type. Hence, if we are making an object `Foo<Trait>`
14 /// from a value of type `Foo<T>`, then `trait_ref` would map `T: Trait`. `None` here means that
15 /// this is an auto trait without any methods, so we only need the basic vtable (drop, size,
17 pub fn get_vtable_ptr(
20 poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
21 ) -> InterpResult<'tcx, Pointer<Option<M::Provenance>>> {
22 trace!("get_vtable(trait_ref={:?})", poly_trait_ref);
24 let (ty, poly_trait_ref) = self.tcx.erase_regions((ty, poly_trait_ref));
26 // All vtables must be monomorphic, bail out otherwise.
27 ensure_monomorphic_enough(*self.tcx, ty)?;
28 ensure_monomorphic_enough(*self.tcx, poly_trait_ref)?;
30 let vtable_symbolic_allocation = self.tcx.create_vtable_alloc(ty, poly_trait_ref);
31 let vtable_ptr = self.global_base_pointer(Pointer::from(vtable_symbolic_allocation))?;
35 /// Returns a high-level representation of the entires of the given vtable.
36 pub fn get_vtable_entries(
38 vtable: Pointer<Option<M::Provenance>>,
39 ) -> InterpResult<'tcx, &'tcx [ty::VtblEntry<'tcx>]> {
40 let (ty, poly_trait_ref) = self.get_ptr_vtable(vtable)?;
41 Ok(if let Some(poly_trait_ref) = poly_trait_ref {
42 let trait_ref = poly_trait_ref.with_self_ty(*self.tcx, ty);
43 let trait_ref = self.tcx.erase_regions(trait_ref);
44 self.tcx.vtable_entries(trait_ref)
46 TyCtxt::COMMON_VTABLE_ENTRIES
50 pub fn get_vtable_size_and_align(
52 vtable: Pointer<Option<M::Provenance>>,
53 ) -> InterpResult<'tcx, (Size, Align)> {
54 let (ty, _trait_ref) = self.get_ptr_vtable(vtable)?;
55 let layout = self.layout_of(ty)?;
56 assert!(!layout.is_unsized(), "there are no vtables for unsized types");
57 Ok((layout.size, layout.align.abi))