@@ -2,7 +2,7 @@ use super::dep_cache::RegistryQueryer;
22use super :: errors:: ActivateResult ;
33use super :: types:: { ConflictMap , ConflictReason , FeaturesSet , ResolveOpts } ;
44use super :: RequestedFeatures ;
5- use crate :: core:: { ActivationsKey , Dependency , PackageId , Summary } ;
5+ use crate :: core:: { ActivationKey , Dependency , PackageId , Summary } ;
66use crate :: util:: interning:: InternedString ;
77use crate :: util:: Graph ;
88use anyhow:: format_err;
@@ -26,8 +26,13 @@ pub struct ResolverContext {
2626 pub parents : Graph < PackageId , im_rc:: HashSet < Dependency , rustc_hash:: FxBuildHasher > > ,
2727}
2828
29- pub type Activations =
30- im_rc:: HashMap < ActivationsKey , ( Summary , ContextAge ) , rustc_hash:: FxBuildHasher > ;
29+ /// By storing activation keys in a `HashMap` we ensure that there is only one
30+ /// semver compatible version of each crate.
31+ type Activations = im_rc:: HashMap <
32+ ActivationKey ,
33+ ( Summary , ContextAge ) ,
34+ nohash_hasher:: BuildNoHashHasher < ActivationKey > ,
35+ > ;
3136
3237/// When backtracking it can be useful to know how far back to go.
3338/// The `ContextAge` of a `Context` is a monotonically increasing counter of the number
@@ -62,7 +67,7 @@ impl ResolverContext {
6267 ) -> ActivateResult < bool > {
6368 let id = summary. package_id ( ) ;
6469 let age: ContextAge = self . age ;
65- match self . activations . entry ( id. as_activations_key ( ) ) {
70+ match self . activations . entry ( id. activation_key ( ) ) {
6671 im_rc:: hashmap:: Entry :: Occupied ( o) => {
6772 debug_assert_eq ! (
6873 & o. get( ) . 0 ,
@@ -101,8 +106,13 @@ impl ResolverContext {
101106 // versions came from a `[patch]` source.
102107 if let Some ( ( _, dep) ) = parent {
103108 if dep. source_id ( ) != id. source_id ( ) {
104- let key = ( id. name ( ) , dep. source_id ( ) , id. version ( ) . into ( ) ) ;
105- let prev = self . activations . insert ( key, ( summary. clone ( ) , age) ) ;
109+ let new_id =
110+ PackageId :: new ( id. name ( ) , id. version ( ) . clone ( ) , dep. source_id ( ) ) ;
111+
112+ let prev = self
113+ . activations
114+ . insert ( new_id. activation_key ( ) , ( summary. clone ( ) , age) ) ;
115+
106116 if let Some ( ( previous_summary, _) ) = prev {
107117 return Err (
108118 ( previous_summary. package_id ( ) , ConflictReason :: Semver ) . into ( )
@@ -145,9 +155,13 @@ impl ResolverContext {
145155
146156 /// If the package is active returns the `ContextAge` when it was added
147157 pub fn is_active ( & self , id : PackageId ) -> Option < ContextAge > {
148- self . activations
149- . get ( & id. as_activations_key ( ) )
150- . and_then ( |( s, l) | if s. package_id ( ) == id { Some ( * l) } else { None } )
158+ let ( summary, age) = self . activations . get ( & id. activation_key ( ) ) ?;
159+
160+ if summary. package_id ( ) == id {
161+ Some ( * age)
162+ } else {
163+ None
164+ }
151165 }
152166
153167 /// Checks whether all of `parent` and the keys of `conflicting activations`
@@ -163,8 +177,8 @@ impl ResolverContext {
163177 max = std:: cmp:: max ( max, self . is_active ( parent) ?) ;
164178 }
165179
166- for id in conflicting_activations. keys ( ) {
167- max = std:: cmp:: max ( max, self . is_active ( * id) ?) ;
180+ for & id in conflicting_activations. keys ( ) {
181+ max = std:: cmp:: max ( max, self . is_active ( id) ?) ;
168182 }
169183 Some ( max)
170184 }
0 commit comments