@@ -253,22 +253,16 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
253
253
type Obligation = PendingPredicateObligation < ' tcx > ;
254
254
type Error = FulfillmentErrorCode < ' tcx > ;
255
255
256
- /// Processes a predicate obligation and returns either:
257
- /// - `Changed(v)` if the predicate is true, presuming that `v` are also true
258
- /// - `Unchanged` if we don't have enough info to be sure
259
- /// - `Error(e)` if the predicate does not hold
256
+ /// Identifies whether a predicate obligation needs processing.
260
257
///
261
258
/// This is always inlined, despite its size, because it has a single
262
259
/// callsite and it is called *very* frequently.
263
260
#[ inline( always) ]
264
- fn process_obligation (
265
- & mut self ,
266
- pending_obligation : & mut Self :: Obligation ,
267
- ) -> ProcessResult < Self :: Obligation , Self :: Error > {
261
+ fn needs_process_obligation ( & self , pending_obligation : & Self :: Obligation ) -> bool {
268
262
// If we were stalled on some unresolved variables, first check whether
269
263
// any of them have been resolved; if not, don't bother doing more work
270
264
// yet.
271
- let change = match pending_obligation. stalled_on . len ( ) {
265
+ match pending_obligation. stalled_on . len ( ) {
272
266
// Match arms are in order of frequency, which matters because this
273
267
// code is so hot. 1 and 0 dominate; 2+ is fairly rare.
274
268
1 => {
@@ -291,42 +285,18 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
291
285
false
292
286
} ) ( )
293
287
}
294
- } ;
295
-
296
- if !change {
297
- debug ! (
298
- "process_predicate: pending obligation {:?} still stalled on {:?}" ,
299
- self . selcx. infcx( ) . resolve_vars_if_possible( pending_obligation. obligation. clone( ) ) ,
300
- pending_obligation. stalled_on
301
- ) ;
302
- return ProcessResult :: Unchanged ;
303
288
}
304
-
305
- self . process_changed_obligations ( pending_obligation)
306
289
}
307
290
308
- fn process_backedge < ' c , I > (
309
- & mut self ,
310
- cycle : I ,
311
- _marker : PhantomData < & ' c PendingPredicateObligation < ' tcx > > ,
312
- ) where
313
- I : Clone + Iterator < Item = & ' c PendingPredicateObligation < ' tcx > > ,
314
- {
315
- if self . selcx . coinductive_match ( cycle. clone ( ) . map ( |s| s. obligation . predicate ) ) {
316
- debug ! ( "process_child_obligations: coinductive match" ) ;
317
- } else {
318
- let cycle: Vec < _ > = cycle. map ( |c| c. obligation . clone ( ) ) . collect ( ) ;
319
- self . selcx . infcx ( ) . report_overflow_error_cycle ( & cycle) ;
320
- }
321
- }
322
- }
323
-
324
- impl < ' a , ' b , ' tcx > FulfillProcessor < ' a , ' b , ' tcx > {
325
- // The code calling this method is extremely hot and only rarely
326
- // actually uses this, so move this part of the code
327
- // out of that loop.
291
+ /// Processes a predicate obligation and returns either:
292
+ /// - `Changed(v)` if the predicate is true, presuming that `v` are also true
293
+ /// - `Unchanged` if we don't have enough info to be sure
294
+ /// - `Error(e)` if the predicate does not hold
295
+ ///
296
+ /// This is called much less often than `needs_process_obligation`, so we
297
+ /// never inline it.
328
298
#[ inline( never) ]
329
- fn process_changed_obligations (
299
+ fn process_obligation (
330
300
& mut self ,
331
301
pending_obligation : & mut PendingPredicateObligation < ' tcx > ,
332
302
) -> ProcessResult < PendingPredicateObligation < ' tcx > , FulfillmentErrorCode < ' tcx > > {
@@ -341,6 +311,8 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
341
311
self . selcx . infcx ( ) . resolve_vars_if_possible ( obligation. predicate ) ;
342
312
}
343
313
314
+ let obligation = & pending_obligation. obligation ;
315
+
344
316
debug ! ( ?obligation, ?obligation. cause, "process_obligation" ) ;
345
317
346
318
let infcx = self . selcx . infcx ( ) ;
@@ -655,6 +627,23 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
655
627
}
656
628
}
657
629
630
+ fn process_backedge < ' c , I > (
631
+ & mut self ,
632
+ cycle : I ,
633
+ _marker : PhantomData < & ' c PendingPredicateObligation < ' tcx > > ,
634
+ ) where
635
+ I : Clone + Iterator < Item = & ' c PendingPredicateObligation < ' tcx > > ,
636
+ {
637
+ if self . selcx . coinductive_match ( cycle. clone ( ) . map ( |s| s. obligation . predicate ) ) {
638
+ debug ! ( "process_child_obligations: coinductive match" ) ;
639
+ } else {
640
+ let cycle: Vec < _ > = cycle. map ( |c| c. obligation . clone ( ) ) . collect ( ) ;
641
+ self . selcx . infcx ( ) . report_overflow_error_cycle ( & cycle) ;
642
+ }
643
+ }
644
+ }
645
+
646
+ impl < ' a , ' b , ' tcx > FulfillProcessor < ' a , ' b , ' tcx > {
658
647
#[ instrument( level = "debug" , skip( self , obligation, stalled_on) ) ]
659
648
fn process_trait_obligation (
660
649
& mut self ,
0 commit comments