Skip to content

Commit 0575cd0

Browse files
committed
refactor: add Tables<'tcx, B: Bridge> and SmirContainer
1 parent 5e0bdaa commit 0575cd0

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
@@ -8,15 +8,15 @@
88
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
99
1010
use std::ops::RangeInclusive;
11+
use std::cell::RefCell;
12+
use std::fmt::Debug;
1113

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

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

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

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

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

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

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

84-
fn to_fn_def(&mut self, def_id: DefId) -> Option<FnDef> {
106+
fn filter_fn_def(&mut self, def_id: DefId) -> Option<DefId> {
85107
if matches!(self.tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) {
86-
Some(self.fn_def(def_id))
108+
Some(def_id)
87109
} else {
88110
None
89111
}
90112
}
91113

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

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

0 commit comments

Comments
 (0)