@@ -40,9 +40,9 @@ use rustc_data_structures::profiling::SelfProfilerRef;
4040use rustc_data_structures:: sharded:: { IntoPointer , ShardedHashMap } ;
4141use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
4242use rustc_data_structures:: steal:: Steal ;
43- # [ cfg ( parallel_compiler ) ]
44- use rustc_data_structures :: sync :: DynSend ;
45- use rustc_data_structures :: sync :: { self , FreezeReadGuard , Lock , Lrc , RwLock , WorkerLocal } ;
43+ use rustc_data_structures :: sync :: {
44+ DynSend , DynSync , FreezeReadGuard , Lock , Lrc , RwLock , WorkerLocal ,
45+ } ;
4646use rustc_data_structures:: unord:: UnordSet ;
4747use rustc_errors:: {
4848 DecorateLint , DiagnosticBuilder , DiagnosticMessage , ErrorGuaranteed , MultiSpan ,
@@ -542,7 +542,7 @@ pub struct GlobalCtxt<'tcx> {
542542 ///
543543 /// FIXME(Centril): consider `dyn LintStoreMarker` once
544544 /// we can upcast to `Any` for some additional type safety.
545- pub lint_store : Lrc < dyn Any + sync :: DynSync + sync :: DynSend > ,
545+ pub lint_store : Lrc < dyn Any + DynSync + DynSend > ,
546546
547547 pub dep_graph : DepGraph ,
548548
@@ -601,32 +601,22 @@ impl<'tcx> GlobalCtxt<'tcx> {
601601 {
602602 let icx = tls:: ImplicitCtxt :: new ( self ) ;
603603
604- let gcx_ptr =
605- GcxPtr { value : Lrc :: new ( RwLock :: new ( Some ( icx. tcx . gcx as * const _ as * const ( ) ) ) ) } ;
606-
607- // Reset `gcx_ptr` to `None` when we exit.
608- let gcx_ptr_ = gcx_ptr. clone ( ) ;
604+ // Reset `current_gcx` to `None` when we exit.
609605 let _on_drop = defer ( move || {
610- * gcx_ptr_ . value . write ( ) = None ;
606+ * self . current_gcx . value . write ( ) = None ;
611607 } ) ;
612608
613609 // Set this `GlobalCtxt` as the current one.
614- * self . current_gcx . value . lock ( ) = Some ( gcx_ptr) ;
610+ {
611+ let mut guard = self . current_gcx . value . write ( ) ;
612+ assert ! ( guard. is_none( ) , "no `GlobalCtxt` is currently set" ) ;
613+ * guard = Some ( self as * const _ as * const ( ) ) ;
614+ }
615615
616616 tls:: enter_context ( & icx, || f ( icx. tcx ) )
617617 }
618618}
619619
620- /// This stores a pointer to a `GlobalCtxt`. When the `GlobalCtxt` is no longer available the lock
621- /// will be set to `None`.
622- #[ derive( Clone ) ]
623- struct GcxPtr {
624- value : Lrc < RwLock < Option < * const ( ) > > > ,
625- }
626-
627- #[ cfg( parallel_compiler) ]
628- unsafe impl DynSend for GcxPtr { }
629-
630620/// This is used to get a reference to a `GlobalCtxt` if one is available.
631621///
632622/// This is needed to allow the deadlock handler access to `GlobalCtxt` to look for query cycles.
@@ -635,21 +625,27 @@ unsafe impl DynSend for GcxPtr {}
635625/// the deadlock handler is not called inside such a job.
636626#[ derive( Clone ) ]
637627pub struct CurrentGcx {
638- value : Lrc < Lock < Option < GcxPtr > > > ,
628+ /// This stores a pointer to a `GlobalCtxt`. This is set to `Some` inside `GlobalCtxt::enter`
629+ /// and reset to `None` when that function returns or unwinds.
630+ value : Lrc < RwLock < Option < * const ( ) > > > ,
639631}
640632
633+ #[ cfg( parallel_compiler) ]
634+ unsafe impl DynSend for CurrentGcx { }
635+ #[ cfg( parallel_compiler) ]
636+ unsafe impl DynSync for CurrentGcx { }
637+
641638impl CurrentGcx {
642639 pub fn new ( ) -> Self {
643- Self { value : Lrc :: new ( Lock :: new ( None ) ) }
640+ Self { value : Lrc :: new ( RwLock :: new ( None ) ) }
644641 }
645642
646643 pub fn access < R > ( & self , f : impl for < ' tcx > FnOnce ( & ' tcx GlobalCtxt < ' tcx > ) -> R ) -> R {
647- let gcx_ptr = self . value . lock ( ) . clone ( ) . unwrap ( ) ;
648- let read_guard = gcx_ptr. value . read ( ) ;
644+ let read_guard = self . value . read ( ) ;
649645 let gcx: * const GlobalCtxt < ' _ > = read_guard. unwrap ( ) as * const _ ;
650- // SAFETY: We hold the read lock for `GcxPtr` . That prevents `GlobalCtxt::enter` from
651- // returning as it would first acquire the write lock. This ensures the `GlobalCtxt` is
652- // live during `f`.
646+ // SAFETY: We hold the read lock for the `GlobalCtxt` pointer . That prevents
647+ // `GlobalCtxt::enter` from returning as it would first acquire the write lock.
648+ // This ensures the `GlobalCtxt` is live during `f`.
653649 f ( unsafe { & * gcx } )
654650 }
655651}
@@ -755,7 +751,7 @@ impl<'tcx> TyCtxt<'tcx> {
755751 s : & ' tcx Session ,
756752 crate_types : Vec < CrateType > ,
757753 stable_crate_id : StableCrateId ,
758- lint_store : Lrc < dyn Any + sync :: DynSend + sync :: DynSync > ,
754+ lint_store : Lrc < dyn Any + DynSend + DynSync > ,
759755 arena : & ' tcx WorkerLocal < Arena < ' tcx > > ,
760756 hir_arena : & ' tcx WorkerLocal < hir:: Arena < ' tcx > > ,
761757 untracked : Untracked ,
0 commit comments