@@ -890,31 +890,38 @@ fn generalize_conflicting(
890890        return  None ; 
891891    } 
892892
893-     let  our_activation_keys:  HashSet < _ >  = our_candidates
894-         . iter ( ) 
895-         . map ( |c| c. package_id ( ) . as_activations_key ( ) ) 
896-         . collect ( ) ; 
893+     let  our_activation_key = { 
894+         // TODO: no reason to allocate a `HashSet` we are just going to throw it out if len > 1 
895+         let  our_activation_keys:  HashSet < _ >  = our_candidates
896+             . iter ( ) 
897+             . map ( |c| c. package_id ( ) . as_activations_key ( ) ) 
898+             . collect ( ) ; 
897899
898-     // if our dep only matches one semver range then we can fast path any other dep 
899-     // that also targets that semver range and has no overlap 
900-     let  our_activation_key = if  our_activation_keys. len ( )  == 1  { 
901-         our_activation_keys. iter ( ) . next ( ) . cloned ( ) 
902-     }  else  { 
903-         None 
900+         // If our dep only matches one semver range then we can fast path any other dep 
901+         // that also targets that semver range and has no overlap. 
902+         if  our_activation_keys. len ( )  == 1  { 
903+             our_activation_keys. iter ( ) . next ( ) . cloned ( ) 
904+         }  else  { 
905+             None 
906+         } 
904907    } ; 
905908
906-     let  our_links:  Option < HashSet < _ > >  = our_candidates. iter ( ) . map ( |c| c. links ( ) ) . collect ( ) ; 
909+     let  our_link = { 
910+         // TODO: no reason to allocate a `HashSet` we are just going to throw it out if len > 1 
911+         let  our_links:  HashSet < Option < _ > >  = our_candidates. iter ( ) . map ( |c| c. links ( ) ) . collect ( ) ; 
907912
908-     // if our dep only matches things that have a links set then we can fast path any other dep 
909-     // that also all use that links and has no overlap 
910-     let  our_link = if  let  Some ( our_links)  = our_links { 
913+         // If our dep only matches things that have a links set then we can fast path any other dep 
914+         // that also all use that links and has no overlap. 
911915        if  our_links. len ( )  == 1  { 
912-             our_links. iter ( ) . next ( ) . cloned ( ) 
916+             // All of `our_candidates` use the same `links`. 
917+             // If they all use Some(value), then we can use the fast path. 
918+             // If they all use None, then we cant. 
919+             our_links. into_iter ( ) . next ( ) . unwrap ( ) 
913920        }  else  { 
921+             // Some of `our_candidates` use a different `links` so whatever `links` get used by 
922+             // the conflicting dep we can select the other. We cant use the fast path. 
914923            None 
915924        } 
916-     }  else  { 
917-         None 
918925    } ; 
919926
920927    let  our_candidates:  HashSet < PackageId >  =
@@ -942,11 +949,17 @@ fn generalize_conflicting(
942949                . rev ( ) 
943950            // the last one to be tried is the least likely to be in the cache, so start with that. 
944951            { 
945-                 if  ( our_activation_key
946-                     . map_or ( false ,  |our| other. package_id ( ) . as_activations_key ( )  == our) 
947-                     || our_link. map_or ( false ,  |_| other. links ( )  == our_link) ) 
948-                     && !our_candidates. contains ( & other. package_id ( ) ) 
952+                 if  ( 
953+                     our_activation_key. map_or ( false ,  |our| { 
954+                     other. package_id ( ) . as_activations_key ( )  == our
955+                 } ) 
956+                     // `other` is semver compatible with all of `our_candidates` 
957+                     || our_link. map_or ( false ,  |_| other. links ( )  == our_link) 
958+                     // or `other` have the same `links` as all of `our_candidates` 
959+                 )  && !our_candidates. contains ( & other. package_id ( ) ) 
960+                 // and is not one of `our_candidates`. 
949961                { 
962+                     // Thus `dep` can not be resolved when `critical_parents_dep` has bean resolved. 
950963                    continue ; 
951964                } 
952965
@@ -967,16 +980,7 @@ fn generalize_conflicting(
967980
968981                if  let  Some ( conflicting)  = past_conflicting_activations. find ( 
969982                    dep, 
970-                     & |id| { 
971-                         if  id == other. package_id ( )  { 
972-                             // we are imagining that we used other instead 
973-                             Some ( backtrack_critical_age) 
974-                         }  else  { 
975-                             cx. is_active ( id) . filter ( |& age|
976-                                         // we only care about things that are older then critical_age 
977-                                         age < backtrack_critical_age) 
978-                         } 
979-                     } , 
983+                     & |id| cx. is_older_active_or ( id,  backtrack_critical_age,  other. package_id ( ) ) , 
980984                    Some ( other. package_id ( ) ) , 
981985                )  { 
982986                    con. extend ( 
@@ -988,6 +992,9 @@ fn generalize_conflicting(
988992                    continue ; 
989993                } 
990994
995+                 // We don't have a reason why `other` cant work. 
996+                 // There for `critical_parents_dep` could have used it, and we can still be activated. 
997+                 // We can not generalize over `critical_parents_dep`, but maybe the next `critical_parents_dep` 
991998                continue  ' dep; 
992999            } 
9931000
@@ -1043,16 +1050,7 @@ fn generalize_children_conflicting(
10431050                . filter_map ( |( ref  new_dep,  _,  _) | { 
10441051                    past_conflicting_activations. find ( 
10451052                        new_dep, 
1046-                         & |id| { 
1047-                             if  id == candidate. package_id ( )  { 
1048-                                 // we are imagining that we used other instead 
1049-                                 Some ( critical_age) 
1050-                             }  else  { 
1051-                                 cx. is_active ( id) . filter ( |& age|
1052-                                         // we only care about things that are older then critical_age 
1053-                                         age < critical_age) 
1054-                             } 
1055-                         } , 
1053+                         & |id| cx. is_older_active_or ( id,  critical_age,  candidate. package_id ( ) ) , 
10561054                        None , 
10571055                    ) 
10581056                } ) 
0 commit comments