Skip to content

Commit 5f6b656

Browse files
committed
Synchronize get_vtable with the codegen_llvm one
1 parent d810139 commit 5f6b656

File tree

3 files changed

+25
-20
lines changed

3 files changed

+25
-20
lines changed

src/librustc_mir/interpret/cast.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -326,12 +326,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
326326
}
327327
(_, &ty::Dynamic(ref data, _)) => {
328328
// Initial cast from sized to dyn trait
329-
let trait_ref = data.principal().unwrap().with_self_ty(
330-
*self.tcx,
331-
src_pointee_ty,
332-
);
333-
let trait_ref = self.tcx.erase_regions(&trait_ref);
334-
let vtable = self.get_vtable(src_pointee_ty, trait_ref)?;
329+
let vtable = self.get_vtable(src_pointee_ty, data.principal())?;
335330
let ptr = self.read_value(src)?.to_scalar_ptr()?;
336331
let val = Value::new_dyn_trait(ptr, vtable);
337332
self.write_value(val, dest)

src/librustc_mir/interpret/eval_context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub struct EvalContext<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> {
5353
pub(crate) stack: Vec<Frame<'mir, 'tcx, M::PointerTag>>,
5454

5555
/// A cache for deduplicating vtables
56-
pub(super) vtables: FxHashMap<(Ty<'tcx>, ty::PolyTraitRef<'tcx>), AllocId>,
56+
pub(super) vtables: FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), AllocId>,
5757
}
5858

5959
/// A stack frame.

src/librustc_mir/interpret/traits.rs

+23-13
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,32 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
2424
pub fn get_vtable(
2525
&mut self,
2626
ty: Ty<'tcx>,
27-
trait_ref: ty::PolyTraitRef<'tcx>,
27+
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
2828
) -> EvalResult<'tcx, Pointer<M::PointerTag>> {
29-
debug!("get_vtable(trait_ref={:?})", trait_ref);
29+
debug!("get_vtable(trait_ref={:?})", poly_trait_ref);
3030

31-
if let Some(&vtable) = self.vtables.get(&(ty, trait_ref)) {
31+
let (ty, poly_trait_ref) = self.tcx.erase_regions(&(ty, poly_trait_ref));
32+
33+
if let Some(&vtable) = self.vtables.get(&(ty, poly_trait_ref)) {
3234
return Ok(Pointer::from(vtable).with_default_tag());
3335
}
3436

35-
let layout = self.layout_of(trait_ref.self_ty())?;
37+
let trait_ref = poly_trait_ref.map(|trait_ref| {
38+
let trait_ref = trait_ref.with_self_ty(*self.tcx, ty);
39+
self.tcx.erase_regions(&trait_ref)
40+
});
41+
42+
let methods = trait_ref.map(|trait_ref| self.tcx.vtable_methods(trait_ref));
43+
44+
let layout = self.layout_of(ty)?;
3645
assert!(!layout.is_unsized(), "can't create a vtable for an unsized type");
3746
let size = layout.size.bytes();
3847
let align = layout.align.abi();
3948

4049
let ptr_size = self.pointer_size();
4150
let ptr_align = self.tcx.data_layout.pointer_align;
42-
let methods = self.tcx.vtable_methods(trait_ref);
4351
let vtable = self.memory.allocate(
44-
ptr_size * (3 + methods.len() as u64),
52+
ptr_size * (3 + methods.as_ref().map_or(0, |m| m.len() as u64)),
4553
ptr_align,
4654
MemoryKind::Vtable,
4755
)?;
@@ -56,17 +64,19 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
5664
self.memory.write_ptr_sized(align_ptr, ptr_align,
5765
Scalar::from_uint(align, ptr_size).into())?;
5866

59-
for (i, method) in methods.iter().enumerate() {
60-
if let Some((def_id, substs)) = *method {
61-
let instance = self.resolve(def_id, substs)?;
62-
let fn_ptr = self.memory.create_fn_alloc(instance);
63-
let method_ptr = vtable.offset(ptr_size * (3 + i as u64), &self)?;
64-
self.memory.write_ptr_sized(method_ptr, ptr_align, Scalar::Ptr(fn_ptr).into())?;
67+
if let Some(methods) = methods {
68+
for (i, method) in methods.iter().enumerate() {
69+
if let Some((def_id, substs)) = *method {
70+
let instance = self.resolve(def_id, substs)?;
71+
let fn_ptr = self.memory.create_fn_alloc(instance);
72+
let method_ptr = vtable.offset(ptr_size * (3 + i as u64), &self)?;
73+
self.memory.write_ptr_sized(method_ptr, ptr_align, Scalar::Ptr(fn_ptr).into())?;
74+
}
6575
}
6676
}
6777

6878
self.memory.mark_immutable(vtable.alloc_id)?;
69-
assert!(self.vtables.insert((ty, trait_ref), vtable.alloc_id).is_none());
79+
assert!(self.vtables.insert((ty, poly_trait_ref), vtable.alloc_id).is_none());
7080

7181
Ok(vtable)
7282
}

0 commit comments

Comments
 (0)