Skip to content

Commit 66a554b

Browse files
committed
Add method to convert internal to stable constructs
1 parent e2068cd commit 66a554b

File tree

5 files changed

+197
-121
lines changed

5 files changed

+197
-121
lines changed

Diff for: Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4524,6 +4524,7 @@ dependencies = [
45244524
"rustc_middle",
45254525
"rustc_span",
45264526
"rustc_target",
4527+
"scoped-tls",
45274528
"stable_mir",
45284529
"tracing",
45294530
]

Diff for: 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

Diff for: compiler/rustc_smir/src/rustc_internal/mod.rs

+46-12
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,29 @@
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;
21+
use std::rc::Rc;
1822

1923
mod internal;
2024

25+
pub unsafe fn stable<'tcx, S: Stable<'tcx>>(item: &S) -> S::T {
26+
with_tables(|tables| item.stable(tables))
27+
}
28+
2129
impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
2230
type Output = DefId;
2331

@@ -125,18 +133,44 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
125133
item.id.into()
126134
}
127135

136+
// A thread local variable that stores a pointer to the tables mapping between TyCtxt
137+
// datastructures and stable MIR datastructures
138+
scoped_thread_local! (static TLV: Cell<*const ()>);
139+
140+
pub(crate) fn init<'tcx>(tables: TablesWrapper<'tcx>, f: impl FnOnce()) {
141+
assert!(!TLV.is_set());
142+
fn g<'a, 'tcx>(context: &'a TablesWrapper<'tcx>, f: impl FnOnce()) {
143+
let ptr: *const () = &context as *const &_ as _;
144+
TLV.set(&Cell::new(ptr), || {
145+
f();
146+
});
147+
}
148+
g(&tables, f);
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 = unsafe { *(ptr as *const &TablesWrapper<'tcx>) };
159+
let mut tables = 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 = Rc::new(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(TablesWrapper(Rc::clone(&tables)), || init(TablesWrapper(tables), f));
140174
}
141175

142176
#[macro_export]

0 commit comments

Comments
 (0)