@@ -62,7 +62,7 @@ pub struct QueryJob<'tcx> {
6262 pub diagnostics : Lock < Vec < Diagnostic > > ,
6363
6464 #[ cfg( parallel_queries) ]
65- latch : QueryLatch ,
65+ latch : QueryLatch < ' tcx > ,
6666}
6767
6868impl < ' tcx > QueryJob < ' tcx > {
@@ -146,41 +146,45 @@ impl<'tcx> QueryJob<'tcx> {
146146 ///
147147 /// This does nothing for single threaded rustc,
148148 /// as there are no concurrent jobs which could be waiting on us
149- pub fn signal_complete ( & self , tcx : TyCtxt < ' _ , ' tcx , ' _ > ) {
149+ pub fn signal_complete ( & self ) {
150150 #[ cfg( parallel_queries) ]
151- self . latch . set ( tcx ) ;
151+ self . latch . set ( ) ;
152152 }
153153}
154154
155155#[ cfg( parallel_queries) ]
156- struct QueryWaiter < ' a , ' tcx : ' a > {
157- query : & ' a Option < Lrc < QueryJob < ' tcx > > > ,
156+ struct QueryWaiter < ' tcx > {
157+ query : * const Option < Lrc < QueryJob < ' tcx > > > ,
158158 condvar : Condvar ,
159159 span : Span ,
160160 cycle : Option < CycleError < ' tcx > > ,
161161}
162162
163163#[ cfg( parallel_queries) ]
164- impl < ' a , ' tcx > QueryWaiter < ' a , ' tcx > {
165- fn notify ( & self , tcx : TyCtxt < ' _ , ' _ , ' _ > , registry : & rayon_core:: Registry ) {
164+ impl < ' tcx > QueryWaiter < ' tcx > {
165+ fn notify ( & self , registry : & rayon_core:: Registry ) {
166166 rayon_core:: mark_unblocked ( registry) ;
167167 self . condvar . notify_one ( ) ;
168168 }
169169}
170170
171171#[ cfg( parallel_queries) ]
172- struct QueryLatchInfo {
172+ struct QueryLatchInfo < ' tcx > {
173173 complete : bool ,
174- waiters : Vec < & ' static mut QueryWaiter < ' static , ' static > > ,
174+ waiters : Vec < * mut QueryWaiter < ' tcx > > ,
175175}
176176
177+ // Required because of raw pointers
177178#[ cfg( parallel_queries) ]
178- struct QueryLatch {
179- info : Mutex < QueryLatchInfo > ,
179+ unsafe impl < ' tcx > Send for QueryLatchInfo < ' tcx > { }
180+
181+ #[ cfg( parallel_queries) ]
182+ struct QueryLatch < ' tcx > {
183+ info : Mutex < QueryLatchInfo < ' tcx > > ,
180184}
181185
182186#[ cfg( parallel_queries) ]
183- impl QueryLatch {
187+ impl < ' tcx > QueryLatch < ' tcx > {
184188 fn new ( ) -> Self {
185189 QueryLatch {
186190 info : Mutex :: new ( QueryLatchInfo {
@@ -190,44 +194,45 @@ impl QueryLatch {
190194 }
191195 }
192196
193- fn await ( & self , waiter : & mut QueryWaiter < ' _ , ' _ > ) {
197+ fn await ( & self , waiter : & mut QueryWaiter < ' tcx > ) {
194198 let mut info = self . info . lock ( ) ;
195199 if !info. complete {
196- let waiter = & * waiter;
197- unsafe {
198- #[ allow( mutable_transmutes) ]
199- info. waiters . push ( mem:: transmute ( waiter) ) ;
200- }
200+ info. waiters . push ( waiter) ;
201+ let condvar = & waiter. condvar ;
201202 // If this detects a deadlock and the deadlock handler want to resume this thread
202203 // we have to be in the `wait` call. This is ensured by the deadlock handler
203204 // getting the self.info lock.
204205 rayon_core:: mark_blocked ( ) ;
205- waiter . condvar . wait ( & mut info) ;
206+ condvar. wait ( & mut info) ;
206207 }
207208 }
208209
209- fn set ( & self , tcx : TyCtxt < ' _ , ' _ , ' _ > ) {
210+ fn set ( & self ) {
210211 let mut info = self . info . lock ( ) ;
211212 debug_assert ! ( !info. complete) ;
212213 info. complete = true ;
213214 let registry = rayon_core:: Registry :: current ( ) ;
214215 for waiter in info. waiters . drain ( ..) {
215- waiter. notify ( tcx, & registry) ;
216+ unsafe {
217+ ( * waiter) . notify ( & registry) ;
218+ }
216219 }
217220 }
218221
219222 fn resume_waiter (
220223 & self ,
221224 waiter : usize ,
222- error : CycleError
223- ) -> & ' static mut QueryWaiter < ' static , ' static > {
225+ error : CycleError < ' tcx >
226+ ) -> * mut QueryWaiter < ' tcx > {
224227 let mut info = self . info . lock ( ) ;
225228 debug_assert ! ( !info. complete) ;
226229 // Remove the waiter from the list of waiters
227230 let waiter = info. waiters . remove ( waiter) ;
228231
229232 // Set the cycle error it will be picked it up when resumed
230- waiter. cycle = unsafe { Some ( mem:: transmute ( error) ) } ;
233+ unsafe {
234+ ( * waiter) . cycle = Some ( error) ;
235+ }
231236
232237 waiter
233238 }
@@ -250,10 +255,12 @@ where
250255 return Some ( cycle) ;
251256 }
252257 }
253- for ( i, waiter) in query. latch . info . lock ( ) . waiters . iter ( ) . enumerate ( ) {
254- if let Some ( ref waiter_query) = waiter. query {
255- if visit ( waiter. span , & * * waiter_query as Ref ) . is_some ( ) {
256- return Some ( Some ( ( query_ref, i) ) ) ;
258+ for ( i, & waiter) in query. latch . info . lock ( ) . waiters . iter ( ) . enumerate ( ) {
259+ unsafe {
260+ if let Some ( ref waiter_query) = * ( * waiter) . query {
261+ if visit ( ( * waiter) . span , & * * waiter_query as Ref ) . is_some ( ) {
262+ return Some ( Some ( ( query_ref, i) ) ) ;
263+ }
257264 }
258265 }
259266 }
@@ -322,7 +329,7 @@ fn query_entry<'tcx>(r: Ref<'tcx>) -> QueryInfo<'tcx> {
322329#[ cfg( parallel_queries) ]
323330fn remove_cycle < ' tcx > (
324331 jobs : & mut Vec < Ref < ' tcx > > ,
325- wakelist : & mut Vec < & ' static mut QueryWaiter < ' static , ' static > > ,
332+ wakelist : & mut Vec < * mut QueryWaiter < ' tcx > > ,
326333 tcx : TyCtxt < ' _ , ' tcx , ' _ >
327334) {
328335 let mut visited = HashSet :: new ( ) ;
@@ -453,7 +460,9 @@ fn deadlock(tcx: TyCtxt<'_, '_, '_>, registry: &rayon_core::Registry) {
453460
454461 // FIXME: Ensure this won't cause a deadlock before we return
455462 for waiter in wakelist. into_iter ( ) {
456- waiter. notify ( tcx, registry) ;
463+ unsafe {
464+ ( * waiter) . notify ( registry) ;
465+ }
457466 }
458467
459468 on_panic. disable ( ) ;
0 commit comments