@@ -635,15 +635,24 @@ where
635635 ///
636636 /// Goals for the next step get directly added to the nested goals of the `EvalCtxt`.
637637 fn evaluate_added_goals_step ( & mut self ) -> Result < Option < Certainty > , NoSolution > {
638+ if self . nested_goals . is_empty ( ) {
639+ return Ok ( Some ( Certainty :: Yes ) ) ;
640+ }
641+
638642 let cx = self . cx ( ) ;
639643 // If this loop did not result in any progress, what's our final certainty.
640644 let mut unchanged_certainty = Some ( Certainty :: Yes ) ;
641- for ( source, goal, stalled_on) in mem:: take ( & mut self . nested_goals ) {
645+
646+ let mut nested_goals = mem:: take ( & mut self . nested_goals ) ;
647+ let mut pending_goals = vec ! [ ] ;
648+ for ( source, goal, stalled_on) in nested_goals. extract_if ( .., |( _, _, stalled_on) | {
649+ stalled_on. as_ref ( ) . is_none_or ( |s| !self . delegate . is_still_stalled ( s) )
650+ } ) {
642651 if let Some ( certainty) = self . delegate . compute_goal_fast_path ( goal, self . origin_span ) {
643652 match certainty {
644653 Certainty :: Yes => { }
645654 Certainty :: Maybe ( _) => {
646- self . nested_goals . push ( ( source, goal, None ) ) ;
655+ pending_goals . push ( ( source, goal, None ) ) ;
647656 unchanged_certainty = unchanged_certainty. map ( |c| c. and ( certainty) ) ;
648657 }
649658 }
@@ -680,7 +689,7 @@ where
680689 ) ?;
681690 // Add the nested goals from normalization to our own nested goals.
682691 trace ! ( ?nested_goals) ;
683- self . nested_goals . extend ( nested_goals. into_iter ( ) . map ( |( s, g) | ( s, g, None ) ) ) ;
692+ pending_goals . extend ( nested_goals. into_iter ( ) . map ( |( s, g) | ( s, g, None ) ) ) ;
684693
685694 // Finally, equate the goal's RHS with the unconstrained var.
686695 //
@@ -724,7 +733,7 @@ where
724733 match certainty {
725734 Certainty :: Yes => { }
726735 Certainty :: Maybe ( _) => {
727- self . nested_goals . push ( ( source, with_resolved_vars, stalled_on) ) ;
736+ pending_goals . push ( ( source, with_resolved_vars, stalled_on) ) ;
728737 unchanged_certainty = unchanged_certainty. map ( |c| c. and ( certainty) ) ;
729738 }
730739 }
@@ -738,13 +747,25 @@ where
738747 match certainty {
739748 Certainty :: Yes => { }
740749 Certainty :: Maybe ( _) => {
741- self . nested_goals . push ( ( source, goal, stalled_on) ) ;
750+ pending_goals . push ( ( source, goal, stalled_on) ) ;
742751 unchanged_certainty = unchanged_certainty. map ( |c| c. and ( certainty) ) ;
743752 }
744753 }
745754 }
746755 }
747756
757+ // Nested goals still need to be accounted for in the `unchanged_certainty`.
758+ for ( _, _, stalled_on) in & nested_goals {
759+ if let Some ( GoalStalledOn { stalled_cause, .. } ) = stalled_on {
760+ unchanged_certainty =
761+ unchanged_certainty. map ( |c| c. and ( Certainty :: Maybe ( * stalled_cause) ) ) ;
762+ }
763+ }
764+
765+ debug_assert ! ( self . nested_goals. is_empty( ) ) ;
766+ nested_goals. extend ( pending_goals) ;
767+ self . nested_goals = nested_goals;
768+
748769 Ok ( unchanged_certainty)
749770 }
750771
0 commit comments