@@ -60,8 +60,21 @@ impl FromStableHash for Hash64 {
6060 type Hash = StableHasherHash ;
6161
6262 #[ inline]
63- fn from ( StableHasherHash ( [ _0, __1] ) : Self :: Hash ) -> Self {
64- Self { inner : _0 }
63+ fn from ( hash : Self :: Hash ) -> Self {
64+ let bytes = hash. as_bytes ( ) ;
65+
66+ let p0 = u64:: from_le_bytes ( bytes[ 0 ..8 ] . try_into ( ) . unwrap ( ) ) ;
67+ let p1 = u64:: from_le_bytes ( bytes[ 8 ..16 ] . try_into ( ) . unwrap ( ) ) ;
68+ let p2 = u64:: from_le_bytes ( bytes[ 16 ..24 ] . try_into ( ) . unwrap ( ) ) ;
69+ let p3 = u64:: from_le_bytes ( bytes[ 24 ..32 ] . try_into ( ) . unwrap ( ) ) ;
70+
71+ // See https://stackoverflow.com/a/27952689 on why this function is
72+ // implemented this way.
73+ let m0 = p0. wrapping_mul ( 3 ) . wrapping_add ( p1) ;
74+ let m1 = p2. wrapping_mul ( 3 ) . wrapping_add ( p3) ;
75+ let h = m0. wrapping_mul ( 3 ) . wrapping_add ( m1) ;
76+
77+ Self { inner : h }
6578 }
6679}
6780
@@ -127,8 +140,20 @@ impl FromStableHash for Hash128 {
127140 type Hash = StableHasherHash ;
128141
129142 #[ inline]
130- fn from ( StableHasherHash ( [ _0, _1] ) : Self :: Hash ) -> Self {
131- Self { inner : u128:: from ( _0) | ( u128:: from ( _1) << 64 ) }
143+ fn from ( hash : Self :: Hash ) -> Self {
144+ let bytes = hash. as_bytes ( ) ;
145+
146+ let p0 = u64:: from_le_bytes ( bytes[ 0 ..8 ] . try_into ( ) . unwrap ( ) ) ;
147+ let p1 = u64:: from_le_bytes ( bytes[ 8 ..16 ] . try_into ( ) . unwrap ( ) ) ;
148+ let p2 = u64:: from_le_bytes ( bytes[ 16 ..24 ] . try_into ( ) . unwrap ( ) ) ;
149+ let p3 = u64:: from_le_bytes ( bytes[ 24 ..32 ] . try_into ( ) . unwrap ( ) ) ;
150+
151+ // See https://stackoverflow.com/a/27952689 on why this function is
152+ // implemented this way.
153+ let upper = p0. wrapping_mul ( 3 ) . wrapping_add ( p1) ;
154+ let lower = p2. wrapping_mul ( 3 ) . wrapping_add ( p3) ;
155+
156+ Self { inner : u128:: from ( lower) | ( u128:: from ( upper) << 64 ) }
132157 }
133158}
134159
0 commit comments