Skip to content

Commit f131a0a

Browse files
authoredOct 24, 2023
Rollup merge of #117010 - celinval:smir-internal, r=oli-obk
Add method to convert internal to stable constructs This is an alternative implementation to #116999. I believe we can still improve the logic a bit here, but I wanted to see which direction we should go first. In this implementation, the API is simpler and we keep Tables somewhat private. The definition is still public though, since we have to expose the Stable trait. However, there's a cost of keeping another thread-local and using `Rc`, but I'm hoping it will be a small cost. r? ``@oli-obk`` r? ``@spastorino``
2 parents 84f0bef + ae86f59 commit f131a0a

File tree

7 files changed

+281
-141
lines changed

7 files changed

+281
-141
lines changed
 

‎Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4525,6 +4525,7 @@ dependencies = [
45254525
"rustc_middle",
45264526
"rustc_span",
45274527
"rustc_target",
4528+
"scoped-tls",
45284529
"stable_mir",
45294530
"tracing",
45304531
]

‎compiler/rustc_smir/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ rustc_hir = { path = "../rustc_hir" }
99
rustc_middle = { path = "../rustc_middle" }
1010
rustc_span = { path = "../rustc_span" }
1111
rustc_target = { path = "../rustc_target" }
12+
scoped-tls = "1.0"
1213
stable_mir = {path = "../stable_mir" }
1314
tracing = "0.1"
1415

‎compiler/rustc_smir/src/rustc_internal/mod.rs

+47-13
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,32 @@
33
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
44
//! until stable MIR is complete.
55
6-
use crate::rustc_smir::Tables;
6+
use crate::rustc_smir::{Stable, Tables, TablesWrapper};
77
use rustc_data_structures::fx;
88
use rustc_data_structures::fx::FxIndexMap;
99
use rustc_middle::mir::interpret::AllocId;
1010
use rustc_middle::ty;
1111
use rustc_middle::ty::TyCtxt;
1212
use rustc_span::def_id::{CrateNum, DefId};
1313
use rustc_span::Span;
14+
use scoped_tls::scoped_thread_local;
1415
use stable_mir::ty::IndexedVal;
16+
use std::cell::Cell;
17+
use std::cell::RefCell;
1518
use std::fmt::Debug;
1619
use std::hash::Hash;
1720
use std::ops::Index;
1821

1922
mod internal;
2023

24+
pub fn stable<'tcx, S: Stable<'tcx>>(item: &S) -> S::T {
25+
with_tables(|tables| item.stable(tables))
26+
}
27+
28+
pub fn internal<'tcx, S: RustcInternal<'tcx>>(item: &S) -> S::T {
29+
with_tables(|tables| item.internal(tables))
30+
}
31+
2132
impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
2233
type Output = DefId;
2334

@@ -125,18 +136,41 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
125136
item.id.into()
126137
}
127138

139+
// A thread local variable that stores a pointer to the tables mapping between TyCtxt
140+
// datastructures and stable MIR datastructures
141+
scoped_thread_local! (static TLV: Cell<*const ()>);
142+
143+
pub(crate) fn init<'tcx>(tables: &TablesWrapper<'tcx>, f: impl FnOnce()) {
144+
assert!(!TLV.is_set());
145+
let ptr = tables as *const _ as *const ();
146+
TLV.set(&Cell::new(ptr), || {
147+
f();
148+
});
149+
}
150+
151+
/// Loads the current context and calls a function with it.
152+
/// Do not nest these, as that will ICE.
153+
pub(crate) fn with_tables<'tcx, R>(f: impl FnOnce(&mut Tables<'tcx>) -> R) -> R {
154+
assert!(TLV.is_set());
155+
TLV.with(|tlv| {
156+
let ptr = tlv.get();
157+
assert!(!ptr.is_null());
158+
let wrapper = ptr as *const TablesWrapper<'tcx>;
159+
let mut tables = unsafe { (*wrapper).0.borrow_mut() };
160+
f(&mut *tables)
161+
})
162+
}
163+
128164
pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
129-
stable_mir::run(
130-
Tables {
131-
tcx,
132-
def_ids: IndexMap::default(),
133-
alloc_ids: IndexMap::default(),
134-
spans: IndexMap::default(),
135-
types: vec![],
136-
instances: IndexMap::default(),
137-
},
138-
f,
139-
);
165+
let tables = TablesWrapper(RefCell::new(Tables {
166+
tcx,
167+
def_ids: IndexMap::default(),
168+
alloc_ids: IndexMap::default(),
169+
spans: IndexMap::default(),
170+
types: vec![],
171+
instances: IndexMap::default(),
172+
}));
173+
stable_mir::run(&tables, || init(&tables, f));
140174
}
141175

142176
#[macro_export]
@@ -251,7 +285,7 @@ impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> Index<V
251285
/// Trait used to translate a stable construct to its rustc counterpart.
252286
///
253287
/// This is basically a mirror of [crate::rustc_smir::Stable].
254-
pub(crate) trait RustcInternal<'tcx> {
288+
pub trait RustcInternal<'tcx> {
255289
type T;
256290
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T;
257291
}

0 commit comments

Comments
 (0)
Please sign in to comment.