@@ -3,6 +3,7 @@ use std::marker::PhantomData;
3
3
use rustc_data_structures:: obligation_forest:: {
4
4
Error , ForestObligation , ObligationForest , ObligationProcessor , Outcome , ProcessResult ,
5
5
} ;
6
+ use rustc_hir:: def_id:: LocalDefId ;
6
7
use rustc_infer:: infer:: DefineOpaqueTypes ;
7
8
use rustc_infer:: traits:: {
8
9
FromSolverError , PolyTraitObligation , PredicateObligations , ProjectionCacheKey , SelectionError ,
@@ -11,7 +12,10 @@ use rustc_infer::traits::{
11
12
use rustc_middle:: bug;
12
13
use rustc_middle:: ty:: abstract_const:: NotConstEvaluatable ;
13
14
use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
14
- use rustc_middle:: ty:: { self , Binder , Const , GenericArgsRef , TypeVisitableExt , TypingMode } ;
15
+ use rustc_middle:: ty:: {
16
+ self , Binder , Const , GenericArgsRef , TypeVisitable , TypeVisitableExt , TypingMode ,
17
+ } ;
18
+ use rustc_span:: DUMMY_SP ;
15
19
use thin_vec:: ThinVec ;
16
20
use tracing:: { debug, debug_span, instrument} ;
17
21
@@ -24,6 +28,7 @@ use super::{
24
28
} ;
25
29
use crate :: error_reporting:: InferCtxtErrorExt ;
26
30
use crate :: infer:: { InferCtxt , TyOrConstInferVar } ;
31
+ use crate :: solve:: StalledOnCoroutines ;
27
32
use crate :: traits:: normalize:: normalize_with_depth_to;
28
33
use crate :: traits:: project:: { PolyProjectionObligation , ProjectionCacheKeyExt as _} ;
29
34
use crate :: traits:: query:: evaluate_obligation:: InferCtxtExt ;
@@ -166,15 +171,33 @@ where
166
171
& mut self ,
167
172
infcx : & InferCtxt < ' tcx > ,
168
173
) -> PredicateObligations < ' tcx > {
169
- let mut processor =
170
- DrainProcessor { removed_predicates : PredicateObligations :: new ( ) , infcx } ;
174
+ let stalled_coroutines = match infcx. typing_mode ( ) {
175
+ TypingMode :: Analysis { defining_opaque_types_and_generators } => {
176
+ defining_opaque_types_and_generators
177
+ }
178
+ TypingMode :: Coherence
179
+ | TypingMode :: Borrowck { defining_opaque_types : _ }
180
+ | TypingMode :: PostBorrowckAnalysis { defined_opaque_types : _ }
181
+ | TypingMode :: PostAnalysis => return Default :: default ( ) ,
182
+ } ;
183
+
184
+ if stalled_coroutines. is_empty ( ) {
185
+ return Default :: default ( ) ;
186
+ }
187
+
188
+ let mut processor = DrainProcessor {
189
+ infcx,
190
+ removed_predicates : PredicateObligations :: new ( ) ,
191
+ stalled_coroutines,
192
+ } ;
171
193
let outcome: Outcome < _ , _ > = self . predicates . process_obligations ( & mut processor) ;
172
194
assert ! ( outcome. errors. is_empty( ) ) ;
173
195
return processor. removed_predicates ;
174
196
175
197
struct DrainProcessor < ' a , ' tcx > {
176
198
infcx : & ' a InferCtxt < ' tcx > ,
177
199
removed_predicates : PredicateObligations < ' tcx > ,
200
+ stalled_coroutines : & ' tcx ty:: List < LocalDefId > ,
178
201
}
179
202
180
203
impl < ' tcx > ObligationProcessor for DrainProcessor < ' _ , ' tcx > {
@@ -183,10 +206,14 @@ where
183
206
type OUT = Outcome < Self :: Obligation , Self :: Error > ;
184
207
185
208
fn needs_process_obligation ( & self , pending_obligation : & Self :: Obligation ) -> bool {
186
- pending_obligation
187
- . stalled_on
188
- . iter ( )
189
- . any ( |& var| self . infcx . ty_or_const_infer_var_changed ( var) )
209
+ self . infcx
210
+ . resolve_vars_if_possible ( pending_obligation. obligation . predicate )
211
+ . visit_with ( & mut StalledOnCoroutines {
212
+ stalled_coroutines : self . stalled_coroutines ,
213
+ span : DUMMY_SP ,
214
+ cache : Default :: default ( ) ,
215
+ } )
216
+ . is_break ( )
190
217
}
191
218
192
219
fn process_obligation (
0 commit comments