@@ -185,6 +185,10 @@ impl CycleHeads {
185185        self . heads . last ( ) . copied ( ) 
186186    } 
187187
188+     fn  opt_lowest_cycle_head ( & self )  -> Option < StackDepth >  { 
189+         self . heads . first ( ) . copied ( ) 
190+     } 
191+ 
188192    fn  remove_highest_cycle_head ( & mut  self )  { 
189193        let  last = self . heads . pop_last ( ) ; 
190194        debug_assert_ne ! ( last,  None ) ; 
@@ -303,6 +307,7 @@ struct StackEntry<X: Cx> {
303307/// goals still on the stack. 
304308#[ derive_where( Debug ;  X :  Cx ) ]  
305309struct  ProvisionalCacheEntry < X :  Cx >  { 
310+     is_sus :  bool , 
306311    heads :  CycleHeads , 
307312    path_from_head :  CycleKind , 
308313    nested_goals :  NestedGoals < X > , 
@@ -411,7 +416,13 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
411416        let  head = self . stack . next_index ( ) ; 
412417        self . provisional_cache . retain ( |& input,  entries| { 
413418            entries. retain_mut ( |entry| { 
414-                 let  ProvisionalCacheEntry  {  heads,  path_from_head,  nested_goals,  result }  = entry; 
419+                 let  ProvisionalCacheEntry  { 
420+                     is_sus :  _, 
421+                     heads, 
422+                     path_from_head, 
423+                     nested_goals, 
424+                     result, 
425+                 }  = entry; 
415426                if  heads. highest_cycle_head ( )  != head { 
416427                    return  true ; 
417428                } 
@@ -459,6 +470,10 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
459470            return  self . handle_overflow ( cx,  input,  inspect) ; 
460471        } ; 
461472
473+         if  let  Some ( result)  = self . lookup_provisional_cache ( cx,  input)  { 
474+             return  result; 
475+         } 
476+ 
462477        let  validate_cache = if  !D :: inspect_is_noop ( inspect)  { 
463478            None 
464479        }  else  if  let  Some ( scope)  = D :: enter_validation_scope ( cx,  input)  { 
@@ -475,11 +490,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
475490            None 
476491        } ; 
477492
478-         if  let  Some ( result)  = self . lookup_provisional_cache ( cx,  input)  { 
479-             debug_assert ! ( validate_cache. is_none( ) ,  "global cache and provisional entry" ) ; 
480-             return  result; 
481-         } 
482- 
483493        if  let  Some ( result)  = self . check_cycle_on_stack ( cx,  input)  { 
484494            debug_assert ! ( validate_cache. is_none( ) ,  "global cache and cycle on stack" ) ; 
485495            return  result; 
@@ -531,9 +541,16 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
531541        }  else  if  D :: ENABLE_PROVISIONAL_CACHE  { 
532542            debug_assert ! ( validate_cache. is_none( ) ) ; 
533543            let  entry = self . provisional_cache . entry ( input) . or_default ( ) ; 
534-             let  StackEntry  {  heads,  nested_goals,  .. }  = final_entry; 
544+             let  StackEntry  {  heads,  nested_goals,  encountered_overflow,  .. }  = final_entry; 
545+             let  is_sus = encountered_overflow; 
535546            let  path_from_head = Self :: stack_path_kind ( cx,  & self . stack ,  heads. highest_cycle_head ( ) ) ; 
536-             entry. push ( ProvisionalCacheEntry  {  heads,  path_from_head,  nested_goals,  result } ) ; 
547+             entry. push ( ProvisionalCacheEntry  { 
548+                 is_sus, 
549+                 heads, 
550+                 path_from_head, 
551+                 nested_goals, 
552+                 result, 
553+             } ) ; 
537554        }  else  { 
538555            debug_assert ! ( validate_cache. is_none( ) ) ; 
539556        } 
@@ -587,8 +604,13 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
587604            debug ! ( ?input,  ?path_from_global_entry,  ?entries,  "candidate_is_applicable" ) ; 
588605            // A provisional cache entry is applicable if the path to 
589606            // its highest cycle head is equal to the expected path. 
590-             for  ProvisionalCacheEntry  {  heads,  path_from_head,  nested_goals :  _,  result :  _ }  in 
591-                 entries
607+             for  ProvisionalCacheEntry  { 
608+                 is_sus :  _, 
609+                 heads, 
610+                 path_from_head, 
611+                 nested_goals :  _, 
612+                 result :  _, 
613+             }  in  entries. iter ( ) . filter ( |e| !e. is_sus ) 
592614            { 
593615                let  head = heads. highest_cycle_head ( ) ; 
594616                let  full_path = if  Self :: stack_coinductive_from ( cx,  stack,  head)  { 
@@ -682,10 +704,22 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
682704        } 
683705
684706        let  entries = self . provisional_cache . get ( & input) ?; 
685-         for  & ProvisionalCacheEntry  {  ref  heads,  path_from_head,  ref  nested_goals,  result }  in 
686-             entries
707+         for  & ProvisionalCacheEntry  { 
708+             is_sus, 
709+             ref  heads, 
710+             path_from_head, 
711+             ref  nested_goals, 
712+             result, 
713+         }  in  entries
687714        { 
688715            let  head = heads. highest_cycle_head ( ) ; 
716+             if  is_sus { 
717+                 let  last = self . stack . raw . last ( ) . unwrap ( ) ; 
718+                 if  !last. heads . opt_lowest_cycle_head ( ) . is_some_and ( |lowest| lowest <= head)  { 
719+                     continue ; 
720+                 } 
721+             } 
722+ 
689723            if  path_from_head == Self :: stack_path_kind ( cx,  & self . stack ,  head)  { 
690724                // While we don't have to track the full depth of the provisional cache entry, 
691725                // we do have to increment the required depth by one as we'd have already failed 
0 commit comments