Skip to content

Commit 2b8d5dd

Browse files
committed
Add support to get virtual table allocation
1 parent 5a77f1d commit 2b8d5dd

File tree

5 files changed

+69
-4
lines changed

5 files changed

+69
-4
lines changed

compiler/rustc_smir/src/rustc_internal/internal.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use rustc_span::Symbol;
1010
use stable_mir::mir::alloc::AllocId;
1111
use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
1212
use stable_mir::ty::{
13-
Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const, GenericArgKind,
14-
GenericArgs, Region, TraitRef, Ty,
13+
AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const,
14+
ExistentialTraitRef, GenericArgKind, GenericArgs, Region, TraitRef, Ty,
1515
};
1616
use stable_mir::{CrateItem, DefId};
1717

@@ -153,6 +153,17 @@ impl<'tcx> RustcInternal<'tcx> for BoundVariableKind {
153153
}
154154
}
155155

156+
impl<'tcx> RustcInternal<'tcx> for ExistentialTraitRef {
157+
type T = rustc_ty::ExistentialTraitRef<'tcx>;
158+
159+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
160+
rustc_ty::ExistentialTraitRef {
161+
def_id: self.def_id.0.internal(tables),
162+
args: self.generic_args.internal(tables),
163+
}
164+
}
165+
}
166+
156167
impl<'tcx> RustcInternal<'tcx> for TraitRef {
157168
type T = rustc_ty::TraitRef<'tcx>;
158169

@@ -184,6 +195,17 @@ impl<'tcx> RustcInternal<'tcx> for ClosureKind {
184195
}
185196
}
186197

198+
impl<'tcx> RustcInternal<'tcx> for AdtDef {
199+
type T = rustc_ty::AdtDef<'tcx>;
200+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
201+
let ty = tables.tcx.type_of(self.0.internal(&mut *tables)).instantiate_identity().kind();
202+
let rustc_ty::TyKind::Adt(def, _) = ty else {
203+
panic!("Expected an ADT definition, but found: {ty:?}")
204+
};
205+
*def
206+
}
207+
}
208+
187209
impl<'tcx, T> RustcInternal<'tcx> for &T
188210
where
189211
T: RustcInternal<'tcx>,
@@ -194,3 +216,13 @@ where
194216
(*self).internal(tables)
195217
}
196218
}
219+
impl<'tcx, T> RustcInternal<'tcx> for Option<T>
220+
where
221+
T: RustcInternal<'tcx>,
222+
{
223+
type T = Option<T::T>;
224+
225+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
226+
self.as_ref().map(|inner| inner.internal(tables))
227+
}
228+
}

compiler/rustc_smir/src/rustc_internal/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl<'tcx> Tables<'tcx> {
117117
self.def_ids.create_or_fetch(did)
118118
}
119119

120-
fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::mir::alloc::AllocId {
120+
pub(crate) fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::mir::alloc::AllocId {
121121
self.alloc_ids.create_or_fetch(aid)
122122
}
123123

compiler/rustc_smir/src/rustc_smir/mod.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ use rustc_target::abi::FieldIdx;
2020
use stable_mir::mir::alloc::GlobalAlloc;
2121
use stable_mir::mir::mono::{InstanceDef, StaticDef};
2222
use stable_mir::mir::{Body, CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx};
23-
use stable_mir::ty::{AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, ConstId, ConstantKind, FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span, TyKind, UintTy, EarlyParamRegion};
23+
use stable_mir::ty::{
24+
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, ConstId, ConstantKind,
25+
EarlyParamRegion, FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability,
26+
RigidTy, Span, TyKind, UintTy,
27+
};
2428
use stable_mir::{self, opaque, Context, CrateItem, Error, Filename, ItemKind};
2529
use std::cell::RefCell;
2630
use tracing::debug;
@@ -312,6 +316,18 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
312316
let alloc_id = alloc.internal(&mut *tables);
313317
tables.tcx.global_alloc(alloc_id).stable(&mut *tables)
314318
}
319+
320+
fn vtable_allocation(
321+
&self,
322+
global_alloc: &GlobalAlloc,
323+
) -> Option<stable_mir::mir::alloc::AllocId> {
324+
let mut tables = self.0.borrow_mut();
325+
let GlobalAlloc::VTable(ty, trait_ref) = global_alloc else { return None };
326+
let alloc_id = tables
327+
.tcx
328+
.vtable_allocation((ty.internal(&mut *tables), trait_ref.internal(&mut *tables)));
329+
Some(alloc_id.stable(&mut *tables))
330+
}
315331
}
316332

317333
pub(crate) struct TablesWrapper<'tcx>(pub(crate) RefCell<Tables<'tcx>>);
@@ -1536,6 +1552,13 @@ impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
15361552
}
15371553
}
15381554

1555+
impl<'tcx> Stable<'tcx> for mir::interpret::AllocId {
1556+
type T = stable_mir::mir::alloc::AllocId;
1557+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1558+
tables.create_alloc_id(*self)
1559+
}
1560+
}
1561+
15391562
impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> {
15401563
type T = GlobalAlloc;
15411564

compiler/stable_mir/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,9 @@ pub trait Context {
268268

269269
/// Retrieve global allocation for the given allocation ID.
270270
fn global_alloc(&self, id: AllocId) -> GlobalAlloc;
271+
272+
/// Retrieve the id for the virtual table.
273+
fn vtable_allocation(&self, global_alloc: &GlobalAlloc) -> Option<AllocId>;
271274
}
272275

273276
// A thread local variable that stores a pointer to the tables mapping between TyCtxt

compiler/stable_mir/src/mir/alloc.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub enum GlobalAlloc {
99
/// The alloc ID is used as a function pointer.
1010
Function(Instance),
1111
/// This alloc ID points to a symbolic (not-reified) vtable.
12+
/// The `None` trait ref is used to represent auto traits.
1213
VTable(Ty, Option<Binder<ExistentialTraitRef>>),
1314
/// The alloc ID points to a "lazy" static variable that did not get computed (yet).
1415
/// This is also used to break the cycle in recursive statics.
@@ -23,6 +24,12 @@ impl From<AllocId> for GlobalAlloc {
2324
}
2425
}
2526

27+
impl GlobalAlloc {
28+
pub fn vtable_allocation(&self) -> Option<AllocId> {
29+
with(|cx| cx.vtable_allocation(self))
30+
}
31+
}
32+
2633
/// A unique identification number for each provenance
2734
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2835
pub struct AllocId(usize);

0 commit comments

Comments
 (0)