@@ -635,15 +635,24 @@ where
635
635
///
636
636
/// Goals for the next step get directly added to the nested goals of the `EvalCtxt`.
637
637
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
+
638
642
let cx = self . cx ( ) ;
639
643
// If this loop did not result in any progress, what's our final certainty.
640
644
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
+ } ) {
642
651
if let Some ( certainty) = self . delegate . compute_goal_fast_path ( goal, self . origin_span ) {
643
652
match certainty {
644
653
Certainty :: Yes => { }
645
654
Certainty :: Maybe ( _) => {
646
- self . nested_goals . push ( ( source, goal, None ) ) ;
655
+ pending_goals . push ( ( source, goal, None ) ) ;
647
656
unchanged_certainty = unchanged_certainty. map ( |c| c. and ( certainty) ) ;
648
657
}
649
658
}
@@ -680,7 +689,7 @@ where
680
689
) ?;
681
690
// Add the nested goals from normalization to our own nested goals.
682
691
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 ) ) ) ;
684
693
685
694
// Finally, equate the goal's RHS with the unconstrained var.
686
695
//
@@ -724,7 +733,7 @@ where
724
733
match certainty {
725
734
Certainty :: Yes => { }
726
735
Certainty :: Maybe ( _) => {
727
- self . nested_goals . push ( ( source, with_resolved_vars, stalled_on) ) ;
736
+ pending_goals . push ( ( source, with_resolved_vars, stalled_on) ) ;
728
737
unchanged_certainty = unchanged_certainty. map ( |c| c. and ( certainty) ) ;
729
738
}
730
739
}
@@ -738,13 +747,25 @@ where
738
747
match certainty {
739
748
Certainty :: Yes => { }
740
749
Certainty :: Maybe ( _) => {
741
- self . nested_goals . push ( ( source, goal, stalled_on) ) ;
750
+ pending_goals . push ( ( source, goal, stalled_on) ) ;
742
751
unchanged_certainty = unchanged_certainty. map ( |c| c. and ( certainty) ) ;
743
752
}
744
753
}
745
754
}
746
755
}
747
756
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
+
748
769
Ok ( unchanged_certainty)
749
770
}
750
771
0 commit comments