4
4
//! until stable MIR is complete.
5
5
6
6
use crate :: rustc_internal;
7
- use crate :: rustc_smir:: Tables ;
7
+ use crate :: rustc_smir:: { Stable , Tables , TablesWrapper } ;
8
8
use rustc_data_structures:: fx;
9
9
use rustc_data_structures:: fx:: FxIndexMap ;
10
10
use rustc_driver:: { Callbacks , Compilation , RunCompiler } ;
@@ -14,11 +14,19 @@ use rustc_middle::ty;
14
14
use rustc_middle:: ty:: TyCtxt ;
15
15
use rustc_span:: def_id:: { CrateNum , DefId } ;
16
16
use rustc_span:: Span ;
17
+ use scoped_tls:: scoped_thread_local;
17
18
use stable_mir:: ty:: IndexedVal ;
18
19
use stable_mir:: CompilerError ;
20
+ use std:: cell:: Cell ;
21
+ use std:: cell:: RefCell ;
19
22
use std:: fmt:: Debug ;
20
23
use std:: hash:: Hash ;
21
24
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
+ }
22
30
23
31
impl < ' tcx > Index < stable_mir:: DefId > for Tables < ' tcx > {
24
32
type Output = DefId ;
@@ -127,18 +135,44 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
127
135
item. id . into ( )
128
136
}
129
137
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
+
130
166
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) ) ;
142
176
}
143
177
144
178
pub struct StableMir < B = ( ) , C = ( ) >
0 commit comments