Skip to content

Commit 0c42219

Browse files
committed
Add method to convert internal to stable constructs
1 parent 249624b commit 0c42219

File tree

5 files changed

+187
-114
lines changed

5 files changed

+187
-114
lines changed

Diff for: Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4489,6 +4489,7 @@ dependencies = [
44894489
"rustc_middle",
44904490
"rustc_span",
44914491
"rustc_target",
4492+
"scoped-tls",
44924493
"stable_mir",
44934494
"tracing",
44944495
]

Diff for: compiler/rustc_smir/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ rustc_interface = { path = "../rustc_interface" }
1111
rustc_middle = { path = "../rustc_middle" }
1212
rustc_span = { path = "../rustc_span" }
1313
rustc_target = { path = "../rustc_target" }
14+
scoped-tls = "1.0"
1415
stable_mir = {path = "../stable_mir" }
1516
tracing = "0.1"
1617

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

+46-12
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! until stable MIR is complete.
55
66
use crate::rustc_internal;
7-
use crate::rustc_smir::Tables;
7+
use crate::rustc_smir::{Stable, Tables, TablesWrapper};
88
use rustc_data_structures::fx;
99
use rustc_data_structures::fx::FxIndexMap;
1010
use rustc_driver::{Callbacks, Compilation, RunCompiler};
@@ -14,11 +14,19 @@ use rustc_middle::ty;
1414
use rustc_middle::ty::TyCtxt;
1515
use rustc_span::def_id::{CrateNum, DefId};
1616
use rustc_span::Span;
17+
use scoped_tls::scoped_thread_local;
1718
use stable_mir::ty::IndexedVal;
1819
use stable_mir::CompilerError;
20+
use std::cell::Cell;
21+
use std::cell::RefCell;
1922
use std::fmt::Debug;
2023
use std::hash::Hash;
2124
use std::ops::{ControlFlow, Index};
25+
use std::rc::Rc;
26+
27+
pub unsafe fn stable<'tcx, S: Stable<'tcx>>(item: &S) -> S::T {
28+
with_tables(|tables| item.stable(tables))
29+
}
2230

2331
impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
2432
type Output = DefId;
@@ -127,18 +135,44 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
127135
item.id.into()
128136
}
129137

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

144178
pub struct StableMir<B = (), C = ()>

0 commit comments

Comments
 (0)