@@ -811,10 +811,8 @@ impl RemainingCandidates {
811811    } 
812812} 
813813
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. 
815815/// 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`. 
818816fn  generalize_conflicting ( 
819817    cx :  & Context , 
820818    registry :  & mut  RegistryQueryer < ' _ > , 
@@ -823,15 +821,12 @@ fn generalize_conflicting(
823821    dep :  & Dependency , 
824822    conflicting_activations :  & ConflictMap , 
825823)  -> Option < ConflictMap >  { 
826-     if  conflicting_activations. is_empty ( )  { 
827-         return  None ; 
828-     } 
829824    // 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+     ) ? ; 
835830    let  backtrack_critical_reason:  ConflictReason  =
836831        conflicting_activations[ & backtrack_critical_id] . clone ( ) ; 
837832
@@ -923,6 +918,19 @@ fn generalize_conflicting(
923918    None 
924919} 
925920
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+ 
926934/// Looks through the states in `backtrack_stack` for dependencies with 
927935/// remaining candidates. For each one, also checks if rolling back 
928936/// could change the outcome of the failed resolution that caused backtracking 
@@ -949,12 +957,10 @@ fn find_candidate(
949957    // the cause of that backtrack, so we do not update it. 
950958    let  age = if  !backtracked { 
951959        // 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) 
958964    }  else  { 
959965        None 
960966    } ; 
0 commit comments