44//! until stable MIR is complete.
55
66use crate :: rustc_internal;
7- use crate :: rustc_smir:: Tables ;
7+ use crate :: rustc_smir:: { Stable , Tables , TablesWrapper } ;
88use rustc_data_structures:: fx;
99use rustc_data_structures:: fx:: FxIndexMap ;
1010use rustc_driver:: { Callbacks , Compilation , RunCompiler } ;
@@ -14,11 +14,19 @@ use rustc_middle::ty;
1414use rustc_middle:: ty:: TyCtxt ;
1515use rustc_span:: def_id:: { CrateNum , DefId } ;
1616use rustc_span:: Span ;
17+ use scoped_tls:: scoped_thread_local;
1718use stable_mir:: ty:: IndexedVal ;
1819use stable_mir:: CompilerError ;
20+ use std:: cell:: Cell ;
21+ use std:: cell:: RefCell ;
1922use std:: fmt:: Debug ;
2023use std:: hash:: Hash ;
2124use 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
2331impl < ' 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+
130166pub 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
144178pub struct StableMir < B = ( ) , C = ( ) >
0 commit comments