@@ -31,11 +31,22 @@ struct PackageIdInner {
31
31
source_id : SourceId ,
32
32
}
33
33
34
- // Custom equality that uses full equality of SourceId, rather than its custom equality.
34
+ // Custom equality that uses full equality of SourceId, rather than its custom equality,
35
+ // and Version, which usually ignores `build` metadata.
36
+ //
37
+ // The `build` part of the version is usually ignored (like a "comment").
38
+ // However, there are some cases where it is important. The download path from
39
+ // a registry includes the build metadata, and Cargo uses PackageIds for
40
+ // creating download paths. Including it here prevents the PackageId interner
41
+ // from getting poisoned with PackageIds where that build metadata is missing.
35
42
impl PartialEq for PackageIdInner {
36
43
fn eq ( & self , other : & Self ) -> bool {
37
44
self . name == other. name
38
- && self . version == other. version
45
+ && self . version . major == other. version . major
46
+ && self . version . minor == other. version . minor
47
+ && self . version . patch == other. version . patch
48
+ && self . version . pre == other. version . pre
49
+ && self . version . build == other. version . build
39
50
&& self . source_id . full_eq ( other. source_id )
40
51
}
41
52
}
@@ -44,7 +55,11 @@ impl PartialEq for PackageIdInner {
44
55
impl Hash for PackageIdInner {
45
56
fn hash < S : hash:: Hasher > ( & self , into : & mut S ) {
46
57
self . name . hash ( into) ;
47
- self . version . hash ( into) ;
58
+ self . version . major . hash ( into) ;
59
+ self . version . minor . hash ( into) ;
60
+ self . version . patch . hash ( into) ;
61
+ self . version . pre . hash ( into) ;
62
+ self . version . build . hash ( into) ;
48
63
self . source_id . full_hash ( into) ;
49
64
}
50
65
}
@@ -97,6 +112,8 @@ impl PartialEq for PackageId {
97
112
if ptr:: eq ( self . inner , other. inner ) {
98
113
return true ;
99
114
}
115
+ // This is here so that PackageId uses SourceId's and Version's idea
116
+ // of equality. PackageIdInner uses a more exact notion of equality.
100
117
self . inner . name == other. inner . name
101
118
&& self . inner . version == other. inner . version
102
119
&& self . inner . source_id == other. inner . source_id
@@ -105,6 +122,9 @@ impl PartialEq for PackageId {
105
122
106
123
impl Hash for PackageId {
107
124
fn hash < S : hash:: Hasher > ( & self , state : & mut S ) {
125
+ // This is here (instead of derived) so that PackageId uses SourceId's
126
+ // and Version's idea of equality. PackageIdInner uses a more exact
127
+ // notion of hashing.
108
128
self . inner . name . hash ( state) ;
109
129
self . inner . version . hash ( state) ;
110
130
self . inner . source_id . hash ( state) ;
@@ -166,6 +186,12 @@ impl PackageId {
166
186
}
167
187
}
168
188
189
+ /// Returns a value that implements a "stable" hashable value.
190
+ ///
191
+ /// Stable hashing removes the path prefix of the workspace from path
192
+ /// packages. This helps with reproducible builds, since this hash is part
193
+ /// of the symbol metadata, and we don't want the absolute path where the
194
+ /// build is performed to affect the binary output.
169
195
pub fn stable_hash ( self , workspace : & Path ) -> PackageIdStableHash < ' _ > {
170
196
PackageIdStableHash ( self , workspace)
171
197
}
0 commit comments