@@ -162,66 +162,65 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
162162 }
163163 }
164164
165- /// Intern a type. global_interners is Some only if this is
166- /// a local interner and global_interners is its counterpart.
167- fn intern_ty ( & self , st : TypeVariants < ' tcx > ,
168- global_interners : Option < & CtxtInterners < ' gcx > > )
169- -> Ty < ' tcx > {
170- let ty = {
171- let mut interner = self . type_ . borrow_mut ( ) ;
165+ /// Intern a type
166+ fn intern_ty (
167+ local : & CtxtInterners < ' tcx > ,
168+ global : & CtxtInterners < ' gcx > ,
169+ st : TypeVariants < ' tcx >
170+ ) -> Ty < ' tcx > {
171+ let flags = super :: flags:: FlagComputation :: for_sty ( & st) ;
172+
173+ // HACK(eddyb) Depend on flags being accurate to
174+ // determine that all contents are in the global tcx.
175+ // See comments on Lift for why we can't use that.
176+ if flags. flags . intersects ( ty:: TypeFlags :: KEEP_IN_LOCAL_TCX ) {
177+ let mut interner = local. type_ . borrow_mut ( ) ;
172178 if let Some ( & Interned ( ty) ) = interner. get ( & st) {
173179 return ty;
174180 }
175- let global_interner = global_interners. map ( |interners| {
176- ( interners. type_ . borrow_mut ( ) , & interners. arena )
177- } ) ;
178- if let Some ( ( ref type_, _) ) = global_interner {
179- if let Some ( & Interned ( ty) ) = type_. get ( & st) {
180- return ty;
181- }
182- }
183181
184- let flags = super :: flags:: FlagComputation :: for_sty ( & st) ;
185182 let ty_struct = TyS {
186183 sty : st,
187184 flags : flags. flags ,
188185 region_depth : flags. depth ,
189186 } ;
190187
191- // HACK(eddyb) Depend on flags being accurate to
192- // determine that all contents are in the global tcx.
193- // See comments on Lift for why we can't use that.
194- if !flags. flags . intersects ( ty:: TypeFlags :: KEEP_IN_LOCAL_TCX ) {
195- if let Some ( ( mut type_, arena) ) = global_interner {
196- let ty_struct: TyS < ' gcx > = unsafe {
197- mem:: transmute ( ty_struct)
198- } ;
199- let ty: Ty < ' gcx > = arena. alloc ( ty_struct) ;
200- type_. insert ( Interned ( ty) ) ;
201- return ty;
202- }
203- } else {
204- // Make sure we don't end up with inference
205- // types/regions in the global tcx.
206- if global_interner. is_none ( ) {
207- drop ( interner) ;
208- bug ! ( "Attempted to intern `{:?}` which contains \
209- inference types/regions in the global type context",
210- & ty_struct) ;
211- }
188+ // Make sure we don't end up with inference
189+ // types/regions in the global interner
190+ if local as * const _ as usize == global as * const _ as usize {
191+ bug ! ( "Attempted to intern `{:?}` which contains \
192+ inference types/regions in the global type context",
193+ & ty_struct) ;
212194 }
213195
214196 // Don't be &mut TyS.
215- let ty: Ty < ' tcx > = self . arena . alloc ( ty_struct) ;
197+ let ty: Ty < ' tcx > = local . arena . alloc ( ty_struct) ;
216198 interner. insert ( Interned ( ty) ) ;
217199 ty
218- } ;
200+ } else {
201+ let mut interner = global. type_ . borrow_mut ( ) ;
202+ if let Some ( & Interned ( ty) ) = interner. get ( & st) {
203+ return ty;
204+ }
219205
220- debug ! ( "Interned type: {:?} Pointer: {:?}" ,
221- ty, ty as * const TyS ) ;
222- ty
223- }
206+ let ty_struct = TyS {
207+ sty : st,
208+ flags : flags. flags ,
209+ region_depth : flags. depth ,
210+ } ;
211+
212+ // This is safe because all the types the ty_struct can point to
213+ // already is in the global arena
214+ let ty_struct: TyS < ' gcx > = unsafe {
215+ mem:: transmute ( ty_struct)
216+ } ;
224217
218+ // Don't be &mut TyS.
219+ let ty: Ty < ' gcx > = global. arena . alloc ( ty_struct) ;
220+ interner. insert ( Interned ( ty) ) ;
221+ ty
222+ }
223+ }
225224}
226225
227226pub struct CommonTypes < ' tcx > {
@@ -796,7 +795,7 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
796795
797796impl < ' tcx > CommonTypes < ' tcx > {
798797 fn new ( interners : & CtxtInterners < ' tcx > ) -> CommonTypes < ' tcx > {
799- let mk = |sty| interners . intern_ty ( sty , None ) ;
798+ let mk = |sty| CtxtInterners :: intern_ty ( interners , interners , sty ) ;
800799 let mk_region = |r| {
801800 if let Some ( r) = interners. region . borrow ( ) . get ( & r) {
802801 return r. 0 ;
@@ -2130,43 +2129,42 @@ macro_rules! intern_method {
21302129 $keep_in_local_tcx: expr) -> $ty: ty) => {
21312130 impl <' a, ' gcx, $lt_tcx> TyCtxt <' a, ' gcx, $lt_tcx> {
21322131 pub fn $method( self , v: $alloc) -> & $lt_tcx $ty {
2133- {
2134- let key = ( $alloc_to_key) ( & v) ;
2135- if let Some ( i) = self . interners. $name. borrow( ) . get( key) {
2136- return i. 0 ;
2137- }
2138- if !self . is_global( ) {
2139- if let Some ( i) = self . global_interners. $name. borrow( ) . get( key) {
2140- return i. 0 ;
2141- }
2142- }
2143- }
2132+ let key = ( $alloc_to_key) ( & v) ;
21442133
21452134 // HACK(eddyb) Depend on flags being accurate to
21462135 // determine that all contents are in the global tcx.
21472136 // See comments on Lift for why we can't use that.
2148- if !( $keep_in_local_tcx) ( & v) {
2149- if !self . is_global( ) {
2150- let v = unsafe {
2151- mem:: transmute( v)
2152- } ;
2153- let i = ( $alloc_to_ret) ( self . global_interners. arena. $alloc_method( v) ) ;
2154- self . global_interners. $name. borrow_mut( ) . insert( Interned ( i) ) ;
2155- return i;
2137+ if ( $keep_in_local_tcx) ( & v) {
2138+ let mut interner = self . interners. $name. borrow_mut( ) ;
2139+ if let Some ( & Interned ( v) ) = interner. get( key) {
2140+ return v;
21562141 }
2157- } else {
2142+
21582143 // Make sure we don't end up with inference
21592144 // types/regions in the global tcx.
21602145 if self . is_global( ) {
21612146 bug!( "Attempted to intern `{:?}` which contains \
21622147 inference types/regions in the global type context",
21632148 v) ;
21642149 }
2165- }
21662150
2167- let i = ( $alloc_to_ret) ( self . interners. arena. $alloc_method( v) ) ;
2168- self . interners. $name. borrow_mut( ) . insert( Interned ( i) ) ;
2169- i
2151+ let i = ( $alloc_to_ret) ( self . interners. arena. $alloc_method( v) ) ;
2152+ interner. insert( Interned ( i) ) ;
2153+ i
2154+ } else {
2155+ let mut interner = self . global_interners. $name. borrow_mut( ) ;
2156+ if let Some ( & Interned ( v) ) = interner. get( key) {
2157+ return v;
2158+ }
2159+
2160+ // This transmutes $alloc<'tcx> to $alloc<'gcx>
2161+ let v = unsafe {
2162+ mem:: transmute( v)
2163+ } ;
2164+ let i = ( $alloc_to_ret) ( self . global_interners. arena. $alloc_method( v) ) ;
2165+ interner. insert( Interned ( i) ) ;
2166+ i
2167+ }
21702168 }
21712169 }
21722170 }
@@ -2274,15 +2272,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
22742272 self . mk_fn_ptr ( converted_sig)
22752273 }
22762274
2277- // Interns a type/name combination, stores the resulting box in cx.interners,
2278- // and returns the box as cast to an unsafe ptr (see comments for Ty above).
2279- pub fn mk_ty ( self , st : TypeVariants < ' tcx > ) -> Ty < ' tcx > {
2280- let global_interners = if !self . is_global ( ) {
2281- Some ( & self . global_interners )
2282- } else {
2283- None
2284- } ;
2285- self . interners . intern_ty ( st, global_interners)
2275+ pub fn mk_ty ( & self , st : TypeVariants < ' tcx > ) -> Ty < ' tcx > {
2276+ CtxtInterners :: intern_ty ( & self . interners , & self . global_interners , st)
22862277 }
22872278
22882279 pub fn mk_mach_int ( self , tm : ast:: IntTy ) -> Ty < ' tcx > {
0 commit comments