@@ -10,6 +10,7 @@ use std::cmp::Ordering;
1010use std:: hash:: { Hash , Hasher } ;
1111use std:: marker:: PhantomData ;
1212use std:: ops:: { Bound , Deref } ;
13+ use std:: sync:: OnceLock ;
1314use std:: { fmt, iter, mem} ;
1415
1516use rustc_abi:: { ExternAbi , FieldIdx , Layout , LayoutData , TargetDataLayout , VariantIdx } ;
@@ -1347,33 +1348,6 @@ pub struct GlobalCtxt<'tcx> {
13471348
13481349 /// Stores memory for globals (statics/consts).
13491350 pub ( crate ) alloc_map : Lock < interpret:: AllocMap < ' tcx > > ,
1350-
1351- current_gcx : CurrentGcx ,
1352- }
1353-
1354- impl < ' tcx > GlobalCtxt < ' tcx > {
1355- /// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of
1356- /// `f`.
1357- pub fn enter < F , R > ( & ' tcx self , f : F ) -> R
1358- where
1359- F : FnOnce ( TyCtxt < ' tcx > ) -> R ,
1360- {
1361- let icx = tls:: ImplicitCtxt :: new ( self ) ;
1362-
1363- // Reset `current_gcx` to `None` when we exit.
1364- let _on_drop = defer ( move || {
1365- * self . current_gcx . value . write ( ) = None ;
1366- } ) ;
1367-
1368- // Set this `GlobalCtxt` as the current one.
1369- {
1370- let mut guard = self . current_gcx . value . write ( ) ;
1371- assert ! ( guard. is_none( ) , "no `GlobalCtxt` is currently set" ) ;
1372- * guard = Some ( self as * const _ as * const ( ) ) ;
1373- }
1374-
1375- tls:: enter_context ( & icx, || f ( icx. tcx ) )
1376- }
13771351}
13781352
13791353/// This is used to get a reference to a `GlobalCtxt` if one is available.
@@ -1517,7 +1491,8 @@ impl<'tcx> TyCtxt<'tcx> {
15171491 /// By only providing the `TyCtxt` inside of the closure we enforce that the type
15181492 /// context and any interned value (types, args, etc.) can only be used while `ty::tls`
15191493 /// has a valid reference to the context, to allow formatting values that need it.
1520- pub fn create_global_ctxt (
1494+ pub fn create_global_ctxt < T > (
1495+ gcx_cell : & ' tcx OnceLock < GlobalCtxt < ' tcx > > ,
15211496 s : & ' tcx Session ,
15221497 crate_types : Vec < CrateType > ,
15231498 stable_crate_id : StableCrateId ,
@@ -1529,7 +1504,8 @@ impl<'tcx> TyCtxt<'tcx> {
15291504 query_system : QuerySystem < ' tcx > ,
15301505 hooks : crate :: hooks:: Providers ,
15311506 current_gcx : CurrentGcx ,
1532- ) -> GlobalCtxt < ' tcx > {
1507+ f : impl FnOnce ( TyCtxt < ' tcx > ) -> T ,
1508+ ) -> T {
15331509 let data_layout = s. target . parse_data_layout ( ) . unwrap_or_else ( |err| {
15341510 s. dcx ( ) . emit_fatal ( err) ;
15351511 } ) ;
@@ -1538,7 +1514,7 @@ impl<'tcx> TyCtxt<'tcx> {
15381514 let common_lifetimes = CommonLifetimes :: new ( & interners) ;
15391515 let common_consts = CommonConsts :: new ( & interners, & common_types, s, & untracked) ;
15401516
1541- GlobalCtxt {
1517+ let gcx = gcx_cell . get_or_init ( || GlobalCtxt {
15421518 sess : s,
15431519 crate_types,
15441520 stable_crate_id,
@@ -1562,8 +1538,23 @@ impl<'tcx> TyCtxt<'tcx> {
15621538 canonical_param_env_cache : Default :: default ( ) ,
15631539 data_layout,
15641540 alloc_map : Lock :: new ( interpret:: AllocMap :: new ( ) ) ,
1565- current_gcx,
1541+ } ) ;
1542+
1543+ let icx = tls:: ImplicitCtxt :: new ( & gcx) ;
1544+
1545+ // Reset `current_gcx` to `None` when we exit.
1546+ let _on_drop = defer ( || {
1547+ * current_gcx. value . write ( ) = None ;
1548+ } ) ;
1549+
1550+ // Set this `GlobalCtxt` as the current one.
1551+ {
1552+ let mut guard = current_gcx. value . write ( ) ;
1553+ assert ! ( guard. is_none( ) , "no `GlobalCtxt` is currently set" ) ;
1554+ * guard = Some ( & gcx as * const _ as * const ( ) ) ;
15661555 }
1556+
1557+ tls:: enter_context ( & icx, || f ( icx. tcx ) )
15671558 }
15681559
15691560 /// Obtain all lang items of this crate and all dependencies (recursively)
0 commit comments