Skip to content

Commit d0130ae

Browse files
committed
refactor: add Tables<'tcx, B: Bridge> and SmirContainer
1 parent 48aee7e commit d0130ae

File tree

2 files changed

+87
-153
lines changed

2 files changed

+87
-153
lines changed

compiler/rustc_smir/src/rustc_internal/mod.rs

Lines changed: 25 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ use rustc_span::Span;
1717
use rustc_span::def_id::{CrateNum, DefId};
1818
use scoped_tls::scoped_thread_local;
1919
use stable_mir::Error;
20-
use stable_mir::abi::Layout;
2120
use stable_mir::compiler_interface::SmirInterface;
2221
use stable_mir::ty::IndexedVal;
2322

2423
use crate::rustc_smir::context::SmirCtxt;
2524
use crate::rustc_smir::{Stable, Tables};
25+
use crate::rustc_smir::{Bridge, SmirContainer, Tables};
2626
use crate::stable_mir;
2727

2828
mod internal;
@@ -40,7 +40,7 @@ pub mod pretty;
4040
///
4141
/// This function will panic if StableMIR has not been properly initialized.
4242
pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
43-
with_tables(|tables| item.stable(tables))
43+
with_container(|tables, cx| item.stable(tables, cx))
4444
}
4545

4646
/// Convert a stable item into its internal Rust compiler counterpart, if one exists.
@@ -54,137 +54,40 @@ pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
5454
/// # Panics
5555
///
5656
/// This function will panic if StableMIR has not been properly initialized.
57-
pub fn internal<'tcx, S>(tcx: TyCtxt<'tcx>, item: S) -> S::T<'tcx>
57+
pub fn internal<'tcx, S>(item: S) -> S::T<'tcx>
5858
where
5959
S: RustcInternal,
6060
{
61-
// The tcx argument ensures that the item won't outlive the type context.
62-
with_tables(|tables| item.internal(tables, tcx))
61+
with_container(|tables, cx| item.internal(tables, cx))
6362
}
6463

