@@ -185,7 +185,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
185185    f :  F , 
186186)  -> R  { 
187187    use  rustc_data_structures:: { jobserver,  sync:: FromDyn } ; 
188-     use  rustc_middle:: ty:: tls; 
188+     use  rustc_middle:: ty:: tls:: { self ,   GcxPtr } ; 
189189    use  rustc_query_impl:: QueryCtxt ; 
190190    use  rustc_query_system:: query:: { deadlock,  QueryContext } ; 
191191
@@ -208,18 +208,34 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
208208        . deadlock_handler ( || { 
209209            // On deadlock, creates a new thread and forwards information in thread 
210210            // locals to it. The new thread runs the deadlock handler. 
211-             let  query_map = FromDyn :: from ( tls:: with ( |tcx| { 
212-                 QueryCtxt :: new ( tcx) 
213-                     . try_collect_active_jobs ( ) 
214-                     . expect ( "active jobs shouldn't be locked in deadlock handler" ) 
215-             } ) ) ; 
211+             let  query_map = FromDyn :: from ( { 
212+                 // Get a GlobalCtxt reference from GCX_PTR as we cannot rely on having a TyCtxt TLS 
213+                 // reference here. 
214+                 // SAFETY: No thread will end the lifetime of  `GlobalCtxt` as they're deadlocked 
215+                 // and won't resume until the `deadlock` call. 
216+                 unsafe  { 
217+                     tls:: GCX_PTR . with ( |gcx_ptr| { 
218+                         gcx_ptr. access ( |gcx| { 
219+                             tls:: enter_context ( & tls:: ImplicitCtxt :: new ( gcx) ,  || { 
220+                                 tls:: with ( |tcx| { 
221+                                     QueryCtxt :: new ( tcx) . try_collect_active_jobs ( ) . expect ( 
222+                                         "active jobs shouldn't be locked in deadlock handler" , 
223+                                     ) 
224+                                 } ) 
225+                             } ) 
226+                         } ) 
227+                     } ) 
228+                 } 
229+             } ) ; 
216230            let  registry = rayon_core:: Registry :: current ( ) ; 
217231            thread:: spawn ( move  || deadlock ( query_map. into_inner ( ) ,  & registry) ) ; 
218232        } ) ; 
219233    if  let  Some ( size)  = get_stack_size ( )  { 
220234        builder = builder. stack_size ( size) ; 
221235    } 
222236
237+     let  gcx_ptr = GcxPtr :: new ( ) ; 
238+ 
223239    // We create the session globals on the main thread, then create the thread 
224240    // pool. Upon creation, each worker thread created gets a copy of the 
225241    // session globals in TLS. This is possible because `SessionGlobals` impls 
@@ -235,7 +251,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
235251                        registry. register ( ) ; 
236252
237253                        rustc_span:: set_session_globals_then ( session_globals. into_inner ( ) ,  || { 
238-                             thread. run ( ) 
254+                             tls :: GCX_PTR . set ( & gcx_ptr ,  ||  thread. run ( ) ) 
239255                        } ) 
240256                    } , 
241257                    // Run `f` on the first thread in the thread pool. 
0 commit comments