@@ -18,6 +18,11 @@ use syntax_pos::Span;
1818use ty:: tls;
1919use ty:: query:: Query ;
2020use ty:: query:: plumbing:: CycleError ;
21+ #[ cfg( not( parallel_queries) ) ]
22+ use ty:: query:: {
23+ plumbing:: TryGetJob ,
24+ config:: QueryDescription ,
25+ } ;
2126use ty:: context:: TyCtxt ;
2227use errors:: Diagnostic ;
2328use std:: process;
@@ -83,44 +88,52 @@ impl<'tcx> QueryJob<'tcx> {
8388 ///
8489 /// For single threaded rustc there's no concurrent jobs running, so if we are waiting for any
8590 /// query that means that there is a query cycle, thus this always running a cycle error.
86- pub ( super ) fn await < ' lcx > (
91+ #[ cfg( not( parallel_queries) ) ]
92+ #[ inline( never) ]
93+ #[ cold]
94+ pub ( super ) fn await < ' lcx , ' a , D : QueryDescription < ' tcx > > (
8795 & self ,
8896 tcx : TyCtxt < ' _ , ' tcx , ' lcx > ,
8997 span : Span ,
90- ) -> Result < ( ) , CycleError < ' tcx > > {
91- #[ cfg( not( parallel_queries) ) ]
92- {
93- self . find_cycle_in_stack ( tcx, span)
94- }
98+ ) -> TryGetJob < ' a , ' tcx , D > {
99+ TryGetJob :: JobCompleted ( Err ( Box :: new ( self . find_cycle_in_stack ( tcx, span) ) ) )
100+ }
95101
96- #[ cfg( parallel_queries) ]
97- {
98- tls:: with_related_context ( tcx, move |icx| {
99- let mut waiter = Lrc :: new ( QueryWaiter {
100- query : icx. query . clone ( ) ,
101- span,
102- cycle : Lock :: new ( None ) ,
103- condvar : Condvar :: new ( ) ,
104- } ) ;
105- self . latch . await ( & waiter) ;
106- // FIXME: Get rid of this lock. We have ownership of the QueryWaiter
107- // although another thread may still have a Lrc reference so we cannot
108- // use Lrc::get_mut
109- let mut cycle = waiter. cycle . lock ( ) ;
110- match cycle. take ( ) {
111- None => Ok ( ( ) ) ,
112- Some ( cycle) => Err ( cycle)
113- }
114- } )
115- }
102+ /// Awaits for the query job to complete.
103+ ///
104+ /// For single threaded rustc there's no concurrent jobs running, so if we are waiting for any
105+ /// query that means that there is a query cycle, thus this always running a cycle error.
106+ #[ cfg( parallel_queries) ]
107+ pub ( super ) fn await < ' lcx > (
108+ & self ,
109+ tcx : TyCtxt < ' _ , ' tcx , ' lcx > ,
110+ span : Span ,
111+ ) -> Result < ( ) , Box < CycleError < ' tcx > > > {
112+ tls:: with_related_context ( tcx, move |icx| {
113+ let mut waiter = Lrc :: new ( QueryWaiter {
114+ query : icx. query . clone ( ) ,
115+ span,
116+ cycle : Lock :: new ( None ) ,
117+ condvar : Condvar :: new ( ) ,
118+ } ) ;
119+ self . latch . await ( & waiter) ;
120+ // FIXME: Get rid of this lock. We have ownership of the QueryWaiter
121+ // although another thread may still have a Lrc reference so we cannot
122+ // use Lrc::get_mut
123+ let mut cycle = waiter. cycle . lock ( ) ;
124+ match cycle. take ( ) {
125+ None => Ok ( ( ) ) ,
126+ Some ( cycle) => Err ( Box :: new ( cycle) )
127+ }
128+ } )
116129 }
117130
118131 #[ cfg( not( parallel_queries) ) ]
119132 fn find_cycle_in_stack < ' lcx > (
120133 & self ,
121134 tcx : TyCtxt < ' _ , ' tcx , ' lcx > ,
122135 span : Span ,
123- ) -> Result < ( ) , CycleError < ' tcx > > {
136+ ) -> CycleError < ' tcx > {
124137 // Get the current executing query (waiter) and find the waitee amongst its parents
125138 let mut current_job = tls:: with_related_context ( tcx, |icx| icx. query . clone ( ) ) ;
126139 let mut cycle = Vec :: new ( ) ;
@@ -140,7 +153,7 @@ impl<'tcx> QueryJob<'tcx> {
140153 let usage = job. parent . as_ref ( ) . map ( |parent| {
141154 ( job. info . span , parent. info . query . clone ( ) )
142155 } ) ;
143- return Err ( CycleError { usage, cycle } ) ;
156+ return CycleError { usage, cycle } ;
144157 }
145158
146159 current_job = job. parent . clone ( ) ;
0 commit comments