@@ -82,13 +82,15 @@ use crate::hir;
82
82
pub struct AllArenas < ' tcx > {
83
83
pub global : WorkerLocal < GlobalArenas < ' tcx > > ,
84
84
pub interner : SyncDroplessArena ,
85
+ pub local_interner : SyncDroplessArena ,
85
86
}
86
87
87
88
impl < ' tcx > AllArenas < ' tcx > {
88
89
pub fn new ( ) -> Self {
89
90
AllArenas {
90
91
global : WorkerLocal :: new ( |_| GlobalArenas :: default ( ) ) ,
91
92
interner : SyncDroplessArena :: default ( ) ,
93
+ local_interner : SyncDroplessArena :: default ( ) ,
92
94
}
93
95
}
94
96
}
@@ -154,7 +156,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
154
156
/// Intern a type
155
157
#[ inline( never) ]
156
158
fn intern_ty (
157
- local : & CtxtInterners < ' tcx > ,
159
+ local : & CtxtInterners < ' gcx > ,
158
160
global : & CtxtInterners < ' gcx > ,
159
161
st : TyKind < ' tcx >
160
162
) -> Ty < ' tcx > {
@@ -179,6 +181,12 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
179
181
& ty_struct) ;
180
182
}
181
183
184
+ // This is safe because all the types the ty_struct can point to
185
+ // already is in the local arena or the global arena
186
+ let ty_struct: TyS < ' gcx > = unsafe {
187
+ mem:: transmute ( ty_struct)
188
+ } ;
189
+
182
190
Interned ( local. arena . alloc ( ty_struct) )
183
191
} ) . 0
184
192
} else {
@@ -1029,8 +1037,8 @@ pub struct FreeRegionInfo {
1029
1037
#[ derive( Copy , Clone ) ]
1030
1038
pub struct TyCtxt < ' a , ' gcx : ' tcx , ' tcx : ' a > {
1031
1039
gcx : & ' gcx GlobalCtxt < ' gcx > ,
1032
- interners : & ' tcx CtxtInterners < ' tcx > ,
1033
- dummy : PhantomData < & ' a ( ) > ,
1040
+ interners : & ' gcx CtxtInterners < ' gcx > ,
1041
+ dummy : PhantomData < ( & ' a ( ) , & ' tcx ( ) ) > ,
1034
1042
}
1035
1043
1036
1044
impl < ' gcx > Deref for TyCtxt < ' _ , ' gcx , ' _ > {
@@ -1045,6 +1053,7 @@ pub struct GlobalCtxt<'tcx> {
1045
1053
pub arena : WorkerLocal < Arena < ' tcx > > ,
1046
1054
global_arenas : & ' tcx WorkerLocal < GlobalArenas < ' tcx > > ,
1047
1055
global_interners : CtxtInterners < ' tcx > ,
1056
+ local_interners : CtxtInterners < ' tcx > ,
1048
1057
1049
1058
cstore : & ' tcx CrateStoreDyn ,
1050
1059
@@ -1262,6 +1271,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1262
1271
s. fatal ( & err) ;
1263
1272
} ) ;
1264
1273
let interners = CtxtInterners :: new ( & arenas. interner ) ;
1274
+ let local_interners = CtxtInterners :: new ( & arenas. local_interner ) ;
1265
1275
let common = Common {
1266
1276
empty_predicates : ty:: GenericPredicates {
1267
1277
parent : None ,
@@ -1321,6 +1331,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1321
1331
arena : WorkerLocal :: new ( |_| Arena :: default ( ) ) ,
1322
1332
global_arenas : & arenas. global ,
1323
1333
global_interners : interners,
1334
+ local_interners : local_interners,
1324
1335
dep_graph,
1325
1336
common,
1326
1337
types : common_types,
@@ -1716,18 +1727,15 @@ impl<'gcx> GlobalCtxt<'gcx> {
1716
1727
/// with the same lifetime as `arena`.
1717
1728
pub fn enter_local < ' tcx , F , R > (
1718
1729
& ' gcx self ,
1719
- arena : & ' tcx SyncDroplessArena ,
1720
- interners : & ' tcx mut Option < CtxtInterners < ' tcx > > ,
1721
1730
f : F
1722
1731
) -> R
1723
1732
where
1724
1733
F : FnOnce ( TyCtxt < ' tcx , ' gcx , ' tcx > ) -> R ,
1725
1734
' gcx : ' tcx ,
1726
1735
{
1727
- * interners = Some ( CtxtInterners :: new ( & arena) ) ;
1728
1736
let tcx = TyCtxt {
1729
1737
gcx : self ,
1730
- interners : interners . as_ref ( ) . unwrap ( ) ,
1738
+ interners : & self . local_interners ,
1731
1739
dummy : PhantomData ,
1732
1740
} ;
1733
1741
ty:: tls:: with_related_context ( tcx. global_tcx ( ) , |icx| {
@@ -2333,6 +2341,17 @@ macro_rules! intern_method {
2333
2341
pub fn $method( self , v: $alloc) -> & $lt_tcx $ty {
2334
2342
let key = ( $alloc_to_key) ( & v) ;
2335
2343
2344
+ let alloc = |v, interners: & ' gcx CtxtInterners <' gcx>| {
2345
+ // This transmutes $alloc<'tcx> to $alloc<'gcx>
2346
+ let v = unsafe {
2347
+ mem:: transmute( v)
2348
+ } ;
2349
+ let i: & $lt_tcx $ty = $alloc_method( & interners. arena, v) ;
2350
+ // Cast to 'gcx
2351
+ let i = unsafe { mem:: transmute( i) } ;
2352
+ Interned ( i)
2353
+ } ;
2354
+
2336
2355
// HACK(eddyb) Depend on flags being accurate to
2337
2356
// determine that all contents are in the global tcx.
2338
2357
// See comments on Lift for why we can't use that.
@@ -2346,18 +2365,11 @@ macro_rules! intern_method {
2346
2365
v) ;
2347
2366
}
2348
2367
2349
- Interned ( $alloc_method ( & self . interners. arena , v ) )
2368
+ alloc ( v , & self . interners)
2350
2369
} ) . 0
2351
2370
} else {
2352
2371
self . global_interners. $name. borrow_mut( ) . intern_ref( key, || {
2353
- // This transmutes $alloc<'tcx> to $alloc<'gcx>
2354
- let v = unsafe {
2355
- mem:: transmute( v)
2356
- } ;
2357
- let i: & $lt_tcx $ty = $alloc_method( & self . global_interners. arena, v) ;
2358
- // Cast to 'gcx
2359
- let i = unsafe { mem:: transmute( i) } ;
2360
- Interned ( i)
2372
+ alloc( v, & self . global_interners)
2361
2373
} ) . 0
2362
2374
}
2363
2375
}
0 commit comments