@@ -18,6 +18,11 @@ use syntax_pos::Span;
18
18
use ty:: tls;
19
19
use ty:: query:: Query ;
20
20
use ty:: query:: plumbing:: CycleError ;
21
+ #[ cfg( not( parallel_queries) ) ]
22
+ use ty:: query:: {
23
+ plumbing:: TryGetJob ,
24
+ config:: QueryDescription ,
25
+ } ;
21
26
use ty:: context:: TyCtxt ;
22
27
use errors:: Diagnostic ;
23
28
use std:: process;
@@ -83,44 +88,52 @@ impl<'tcx> QueryJob<'tcx> {
83
88
///
84
89
/// For single threaded rustc there's no concurrent jobs running, so if we are waiting for any
85
90
/// 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 > > (
87
95
& self ,
88
96
tcx : TyCtxt < ' _ , ' tcx , ' lcx > ,
89
97
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
+ }
95
101
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
+ } )
116
129
}
117
130
118
131
#[ cfg( not( parallel_queries) ) ]
119
132
fn find_cycle_in_stack < ' lcx > (
120
133
& self ,
121
134
tcx : TyCtxt < ' _ , ' tcx , ' lcx > ,
122
135
span : Span ,
123
- ) -> Result < ( ) , CycleError < ' tcx > > {
136
+ ) -> CycleError < ' tcx > {
124
137
// Get the current executing query (waiter) and find the waitee amongst its parents
125
138
let mut current_job = tls:: with_related_context ( tcx, |icx| icx. query . clone ( ) ) ;
126
139
let mut cycle = Vec :: new ( ) ;
@@ -140,7 +153,7 @@ impl<'tcx> QueryJob<'tcx> {
140
153
let usage = job. parent . as_ref ( ) . map ( |parent| {
141
154
( job. info . span , parent. info . query . clone ( ) )
142
155
} ) ;
143
- return Err ( CycleError { usage, cycle } ) ;
156
+ return CycleError { usage, cycle } ;
144
157
}
145
158
146
159
current_job = job. parent . clone ( ) ;
0 commit comments