|
3 | 3 | //! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
|
4 | 4 | //! until stable MIR is complete.
|
5 | 5 |
|
6 |
| -use crate::rustc_smir::Tables; |
| 6 | +use crate::rustc_smir::{Stable, Tables, TablesWrapper}; |
7 | 7 | use rustc_data_structures::fx;
|
8 | 8 | use rustc_data_structures::fx::FxIndexMap;
|
9 | 9 | use rustc_middle::mir::interpret::AllocId;
|
10 | 10 | use rustc_middle::ty;
|
11 | 11 | use rustc_middle::ty::TyCtxt;
|
12 | 12 | use rustc_span::def_id::{CrateNum, DefId};
|
13 | 13 | use rustc_span::Span;
|
| 14 | +use scoped_tls::scoped_thread_local; |
14 | 15 | use stable_mir::ty::IndexedVal;
|
| 16 | +use std::cell::Cell; |
| 17 | +use std::cell::RefCell; |
15 | 18 | use std::fmt::Debug;
|
16 | 19 | use std::hash::Hash;
|
17 | 20 | use std::ops::Index;
|
18 | 21 |
|
19 | 22 | mod internal;
|
20 | 23 |
|
| 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 | + |
21 | 32 | impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
|
22 | 33 | type Output = DefId;
|
23 | 34 |
|
@@ -125,18 +136,41 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
|
125 | 136 | item.id.into()
|
126 | 137 | }
|
127 | 138 |
|
| 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 | + |
128 | 164 | 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)); |
140 | 174 | }
|
141 | 175 |
|
142 | 176 | #[macro_export]
|
@@ -251,7 +285,7 @@ impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> Index<V
|
251 | 285 | /// Trait used to translate a stable construct to its rustc counterpart.
|
252 | 286 | ///
|
253 | 287 | /// This is basically a mirror of [crate::rustc_smir::Stable].
|
254 |
| -pub(crate) trait RustcInternal<'tcx> { |
| 288 | +pub trait RustcInternal<'tcx> { |
255 | 289 | type T;
|
256 | 290 | fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T;
|
257 | 291 | }
|
0 commit comments