@@ -253,22 +253,16 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
253253 type Obligation = PendingPredicateObligation < ' tcx > ;
254254 type Error = FulfillmentErrorCode < ' tcx > ;
255255
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.
260257 ///
261258 /// This is always inlined, despite its size, because it has a single
262259 /// callsite and it is called *very* frequently.
263260 #[ 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 {
268262 // If we were stalled on some unresolved variables, first check whether
269263 // any of them have been resolved; if not, don't bother doing more work
270264 // yet.
271- let change = match pending_obligation. stalled_on . len ( ) {
265+ match pending_obligation. stalled_on . len ( ) {
272266 // Match arms are in order of frequency, which matters because this
273267 // code is so hot. 1 and 0 dominate; 2+ is fairly rare.
274268 1 => {
@@ -291,42 +285,18 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
291285 false
292286 } ) ( )
293287 }
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 ;
303288 }
304-
305- self . process_changed_obligations ( pending_obligation)
306289 }
307290
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.
328298 #[ inline( never) ]
329- fn process_changed_obligations (
299+ fn process_obligation (
330300 & mut self ,
331301 pending_obligation : & mut PendingPredicateObligation < ' tcx > ,
332302 ) -> ProcessResult < PendingPredicateObligation < ' tcx > , FulfillmentErrorCode < ' tcx > > {
@@ -341,6 +311,8 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
341311 self . selcx . infcx ( ) . resolve_vars_if_possible ( obligation. predicate ) ;
342312 }
343313
314+ let obligation = & pending_obligation. obligation ;
315+
344316 debug ! ( ?obligation, ?obligation. cause, "process_obligation" ) ;
345317
346318 let infcx = self . selcx . infcx ( ) ;
@@ -655,6 +627,23 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
655627 }
656628 }
657629
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 > {
658647 #[ instrument( level = "debug" , skip( self , obligation, stalled_on) ) ]
659648 fn process_trait_obligation (
660649 & mut self ,
0 commit comments