Use ExtractIf in evaluate_added_goals_step · rust-lang/rust@dfc9304 (original) (raw)
`@@ -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, 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
``