@@ -81,12 +81,14 @@ use crate::hir;
8181
8282pub struct AllArenas {
8383 pub interner : SyncDroplessArena ,
84+ pub local_interner : SyncDroplessArena ,
8485}
8586
8687impl AllArenas {
8788 pub fn new ( ) -> Self {
8889 AllArenas {
8990 interner : SyncDroplessArena :: default ( ) ,
91+ local_interner : SyncDroplessArena :: default ( ) ,
9092 }
9193 }
9294}
@@ -135,7 +137,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
135137 /// Intern a type
136138 #[ inline( never) ]
137139 fn intern_ty (
138- local : & CtxtInterners < ' tcx > ,
140+ local : & CtxtInterners < ' gcx > ,
139141 global : & CtxtInterners < ' gcx > ,
140142 st : TyKind < ' tcx >
141143 ) -> Ty < ' tcx > {
@@ -160,6 +162,12 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
160162 & ty_struct) ;
161163 }
162164
165+ // This is safe because all the types the ty_struct can point to
166+ // already is in the local arena or the global arena
167+ let ty_struct: TyS < ' gcx > = unsafe {
168+ mem:: transmute ( ty_struct)
169+ } ;
170+
163171 Interned ( local. arena . alloc ( ty_struct) )
164172 } ) . 0
165173 } else {
@@ -1010,8 +1018,8 @@ pub struct FreeRegionInfo {
10101018#[ derive( Copy , Clone ) ]
10111019pub struct TyCtxt < ' a , ' gcx : ' tcx , ' tcx : ' a > {
10121020 gcx : & ' gcx GlobalCtxt < ' gcx > ,
1013- interners : & ' tcx CtxtInterners < ' tcx > ,
1014- dummy : PhantomData < & ' a ( ) > ,
1021+ interners : & ' gcx CtxtInterners < ' gcx > ,
1022+ dummy : PhantomData < ( & ' a ( ) , & ' tcx ( ) ) > ,
10151023}
10161024
10171025impl < ' gcx > Deref for TyCtxt < ' _ , ' gcx , ' _ > {
@@ -1026,6 +1034,7 @@ pub struct GlobalCtxt<'tcx> {
10261034 pub arena : WorkerLocal < Arena < ' tcx > > ,
10271035
10281036 global_interners : CtxtInterners < ' tcx > ,
1037+ local_interners : CtxtInterners < ' tcx > ,
10291038
10301039 cstore : & ' tcx CrateStoreDyn ,
10311040
@@ -1222,6 +1231,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12221231 s. fatal ( & err) ;
12231232 } ) ;
12241233 let interners = CtxtInterners :: new ( & arenas. interner ) ;
1234+ let local_interners = CtxtInterners :: new ( & arenas. local_interner ) ;
12251235 let common = Common {
12261236 empty_predicates : ty:: GenericPredicates {
12271237 parent : None ,
@@ -1280,6 +1290,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12801290 cstore,
12811291 arena : WorkerLocal :: new ( |_| Arena :: default ( ) ) ,
12821292 global_interners : interners,
1293+ local_interners : local_interners,
12831294 dep_graph,
12841295 common,
12851296 types : common_types,
@@ -1669,18 +1680,15 @@ impl<'gcx> GlobalCtxt<'gcx> {
16691680 /// with the same lifetime as `arena`.
16701681 pub fn enter_local < ' tcx , F , R > (
16711682 & ' gcx self ,
1672- arena : & ' tcx SyncDroplessArena ,
1673- interners : & ' tcx mut Option < CtxtInterners < ' tcx > > ,
16741683 f : F
16751684 ) -> R
16761685 where
16771686 F : FnOnce ( TyCtxt < ' tcx , ' gcx , ' tcx > ) -> R ,
16781687 ' gcx : ' tcx ,
16791688 {
1680- * interners = Some ( CtxtInterners :: new ( & arena) ) ;
16811689 let tcx = TyCtxt {
16821690 gcx : self ,
1683- interners : interners . as_ref ( ) . unwrap ( ) ,
1691+ interners : & self . local_interners ,
16841692 dummy : PhantomData ,
16851693 } ;
16861694 ty:: tls:: with_related_context ( tcx. global_tcx ( ) , |icx| {
@@ -2286,6 +2294,17 @@ macro_rules! intern_method {
22862294 pub fn $method( self , v: $alloc) -> & $lt_tcx $ty {
22872295 let key = ( $alloc_to_key) ( & v) ;
22882296
2297+ let alloc = |v, interners: & ' gcx CtxtInterners <' gcx>| {
2298+ // This transmutes $alloc<'tcx> to $alloc<'gcx>
2299+ let v = unsafe {
2300+ mem:: transmute( v)
2301+ } ;
2302+ let i: & $lt_tcx $ty = $alloc_method( & interners. arena, v) ;
2303+ // Cast to 'gcx
2304+ let i = unsafe { mem:: transmute( i) } ;
2305+ Interned ( i)
2306+ } ;
2307+
22892308 // HACK(eddyb) Depend on flags being accurate to
22902309 // determine that all contents are in the global tcx.
22912310 // See comments on Lift for why we can't use that.
@@ -2299,18 +2318,11 @@ macro_rules! intern_method {
22992318 v) ;
23002319 }
23012320
2302- Interned ( $alloc_method ( & self . interners. arena , v ) )
2321+ alloc ( v , & self . interners)
23032322 } ) . 0
23042323 } else {
23052324 self . global_interners. $name. borrow_mut( ) . intern_ref( key, || {
2306- // This transmutes $alloc<'tcx> to $alloc<'gcx>
2307- let v = unsafe {
2308- mem:: transmute( v)
2309- } ;
2310- let i: & $lt_tcx $ty = $alloc_method( & self . global_interners. arena, v) ;
2311- // Cast to 'gcx
2312- let i = unsafe { mem:: transmute( i) } ;
2313- Interned ( i)
2325+ alloc( v, & self . global_interners)
23142326 } ) . 0
23152327 }
23162328 }
0 commit comments