65-
impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
64+
impl<'tcx, B: Bridge> Index<B::DefId> for Tables<'tcx, B> {
6665
type Output = DefId;
6766

6867
#[inline(always)]
69-
fn index(&self, index: stable_mir::DefId) -> &Self::Output {
68+
fn index(&self, index: B::DefId) -> &Self::Output {
7069
&self.def_ids[index]
7170
}
7271
}
7372

74-
impl<'tcx> Index<stable_mir::ty::Span> for Tables<'tcx> {
75-
type Output = Span;
76-
77-
#[inline(always)]
78-
fn index(&self, index: stable_mir::ty::Span) -> &Self::Output {
79-
&self.spans[index]
80-
}
81-
}
82-
83-
impl<'tcx> Tables<'tcx> {
84-
pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem {
85-
stable_mir::CrateItem(self.create_def_id(did))
86-
}
87-
88-
pub fn adt_def(&mut self, did: DefId) -> stable_mir::ty::AdtDef {
89-
stable_mir::ty::AdtDef(self.create_def_id(did))
90-
}
91-
92-
pub fn foreign_module_def(&mut self, did: DefId) -> stable_mir::ty::ForeignModuleDef {
93-
stable_mir::ty::ForeignModuleDef(self.create_def_id(did))
94-
}
95-
96-
pub fn foreign_def(&mut self, did: DefId) -> stable_mir::ty::ForeignDef {
97-
stable_mir::ty::ForeignDef(self.create_def_id(did))
98-
}
99-
100-
pub fn fn_def(&mut self, did: DefId) -> stable_mir::ty::FnDef {
101-
stable_mir::ty::FnDef(self.create_def_id(did))
102-
}
103-
104-
pub fn closure_def(&mut self, did: DefId) -> stable_mir::ty::ClosureDef {
105-
stable_mir::ty::ClosureDef(self.create_def_id(did))
106-
}
107-
108-
pub fn coroutine_def(&mut self, did: DefId) -> stable_mir::ty::CoroutineDef {
109-
stable_mir::ty::CoroutineDef(self.create_def_id(did))
110-
}
111-
112-
pub fn coroutine_closure_def(&mut self, did: DefId) -> stable_mir::ty::CoroutineClosureDef {
113-
stable_mir::ty::CoroutineClosureDef(self.create_def_id(did))
114-
}
115-
116-
pub fn alias_def(&mut self, did: DefId) -> stable_mir::ty::AliasDef {
117-
stable_mir::ty::AliasDef(self.create_def_id(did))
118-
}
119-
120-
pub fn param_def(&mut self, did: DefId) -> stable_mir::ty::ParamDef {
121-
stable_mir::ty::ParamDef(self.create_def_id(did))
122-
}
123-
124-
pub fn br_named_def(&mut self, did: DefId) -> stable_mir::ty::BrNamedDef {
125-
stable_mir::ty::BrNamedDef(self.create_def_id(did))
126-
}
127-
128-
pub fn trait_def(&mut self, did: DefId) -> stable_mir::ty::TraitDef {
129-
stable_mir::ty::TraitDef(self.create_def_id(did))
130-
}
131-
132-
pub fn generic_def(&mut self, did: DefId) -> stable_mir::ty::GenericDef {
133-
stable_mir::ty::GenericDef(self.create_def_id(did))
134-
}
135-
136-
pub fn const_def(&mut self, did: DefId) -> stable_mir::ty::ConstDef {
137-
stable_mir::ty::ConstDef(self.create_def_id(did))
138-
}
139-
140-
pub fn impl_def(&mut self, did: DefId) -> stable_mir::ty::ImplDef {
141-
stable_mir::ty::ImplDef(self.create_def_id(did))
142-
}
143-
144-
pub fn region_def(&mut self, did: DefId) -> stable_mir::ty::RegionDef {
145-
stable_mir::ty::RegionDef(self.create_def_id(did))
146-
}
147-
148-
pub fn coroutine_witness_def(&mut self, did: DefId) -> stable_mir::ty::CoroutineWitnessDef {
149-
stable_mir::ty::CoroutineWitnessDef(self.create_def_id(did))
150-
}
151-
152-
pub fn assoc_def(&mut self, did: DefId) -> stable_mir::ty::AssocDef {
153-
stable_mir::ty::AssocDef(self.create_def_id(did))
154-
}
155-
156-
pub fn opaque_def(&mut self, did: DefId) -> stable_mir::ty::OpaqueDef {
157-
stable_mir::ty::OpaqueDef(self.create_def_id(did))
158-
}
159-
160-
pub fn prov(&mut self, aid: AllocId) -> stable_mir::ty::Prov {
161-
stable_mir::ty::Prov(self.create_alloc_id(aid))
162-
}
163-
164-
pub(crate) fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId {
73+
impl<'tcx, B: Bridge> Tables<'tcx, B> {
74+
pub fn create_def_id(&mut self, did: DefId) -> B::DefId {
16575
self.def_ids.create_or_fetch(did)
16676
}
16777

168-
pub(crate) fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::mir::alloc::AllocId {
78+
pub fn create_alloc_id(&mut self, aid: AllocId) -> B::AllocId {
16979
self.alloc_ids.create_or_fetch(aid)
17080
}
17181

172-
pub(crate) fn create_span(&mut self, span: Span) -> stable_mir::ty::Span {
82+
pub fn create_span(&mut self, span: Span) -> B::Span {
17383
self.spans.create_or_fetch(span)
17484
}
17585

176-
pub(crate) fn instance_def(
177-
&mut self,
178-
instance: ty::Instance<'tcx>,
179-
) -> stable_mir::mir::mono::InstanceDef {
86+
pub fn instance_def(&mut self, instance: ty::Instance<'tcx>) -> B::InstanceDef {
18087
self.instances.create_or_fetch(instance)
18188
}
18289

183-
pub(crate) fn static_def(&mut self, did: DefId) -> stable_mir::mir::mono::StaticDef {
184-
stable_mir::mir::mono::StaticDef(self.create_def_id(did))
185-
}
186-
187-
pub(crate) fn layout_id(&mut self, layout: rustc_abi::Layout<'tcx>) -> Layout {
90+
pub fn layout_id(&mut self, layout: rustc_abi::Layout<'tcx>) -> B::Layout {
18891
self.layouts.create_or_fetch(layout)
18992
}
19093
}
@@ -197,49 +100,39 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
197100
// datastructures and stable MIR datastructures
198101
scoped_thread_local! (static TLV: Cell<*const ()>);
199102

200-
pub(crate) fn init<'tcx, F, T>(cx: &SmirCtxt<'tcx>, f: F) -> T
103+
pub(crate) fn init<'tcx, F, T, B: Bridge>(container: &SmirContainer<'tcx, B>, f: F) -> T
201104
where
202105
F: FnOnce() -> T,
203106
{
204107
assert!(!TLV.is_set());
205-
let ptr = cx as *const _ as *const ();
108+
let ptr = container as *const _ as *const ();
206109
TLV.set(&Cell::new(ptr), || f())
207110
}
208111

209112
/// Loads the current context and calls a function with it.
210113
/// Do not nest these, as that will ICE.
211-
pub(crate) fn with_tables<R>(f: impl for<'tcx> FnOnce(&mut Tables<'tcx>) -> R) -> R {
114+
pub(crate) fn with_container<'tcx, R, B: Bridge>(
115+
f: impl FnOnce(&mut Tables<'tcx, B>, &SmirCtxt<'tcx, B>) -> R,
116+
) -> R {
212117
assert!(TLV.is_set());
213118
TLV.with(|tlv| {
214119
let ptr = tlv.get();
215120
assert!(!ptr.is_null());
216-
let context = ptr as *const SmirCtxt<'_>;
217-
let mut tables = unsafe { (*context).0.borrow_mut() };
218-
f(&mut *tables)
121+
let container = ptr as *const SmirContainer<'tcx, B>;
122+
let mut tables = unsafe { (*container).tables.borrow_mut() };
123+
let cx = unsafe { (*container).cx.borrow() };
124+
f(&mut *tables, &*cx)
219125
})
220126
}
221127

222128
pub fn run<F, T>(tcx: TyCtxt<'_>, f: F) -> Result<T, Error>
223129
where
224130
F: FnOnce() -> T,
225131
{
226-
let tables = SmirCtxt(RefCell::new(Tables {
227-
tcx,
228-
def_ids: IndexMap::default(),
229-
alloc_ids: IndexMap::default(),
230-
spans: IndexMap::default(),
231-
types: IndexMap::default(),
232-
instances: IndexMap::default(),
233-
ty_consts: IndexMap::default(),
234-
mir_consts: IndexMap::default(),
235-
layouts: IndexMap::default(),
236-
}));
237-
238-
let interface = SmirInterface { cx: tables };
239-
240-
// Pass the `SmirInterface` to compiler_interface::run
241-
// and initialize the rustc-specific TLS with tables.
242-
stable_mir::compiler_interface::run(&interface, || init(&interface.cx, f))
132+
let smir_cx = RefCell::new(SmirCtxt::new(tcx));
133+
let container = SmirContainer { tables: RefCell::new(Tables::new(tcx)), cx: smir_cx };
134+
135+
stable_mir::compiler_interface::run(&container, || init(&container, f))
243136
}
244137

245138
/// Instantiate and run the compiler with the provided arguments and callback.

compiler/rustc_smir/src/rustc_smir/mod.rs

Lines changed: 62 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@
99
1010
use std::marker::PointeeSized;
1111
use std::ops::RangeInclusive;
12+
use std::cell::RefCell;
13+
use std::fmt::Debug;
1214

15+
use context::SmirCtxt;
1316
use rustc_hir::def::DefKind;
1417
use rustc_middle::mir;
1518
use rustc_middle::mir::interpret::AllocId;
1619
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
1720
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
18-
use stable_mir::abi::Layout;
19-
use stable_mir::mir::mono::{InstanceDef, StaticDef};
20-
use stable_mir::ty::{FnDef, MirConstId, Span, TyConstId};
2121
use stable_mir::{CtorKind, ItemKind};
2222
use tracing::debug;
2323

@@ -29,28 +29,50 @@ mod builder;
2929
pub mod context;
3030
mod convert;
3131

32-
pub struct Tables<'tcx> {
33-
pub(crate) tcx: TyCtxt<'tcx>,
34-
pub(crate) def_ids: IndexMap<DefId, stable_mir::DefId>,
35-
pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::mir::alloc::AllocId>,
36-
pub(crate) spans: IndexMap<rustc_span::Span, Span>,
37-
pub(crate) types: IndexMap<Ty<'tcx>, stable_mir::ty::Ty>,
38-
pub(crate) instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
39-
pub(crate) ty_consts: IndexMap<ty::Const<'tcx>, TyConstId>,
40-
pub(crate) mir_consts: IndexMap<mir::Const<'tcx>, MirConstId>,
41-
pub(crate) layouts: IndexMap<rustc_abi::Layout<'tcx>, Layout>,
32+
/// A container which is used for TLS.
33+
pub struct SmirContainer<'tcx, B: Bridge> {
34+
pub tables: RefCell<Tables<'tcx, B>>,
35+
pub cx: RefCell<SmirCtxt<'tcx, B>>,
4236
}
4337

44-
impl<'tcx> Tables<'tcx> {
45-
pub(crate) fn intern_ty(&mut self, ty: Ty<'tcx>) -> stable_mir::ty::Ty {
38+
pub struct Tables<'tcx, B: Bridge> {
39+
tcx: TyCtxt<'tcx>,
40+
pub(crate) def_ids: IndexMap<DefId, B::DefId>,
41+
pub(crate) alloc_ids: IndexMap<AllocId, B::AllocId>,
42+
pub(crate) spans: IndexMap<rustc_span::Span, B::Span>,
43+
pub(crate) types: IndexMap<Ty<'tcx>, B::Ty>,
44+
pub(crate) instances: IndexMap<ty::Instance<'tcx>, B::InstanceDef>,
45+
pub(crate) ty_consts: IndexMap<ty::Const<'tcx>, B::TyConstId>,
46+
pub(crate) mir_consts: IndexMap<mir::Const<'tcx>, B::MirConstId>,
47+
pub(crate) layouts: IndexMap<rustc_abi::Layout<'tcx>, B::Layout>,
48+
}
49+
50+
impl<'tcx, B: Bridge> Tables<'tcx, B> {
51+
pub(crate) fn new(tcx: TyCtxt<'tcx>) -> Self {
52+
Self {
53+
tcx,
54+
def_ids: IndexMap::default(),
55+
alloc_ids: IndexMap::default(),
56+
spans: IndexMap::default(),
57+
types: IndexMap::default(),
58+
instances: IndexMap::default(),
59+
ty_consts: IndexMap::default(),
60+
mir_consts: IndexMap::default(),
61+
layouts: IndexMap::default(),
62+
}
63+
}
64+
}
65+
66+
impl<'tcx, B: Bridge> Tables<'tcx, B> {
67+
pub(crate) fn intern_ty(&mut self, ty: Ty<'tcx>) -> B::Ty {
4668
self.types.create_or_fetch(ty)
4769
}
4870

49-
pub(crate) fn intern_ty_const(&mut self, ct: ty::Const<'tcx>) -> TyConstId {
71+
pub(crate) fn intern_ty_const(&mut self, ct: ty::Const<'tcx>) -> B::TyConstId {
5072
self.ty_consts.create_or_fetch(ct)
5173
}
5274

53-
pub(crate) fn intern_mir_const(&mut self, constant: mir::Const<'tcx>) -> MirConstId {
75+
pub(crate) fn intern_mir_const(&mut self, constant: mir::Const<'tcx>) -> B::MirConstId {
5476
self.mir_consts.create_or_fetch(constant)
5577
}
5678

@@ -82,19 +104,38 @@ impl<'tcx> Tables<'tcx> {
82104
!must_override && self.tcx.is_mir_available(def_id)
83105
}
84106

85-
fn to_fn_def(&mut self, def_id: DefId) -> Option<FnDef> {
107+
fn filter_fn_def(&mut self, def_id: DefId) -> Option<DefId> {
86108
if matches!(self.tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) {
87-
Some(self.fn_def(def_id))
109+
Some(def_id)
88110
} else {
89111
None
90112
}
91113
}
92114

93-
fn to_static(&mut self, def_id: DefId) -> Option<StaticDef> {
94-
matches!(self.tcx.def_kind(def_id), DefKind::Static { .. }).then(|| self.static_def(def_id))
115+
fn filter_static_def(&mut self, def_id: DefId) -> Option<DefId> {
116+
matches!(self.tcx.def_kind(def_id), DefKind::Static { .. }).then(|| def_id)
95117
}
96118
}
97119

120+
/// A trait defining types that are used to emulate StableMIR components, which is really
121+
/// useful when programming in stable_mir-agnostic settings.
122+
pub trait Bridge {
123+
type DefId: Copy + Debug + PartialEq + IndexedVal;
124+
type AllocId: Copy + Debug + PartialEq + IndexedVal;
125+
type Span: Copy + Debug + PartialEq + IndexedVal;
126+
type Ty: Copy + Debug + PartialEq + IndexedVal;
127+
type InstanceDef: Copy + Debug + PartialEq + IndexedVal;
128+
type TyConstId: Copy + Debug + PartialEq + IndexedVal;
129+
type MirConstId: Copy + Debug + PartialEq + IndexedVal;
130+
type Layout: Copy + Debug + PartialEq + IndexedVal;
131+
type Error: SmirError;
132+
}
133+
134+
pub trait SmirError {
135+
fn new(msg: String) -> Self;
136+
fn from_internal<T: Debug>(err: T) -> Self;
137+
}
138+
98139
/// Iterate over the definitions of the given crate.
99140
pub(crate) fn filter_def_ids<F, T>(tcx: TyCtxt<'_>, krate: CrateNum, mut func: F) -> Vec<T>
100141
where

0 commit comments

Comments
 (0)