| 
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