@@ -811,10 +811,8 @@ impl RemainingCandidates {
811
811
}
812
812
}
813
813
814
- /// Attempts to find a new conflict that allows a `find_candidate` feather then the input one.
814
+ /// Attempts to find a new conflict that allows a `find_candidate` better then the input one.
815
815
/// It will add the new conflict to the cache if one is found.
816
- ///
817
- /// Panics if the input conflict is not all active in `cx`.
818
816
fn generalize_conflicting (
819
817
cx : & Context ,
820
818
registry : & mut RegistryQueryer < ' _ > ,
@@ -823,15 +821,12 @@ fn generalize_conflicting(
823
821
dep : & Dependency ,
824
822
conflicting_activations : & ConflictMap ,
825
823
) -> Option < ConflictMap > {
826
- if conflicting_activations. is_empty ( ) {
827
- return None ;
828
- }
829
824
// We need to determine the `ContextAge` that this `conflicting_activations` will jump to, and why.
830
- let ( backtrack_critical_age, backtrack_critical_id) = conflicting_activations
831
- . keys ( )
832
- . map ( | & c| ( cx . is_active ( c ) . expect ( "not currently active!?" ) , c ) )
833
- . max ( )
834
- . unwrap ( ) ;
825
+ let ( backtrack_critical_age, backtrack_critical_id) = shortcircuit_max (
826
+ conflicting_activations
827
+ . keys ( )
828
+ . map ( | & c| cx . is_active ( c ) . map ( |a| ( a , c ) ) ) ,
829
+ ) ? ;
835
830
let backtrack_critical_reason: ConflictReason =
836
831
conflicting_activations[ & backtrack_critical_id] . clone ( ) ;
837
832
@@ -923,6 +918,19 @@ fn generalize_conflicting(
923
918
None
924
919
}
925
920
921
+ /// Returns Some of the largest item in the iterator.
922
+ /// Returns None if any of the items are None or the iterator is empty.
923
+ fn shortcircuit_max < I : Ord > ( iter : impl Iterator < Item = Option < I > > ) -> Option < I > {
924
+ let mut out = None ;
925
+ for i in iter {
926
+ if i. is_none ( ) {
927
+ return None ;
928
+ }
929
+ out = std:: cmp:: max ( out, i) ;
930
+ }
931
+ out
932
+ }
933
+
926
934
/// Looks through the states in `backtrack_stack` for dependencies with
927
935
/// remaining candidates. For each one, also checks if rolling back
928
936
/// could change the outcome of the failed resolution that caused backtracking
@@ -949,12 +957,10 @@ fn find_candidate(
949
957
// the cause of that backtrack, so we do not update it.
950
958
let age = if !backtracked {
951
959
// we don't have abnormal situations. So we can ask `cx` for how far back we need to go.
952
- let a = cx. is_conflicting ( Some ( parent. package_id ( ) ) , conflicting_activations) ;
953
- // If the `conflicting_activations` does not apply to `cx`, then something went very wrong
954
- // in building it. But we will just fall back to laboriously trying all possibilities witch
955
- // will give us the correct answer so only `assert` if there is a developer to debug it.
956
- debug_assert ! ( a. is_some( ) ) ;
957
- a
960
+ // If the `conflicting_activations` does not apply to `cx`,
961
+ // we will just fall back to laboriously trying all possibilities witch
962
+ // will give us the correct answer.
963
+ cx. is_conflicting ( Some ( parent. package_id ( ) ) , conflicting_activations)
958
964
} else {
959
965
None
960
966
} ;
0 commit comments