@@ -804,6 +804,29 @@ impl<'tcx> ctxt<'tcx> {
804
804
}
805
805
}
806
806
807
+ pub mod tls {
808
+ use middle:: ty;
809
+ use session:: Session ;
810
+
811
+ /// Marker type used for the scoped TLS slot.
812
+ /// The type context cannot be used directly because the scoped TLS
813
+ /// in libstd doesn't allow types generic over lifetimes.
814
+ struct ThreadLocalTyCx ;
815
+
816
+ scoped_thread_local ! ( static TLS_TCX : ThreadLocalTyCx ) ;
817
+
818
+ pub fn enter < ' tcx , F : FnOnce ( & ty:: ctxt < ' tcx > ) -> R , R > ( tcx : ty:: ctxt < ' tcx > , f : F )
819
+ -> ( Session , R ) {
820
+ let tls_ptr = & tcx as * const _ as * const ThreadLocalTyCx ;
821
+ let result = TLS_TCX . set ( unsafe { & * tls_ptr } , || f ( & tcx) ) ;
822
+ ( tcx. sess , result)
823
+ }
824
+
825
+ pub fn with < F : FnOnce ( & ty:: ctxt ) -> R , R > ( f : F ) -> R {
826
+ TLS_TCX . with ( |tcx| f ( unsafe { & * ( tcx as * const _ as * const ty:: ctxt ) } ) )
827
+ }
828
+ }
829
+
807
830
// Flags that we track on types. These flags are propagated upwards
808
831
// through the type during type construction, so that we can quickly
809
832
// check whether the type has various kinds of types in it without
@@ -2824,7 +2847,7 @@ pub fn with_ctxt<'tcx, F, R>(s: Session,
2824
2847
let mut interner = FnvHashMap ( ) ;
2825
2848
let common_types = CommonTypes :: new ( & arenas. type_ , & mut interner) ;
2826
2849
2827
- let tcx = ctxt {
2850
+ tls :: enter ( ctxt {
2828
2851
arenas : arenas,
2829
2852
interner : RefCell :: new ( interner) ,
2830
2853
substs_interner : RefCell :: new ( FnvHashMap ( ) ) ,
@@ -2886,9 +2909,7 @@ pub fn with_ctxt<'tcx, F, R>(s: Session,
2886
2909
const_qualif_map : RefCell :: new ( NodeMap ( ) ) ,
2887
2910
custom_coerce_unsized_kinds : RefCell :: new ( DefIdMap ( ) ) ,
2888
2911
cast_kinds : RefCell :: new ( NodeMap ( ) ) ,
2889
- } ;
2890
- let result = f ( & tcx) ;
2891
- ( tcx. sess , result)
2912
+ } , f)
2892
2913
}
2893
2914
2894
2915
// Type constructors
0 commit comments