@@ -15,7 +15,6 @@ use crate::bit_set;
1515/// extended to 64 bits if needed.
1616pub struct StableHasher < W > {
1717 state : SipHasher128 ,
18- bytes_hashed : u64 ,
1918 width : PhantomData < W > ,
2019}
2120
@@ -33,7 +32,6 @@ impl<W: StableHasherResult> StableHasher<W> {
3332 pub fn new ( ) -> Self {
3433 StableHasher {
3534 state : SipHasher128 :: new_with_keys ( 0 , 0 ) ,
36- bytes_hashed : 0 ,
3735 width : PhantomData ,
3836 }
3937 }
@@ -61,11 +59,6 @@ impl<W> StableHasher<W> {
6159 pub fn finalize ( self ) -> ( u64 , u64 ) {
6260 self . state . finish128 ( )
6361 }
64-
65- #[ inline]
66- pub fn bytes_hashed ( & self ) -> u64 {
67- self . bytes_hashed
68- }
6962}
7063
7164impl < W > Hasher for StableHasher < W > {
@@ -76,37 +69,31 @@ impl<W> Hasher for StableHasher<W> {
7669 #[ inline]
7770 fn write ( & mut self , bytes : & [ u8 ] ) {
7871 self . state . write ( bytes) ;
79- self . bytes_hashed += bytes. len ( ) as u64 ;
8072 }
8173
8274 #[ inline]
8375 fn write_u8 ( & mut self , i : u8 ) {
8476 self . state . write_u8 ( i) ;
85- self . bytes_hashed += 1 ;
8677 }
8778
8879 #[ inline]
8980 fn write_u16 ( & mut self , i : u16 ) {
9081 self . state . write_u16 ( i. to_le ( ) ) ;
91- self . bytes_hashed += 2 ;
9282 }
9383
9484 #[ inline]
9585 fn write_u32 ( & mut self , i : u32 ) {
9686 self . state . write_u32 ( i. to_le ( ) ) ;
97- self . bytes_hashed += 4 ;
9887 }
9988
10089 #[ inline]
10190 fn write_u64 ( & mut self , i : u64 ) {
10291 self . state . write_u64 ( i. to_le ( ) ) ;
103- self . bytes_hashed += 8 ;
10492 }
10593
10694 #[ inline]
10795 fn write_u128 ( & mut self , i : u128 ) {
10896 self . state . write_u128 ( i. to_le ( ) ) ;
109- self . bytes_hashed += 16 ;
11097 }
11198
11299 #[ inline]
@@ -115,37 +102,31 @@ impl<W> Hasher for StableHasher<W> {
115102 // platforms. This is important for symbol hashes when cross compiling,
116103 // for example.
117104 self . state . write_u64 ( ( i as u64 ) . to_le ( ) ) ;
118- self . bytes_hashed += 8 ;
119105 }
120106
121107 #[ inline]
122108 fn write_i8 ( & mut self , i : i8 ) {
123109 self . state . write_i8 ( i) ;
124- self . bytes_hashed += 1 ;
125110 }
126111
127112 #[ inline]
128113 fn write_i16 ( & mut self , i : i16 ) {
129114 self . state . write_i16 ( i. to_le ( ) ) ;
130- self . bytes_hashed += 2 ;
131115 }
132116
133117 #[ inline]
134118 fn write_i32 ( & mut self , i : i32 ) {
135119 self . state . write_i32 ( i. to_le ( ) ) ;
136- self . bytes_hashed += 4 ;
137120 }
138121
139122 #[ inline]
140123 fn write_i64 ( & mut self , i : i64 ) {
141124 self . state . write_i64 ( i. to_le ( ) ) ;
142- self . bytes_hashed += 8 ;
143125 }
144126
145127 #[ inline]
146128 fn write_i128 ( & mut self , i : i128 ) {
147129 self . state . write_i128 ( i. to_le ( ) ) ;
148- self . bytes_hashed += 16 ;
149130 }
150131
151132 #[ inline]
@@ -154,12 +135,35 @@ impl<W> Hasher for StableHasher<W> {
154135 // platforms. This is important for symbol hashes when cross compiling,
155136 // for example.
156137 self . state . write_i64 ( ( i as i64 ) . to_le ( ) ) ;
157- self . bytes_hashed += 8 ;
158138 }
159139}
160140
161141/// Something that implements `HashStable<CTX>` can be hashed in a way that is
162142/// stable across multiple compilation sessions.
143+ ///
144+ /// Note that `HashStable` imposes rather more strict requirements than usual
145+ /// hash functions:
146+ ///
147+ /// - Stable hashes are sometimes used as identifiers. Therefore they must
148+ /// conform to the corresponding `PartialEq` implementations:
149+ ///
150+ /// - `x == y` implies `hash_stable(x) == hash_stable(y)`, and
151+ /// - `x != y` implies `hash_stable(x) != hash_stable(y)`.
152+ ///
153+ /// That second condition is usually not required for hash functions
154+ /// (e.g. `Hash`). In practice this means that `hash_stable` must feed any
155+ /// information into the hasher that a `PartialEq` comparision takes into
156+ /// account. See [#49300](https://github.com/rust-lang/rust/issues/49300)
157+ /// for an example where violating this invariant has caused trouble in the
158+ /// past.
159+ ///
160+ /// - `hash_stable()` must be independent of the current
161+ /// compilation session. E.g. they must not hash memory addresses or other
162+ /// things that are "randomly" assigned per compilation session.
163+ ///
164+ /// - `hash_stable()` must be independent of the host architecture. The
165+ /// `StableHasher` takes care of endianness and `isize`/`usize` platform
166+ /// differences.
163167pub trait HashStable < CTX > {
164168 fn hash_stable < W : StableHasherResult > ( & self ,
165169 hcx : & mut CTX ,
0 commit comments