@@ -80,6 +80,61 @@ impl<'tcx> CtxtArenas<'tcx> {
80
80
}
81
81
}
82
82
83
+ struct CtxtInterners < ' tcx > {
84
+ /// The arenas that types etc are allocated from.
85
+ arenas : & ' tcx CtxtArenas < ' tcx > ,
86
+
87
+ /// Specifically use a speedy hash algorithm for these hash sets,
88
+ /// they're accessed quite often.
89
+ type_ : RefCell < FnvHashSet < InternedTy < ' tcx > > > ,
90
+ substs : RefCell < FnvHashSet < InternedSubsts < ' tcx > > > ,
91
+ bare_fn : RefCell < FnvHashSet < & ' tcx BareFnTy < ' tcx > > > ,
92
+ region : RefCell < FnvHashSet < & ' tcx Region > > ,
93
+ stability : RefCell < FnvHashSet < & ' tcx attr:: Stability > > ,
94
+ layout : RefCell < FnvHashSet < & ' tcx Layout > > ,
95
+ }
96
+
97
+ impl < ' tcx > CtxtInterners < ' tcx > {
98
+ fn new ( arenas : & ' tcx CtxtArenas < ' tcx > ) -> CtxtInterners < ' tcx > {
99
+ CtxtInterners {
100
+ arenas : arenas,
101
+ type_ : RefCell :: new ( FnvHashSet ( ) ) ,
102
+ substs : RefCell :: new ( FnvHashSet ( ) ) ,
103
+ bare_fn : RefCell :: new ( FnvHashSet ( ) ) ,
104
+ region : RefCell :: new ( FnvHashSet ( ) ) ,
105
+ stability : RefCell :: new ( FnvHashSet ( ) ) ,
106
+ layout : RefCell :: new ( FnvHashSet ( ) )
107
+ }
108
+ }
109
+
110
+ fn intern_ty ( & self , st : TypeVariants < ' tcx > ) -> Ty < ' tcx > {
111
+ let ty = {
112
+ let mut interner = self . type_ . borrow_mut ( ) ;
113
+ match interner. get ( & st) {
114
+ Some ( & InternedTy { ty } ) => return ty,
115
+ None => ( )
116
+ }
117
+
118
+ let flags = super :: flags:: FlagComputation :: for_sty ( & st) ;
119
+
120
+ // Don't be &mut TyS.
121
+ let ty: Ty = self . arenas . type_ . alloc ( TyS {
122
+ sty : st,
123
+ flags : Cell :: new ( flags. flags ) ,
124
+ region_depth : flags. depth ,
125
+ } ) ;
126
+
127
+ interner. insert ( InternedTy { ty : ty } ) ;
128
+ ty
129
+ } ;
130
+
131
+ debug ! ( "Interned type: {:?} Pointer: {:?}" ,
132
+ ty, ty as * const TyS ) ;
133
+ ty
134
+ }
135
+
136
+ }
137
+
83
138
pub struct CommonTypes < ' tcx > {
84
139
pub bool : Ty < ' tcx > ,
85
140
pub char : Ty < ' tcx > ,
@@ -190,11 +245,8 @@ impl<'a, 'tcx> Tables<'tcx> {
190
245
}
191
246
192
247
impl < ' tcx > CommonTypes < ' tcx > {
193
- fn new ( arena : & ' tcx TypedArena < TyS < ' tcx > > ,
194
- interner : & RefCell < FnvHashSet < InternedTy < ' tcx > > > )
195
- -> CommonTypes < ' tcx >
196
- {
197
- let mk = |sty| TyCtxt :: intern_ty ( arena, interner, sty) ;
248
+ fn new ( interners : & CtxtInterners < ' tcx > ) -> CommonTypes < ' tcx > {
249
+ let mk = |sty| interners. intern_ty ( sty) ;
198
250
CommonTypes {
199
251
bool : mk ( TyBool ) ,
200
252
char : mk ( TyChar ) ,
@@ -221,7 +273,7 @@ impl<'tcx> CommonTypes<'tcx> {
221
273
#[ derive( Copy , Clone ) ]
222
274
pub struct TyCtxt < ' a , ' tcx : ' a > {
223
275
gcx : & ' a GlobalCtxt < ' tcx > ,
224
-
276
+ interners : & ' a CtxtInterners < ' tcx >
225
277
}
226
278
227
279
impl < ' a , ' tcx > Deref for TyCtxt < ' a , ' tcx > {
@@ -232,17 +284,7 @@ impl<'a, 'tcx> Deref for TyCtxt<'a, 'tcx> {
232
284
}
233
285
234
286
pub struct GlobalCtxt < ' tcx > {
235
- /// The arenas that types etc are allocated from.
236
- arenas : & ' tcx CtxtArenas < ' tcx > ,
237
-
238
- /// Specifically use a speedy hash algorithm for this hash map, it's used
239
- /// quite often.
240
- interner : RefCell < FnvHashSet < InternedTy < ' tcx > > > ,
241
- substs_interner : RefCell < FnvHashSet < InternedSubsts < ' tcx > > > ,
242
- bare_fn_interner : RefCell < FnvHashSet < & ' tcx BareFnTy < ' tcx > > > ,
243
- region_interner : RefCell < FnvHashSet < & ' tcx Region > > ,
244
- stability_interner : RefCell < FnvHashSet < & ' tcx attr:: Stability > > ,
245
- layout_interner : RefCell < FnvHashSet < & ' tcx Layout > > ,
287
+ global_interners : CtxtInterners < ' tcx > ,
246
288
247
289
pub dep_graph : DepGraph ,
248
290
@@ -442,6 +484,16 @@ pub struct GlobalCtxt<'tcx> {
442
484
pub layout_cache : RefCell < FnvHashMap < Ty < ' tcx > , & ' tcx Layout > > ,
443
485
}
444
486
487
+ impl < ' tcx > GlobalCtxt < ' tcx > {
488
+ /// Get the global TyCtxt.
489
+ pub fn global_tcx < ' a > ( & ' a self ) -> TyCtxt < ' a , ' tcx > {
490
+ TyCtxt {
491
+ gcx : self ,
492
+ interners : & self . global_interners
493
+ }
494
+ }
495
+ }
496
+
445
497
impl < ' a , ' tcx > TyCtxt < ' a , ' tcx > {
446
498
pub fn crate_name ( self , cnum : ast:: CrateNum ) -> token:: InternedString {
447
499
if cnum == LOCAL_CRATE {
@@ -481,7 +533,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
481
533
pub fn intern_trait_def ( self , def : ty:: TraitDef < ' tcx > )
482
534
-> & ' tcx ty:: TraitDef < ' tcx > {
483
535
let did = def. trait_ref . def_id ;
484
- let interned = self . arenas . trait_defs . alloc ( def) ;
536
+ let interned = self . global_interners . arenas . trait_defs . alloc ( def) ;
485
537
if let Some ( prev) = self . trait_defs . borrow_mut ( ) . insert ( did, interned) {
486
538
bug ! ( "Tried to overwrite interned TraitDef: {:?}" , prev)
487
539
}
@@ -490,7 +542,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
490
542
491
543
pub fn alloc_trait_def ( self , def : ty:: TraitDef < ' tcx > )
492
544
-> & ' tcx ty:: TraitDef < ' tcx > {
493
- self . arenas . trait_defs . alloc ( def)
545
+ self . global_interners . arenas . trait_defs . alloc ( def)
494
546
}
495
547
496
548
pub fn intern_adt_def ( self ,
@@ -499,7 +551,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
499
551
variants : Vec < ty:: VariantDefData < ' tcx , ' tcx > > )
500
552
-> ty:: AdtDefMaster < ' tcx > {
501
553
let def = ty:: AdtDefData :: new ( self , did, kind, variants) ;
502
- let interned = self . arenas . adt_defs . alloc ( def) ;
554
+ let interned = self . global_interners . arenas . adt_defs . alloc ( def) ;
503
555
// this will need a transmute when reverse-variance is removed
504
556
if let Some ( prev) = self . adt_defs . borrow_mut ( ) . insert ( did, interned) {
505
557
bug ! ( "Tried to overwrite interned AdtDef: {:?}" , prev)
@@ -508,12 +560,12 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
508
560
}
509
561
510
562
pub fn intern_stability ( self , stab : attr:: Stability ) -> & ' tcx attr:: Stability {
511
- if let Some ( st) = self . stability_interner . borrow ( ) . get ( & stab) {
563
+ if let Some ( st) = self . interners . stability . borrow ( ) . get ( & stab) {
512
564
return st;
513
565
}
514
566
515
- let interned = self . arenas . stability . alloc ( stab) ;
516
- if let Some ( prev) = self . stability_interner
567
+ let interned = self . interners . arenas . stability . alloc ( stab) ;
568
+ if let Some ( prev) = self . interners . stability
517
569
. borrow_mut ( )
518
570
. replace ( interned) {
519
571
bug ! ( "Tried to overwrite interned Stability: {:?}" , prev)
@@ -522,12 +574,12 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
522
574
}
523
575
524
576
pub fn intern_layout ( self , layout : Layout ) -> & ' tcx Layout {
525
- if let Some ( layout) = self . layout_interner . borrow ( ) . get ( & layout) {
577
+ if let Some ( layout) = self . interners . layout . borrow ( ) . get ( & layout) {
526
578
return layout;
527
579
}
528
580
529
- let interned = self . arenas . layout . alloc ( layout) ;
530
- if let Some ( prev) = self . layout_interner
581
+ let interned = self . interners . arenas . layout . alloc ( layout) ;
582
+ if let Some ( prev) = self . interners . layout
531
583
. borrow_mut ( )
532
584
. replace ( interned) {
533
585
bug ! ( "Tried to overwrite interned Layout: {:?}" , prev)
@@ -568,18 +620,12 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
568
620
where F : for < ' b > FnOnce ( TyCtxt < ' b , ' tcx > ) -> R
569
621
{
570
622
let data_layout = TargetDataLayout :: parse ( s) ;
571
- let interner = RefCell :: new ( FnvHashSet ( ) ) ;
572
- let common_types = CommonTypes :: new ( & arenas . type_ , & interner ) ;
623
+ let interners = CtxtInterners :: new ( arenas ) ;
624
+ let common_types = CommonTypes :: new ( & interners ) ;
573
625
let dep_graph = map. dep_graph . clone ( ) ;
574
626
let fulfilled_predicates = traits:: GlobalFulfilledPredicates :: new ( dep_graph. clone ( ) ) ;
575
627
tls:: enter ( GlobalCtxt {
576
- arenas : arenas,
577
- interner : interner,
578
- substs_interner : RefCell :: new ( FnvHashSet ( ) ) ,
579
- bare_fn_interner : RefCell :: new ( FnvHashSet ( ) ) ,
580
- region_interner : RefCell :: new ( FnvHashSet ( ) ) ,
581
- stability_interner : RefCell :: new ( FnvHashSet ( ) ) ,
582
- layout_interner : RefCell :: new ( FnvHashSet ( ) ) ,
628
+ global_interners : interners,
583
629
dep_graph : dep_graph. clone ( ) ,
584
630
types : common_types,
585
631
named_region_map : named_region_map,
@@ -653,7 +699,7 @@ pub trait Lift<'tcx> {
653
699
impl < ' a , ' tcx > Lift < ' tcx > for Ty < ' a > {
654
700
type Lifted = Ty < ' tcx > ;
655
701
fn lift_to_tcx < ' b > ( & self , tcx : TyCtxt < ' b , ' tcx > ) -> Option < Ty < ' tcx > > {
656
- if let Some ( & InternedTy { ty } ) = tcx. interner . borrow ( ) . get ( & self . sty ) {
702
+ if let Some ( & InternedTy { ty } ) = tcx. interners . type_ . borrow ( ) . get ( & self . sty ) {
657
703
if * self as * const _ == ty as * const _ {
658
704
return Some ( ty) ;
659
705
}
@@ -665,7 +711,7 @@ impl<'a, 'tcx> Lift<'tcx> for Ty<'a> {
665
711
impl < ' a , ' tcx > Lift < ' tcx > for & ' a Substs < ' a > {
666
712
type Lifted = & ' tcx Substs < ' tcx > ;
667
713
fn lift_to_tcx < ' b > ( & self , tcx : TyCtxt < ' b , ' tcx > ) -> Option < & ' tcx Substs < ' tcx > > {
668
- if let Some ( & InternedSubsts { substs } ) = tcx. substs_interner . borrow ( ) . get ( * self ) {
714
+ if let Some ( & InternedSubsts { substs } ) = tcx. interners . substs . borrow ( ) . get ( * self ) {
669
715
if * self as * const _ == substs as * const _ {
670
716
return Some ( substs) ;
671
717
}
@@ -697,18 +743,17 @@ pub mod tls {
697
743
} )
698
744
}
699
745
700
- pub fn enter < ' tcx , F : for < ' a > FnOnce ( TyCtxt < ' a , ' tcx > ) -> R , R > ( gcx : GlobalCtxt < ' tcx > ,
701
- f : F ) -> R {
746
+ pub fn enter < ' tcx , F , R > ( gcx : GlobalCtxt < ' tcx > , f : F ) -> R
747
+ where F : for < ' a > FnOnce ( TyCtxt < ' a , ' tcx > ) -> R
748
+ {
702
749
codemap:: SPAN_DEBUG . with ( |span_dbg| {
703
750
let original_span_debug = span_dbg. get ( ) ;
704
751
span_dbg. set ( span_debug) ;
705
752
let tls_ptr = & gcx as * const _ as * const ThreadLocalGlobalCtxt ;
706
753
let result = TLS_TCX . with ( |tls| {
707
754
let prev = tls. get ( ) ;
708
755
tls. set ( Some ( tls_ptr) ) ;
709
- let ret = f ( TyCtxt {
710
- gcx : & gcx
711
- } ) ;
756
+ let ret = f ( gcx. global_tcx ( ) ) ;
712
757
tls. set ( prev) ;
713
758
ret
714
759
} ) ;
@@ -718,16 +763,18 @@ pub mod tls {
718
763
}
719
764
720
765
pub fn with < F : FnOnce ( TyCtxt ) -> R , R > ( f : F ) -> R {
721
- TLS_TCX . with ( |tcx| {
722
- let tcx = tcx. get ( ) . unwrap ( ) ;
766
+ TLS_TCX . with ( |gcx| {
767
+ let gcx = gcx. get ( ) . unwrap ( ) ;
768
+ let gcx = unsafe { & * ( gcx as * const GlobalCtxt ) } ;
723
769
f ( TyCtxt {
724
- gcx : unsafe { & * ( tcx as * const GlobalCtxt ) }
770
+ gcx : gcx,
771
+ interners : & gcx. global_interners
725
772
} )
726
773
} )
727
774
}
728
775
729
776
pub fn with_opt < F : FnOnce ( Option < TyCtxt > ) -> R , R > ( f : F ) -> R {
730
- if TLS_TCX . with ( |tcx| tcx . get ( ) . is_some ( ) ) {
777
+ if TLS_TCX . with ( |gcx| gcx . get ( ) . is_some ( ) ) {
731
778
with ( |v| f ( Some ( v) ) )
732
779
} else {
733
780
f ( None )
@@ -760,7 +807,7 @@ macro_rules! sty_debug_print {
760
807
$( let mut $variant = total; ) *
761
808
762
809
763
- for & InternedTy { ty: t } in tcx. interner . borrow( ) . iter( ) {
810
+ for & InternedTy { ty: t } in tcx. interners . type_ . borrow( ) . iter( ) {
764
811
let variant = match t. sty {
765
812
ty:: TyBool | ty:: TyChar | ty:: TyInt ( ..) | ty:: TyUint ( ..) |
766
813
ty:: TyFloat ( ..) | ty:: TyStr => continue ,
@@ -806,11 +853,11 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
806
853
TyEnum , TyBox , TyArray , TySlice , TyRawPtr , TyRef , TyFnDef , TyFnPtr ,
807
854
TyTrait , TyStruct , TyClosure , TyTuple , TyParam , TyInfer , TyProjection ) ;
808
855
809
- println ! ( "Substs interner: #{}" , self . substs_interner . borrow( ) . len( ) ) ;
810
- println ! ( "BareFnTy interner: #{}" , self . bare_fn_interner . borrow( ) . len( ) ) ;
811
- println ! ( "Region interner: #{}" , self . region_interner . borrow( ) . len( ) ) ;
812
- println ! ( "Stability interner: #{}" , self . stability_interner . borrow( ) . len( ) ) ;
813
- println ! ( "Layout interner: #{}" , self . layout_interner . borrow( ) . len( ) ) ;
856
+ println ! ( "Substs interner: #{}" , self . interners . substs . borrow( ) . len( ) ) ;
857
+ println ! ( "BareFnTy interner: #{}" , self . interners . bare_fn . borrow( ) . len( ) ) ;
858
+ println ! ( "Region interner: #{}" , self . interners . region . borrow( ) . len( ) ) ;
859
+ println ! ( "Stability interner: #{}" , self . interners . stability . borrow( ) . len( ) ) ;
860
+ println ! ( "Layout interner: #{}" , self . interners . layout . borrow( ) . len( ) ) ;
814
861
}
815
862
}
816
863
@@ -862,12 +909,12 @@ fn bound_list_is_sorted(bounds: &[ty::PolyProjectionPredicate]) -> bool {
862
909
impl < ' a , ' tcx > TyCtxt < ' a , ' tcx > {
863
910
// Type constructors
864
911
pub fn mk_substs ( self , substs : Substs < ' tcx > ) -> & ' tcx Substs < ' tcx > {
865
- if let Some ( interned) = self . substs_interner . borrow ( ) . get ( & substs) {
912
+ if let Some ( interned) = self . interners . substs . borrow ( ) . get ( & substs) {
866
913
return interned. substs ;
867
914
}
868
915
869
- let substs = self . arenas . substs . alloc ( substs) ;
870
- self . substs_interner . borrow_mut ( ) . insert ( InternedSubsts {
916
+ let substs = self . interners . arenas . substs . alloc ( substs) ;
917
+ self . interners . substs . borrow_mut ( ) . insert ( InternedSubsts {
871
918
substs : substs
872
919
} ) ;
873
920
substs
@@ -884,57 +931,29 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
884
931
}
885
932
886
933
pub fn mk_bare_fn ( self , bare_fn : BareFnTy < ' tcx > ) -> & ' tcx BareFnTy < ' tcx > {
887
- if let Some ( bare_fn) = self . bare_fn_interner . borrow ( ) . get ( & bare_fn) {
934
+ if let Some ( bare_fn) = self . interners . bare_fn . borrow ( ) . get ( & bare_fn) {
888
935
return * bare_fn;
889
936
}
890
937
891
- let bare_fn = self . arenas . bare_fn . alloc ( bare_fn) ;
892
- self . bare_fn_interner . borrow_mut ( ) . insert ( bare_fn) ;
938
+ let bare_fn = self . interners . arenas . bare_fn . alloc ( bare_fn) ;
939
+ self . interners . bare_fn . borrow_mut ( ) . insert ( bare_fn) ;
893
940
bare_fn
894
941
}
895
942
896
943
pub fn mk_region ( self , region : Region ) -> & ' tcx Region {
897
- if let Some ( region) = self . region_interner . borrow ( ) . get ( & region) {
944
+ if let Some ( region) = self . interners . region . borrow ( ) . get ( & region) {
898
945
return * region;
899
946
}
900
947
901
- let region = self . arenas . region . alloc ( region) ;
902
- self . region_interner . borrow_mut ( ) . insert ( region) ;
948
+ let region = self . interners . arenas . region . alloc ( region) ;
949
+ self . interners . region . borrow_mut ( ) . insert ( region) ;
903
950
region
904
951
}
905
952
906
- fn intern_ty ( type_arena : & ' tcx TypedArena < TyS < ' tcx > > ,
907
- interner : & RefCell < FnvHashSet < InternedTy < ' tcx > > > ,
908
- st : TypeVariants < ' tcx > )
909
- -> Ty < ' tcx > {
910
- let ty: Ty /* don't be &mut TyS */ = {
911
- let mut interner = interner. borrow_mut ( ) ;
912
- match interner. get ( & st) {
913
- Some ( & InternedTy { ty } ) => return ty,
914
- None => ( )
915
- }
916
-
917
- let flags = super :: flags:: FlagComputation :: for_sty ( & st) ;
918
-
919
- let ty = match ( ) {
920
- ( ) => type_arena. alloc ( TyS { sty : st,
921
- flags : Cell :: new ( flags. flags ) ,
922
- region_depth : flags. depth , } ) ,
923
- } ;
924
-
925
- interner. insert ( InternedTy { ty : ty } ) ;
926
- ty
927
- } ;
928
-
929
- debug ! ( "Interned type: {:?} Pointer: {:?}" ,
930
- ty, ty as * const TyS ) ;
931
- ty
932
- }
933
-
934
- // Interns a type/name combination, stores the resulting box in cx.interner,
953
+ // Interns a type/name combination, stores the resulting box in cx.interners,
935
954
// and returns the box as cast to an unsafe ptr (see comments for Ty above).
936
955
pub fn mk_ty ( self , st : TypeVariants < ' tcx > ) -> Ty < ' tcx > {
937
- TyCtxt :: intern_ty ( & self . arenas . type_ , & self . interner , st)
956
+ self . interners . intern_ty ( st)
938
957
}
939
958
940
959
pub fn mk_mach_int ( self , tm : ast:: IntTy ) -> Ty < ' tcx > {
0 commit comments