diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index b8ad66901c699..144eaed7e076e 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -42,6 +42,7 @@ impl StableHasher { } impl StableHasherResult for u128 { + #[inline] fn finish(hasher: StableHasher) -> Self { let (_0, _1) = hasher.finalize(); u128::from(_0) | (u128::from(_1) << 64) @@ -49,6 +50,7 @@ impl StableHasherResult for u128 { } impl StableHasherResult for u64 { + #[inline] fn finish(hasher: StableHasher) -> Self { hasher.finalize().0 } @@ -507,7 +509,11 @@ where { #[inline] fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { - hash_stable_hashmap(hcx, hasher, self, ToStableHashKey::to_stable_hash_key); + stable_hash_reduce(hcx, hasher, self.iter(), self.len(), |hasher, hcx, (key, value)| { + let key = key.to_stable_hash_key(hcx); + key.hash_stable(hcx, hasher); + value.hash_stable(hcx, hasher); + }); } } @@ -517,9 +523,10 @@ where R: BuildHasher, { fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { - let mut keys: Vec<_> = self.iter().map(|k| k.to_stable_hash_key(hcx)).collect(); - keys.sort_unstable(); - keys.hash_stable(hcx, hasher); + stable_hash_reduce(hcx, hasher, self.iter(), self.len(), |hasher, hcx, key| { + let key = key.to_stable_hash_key(hcx); + key.hash_stable(hcx, hasher); + }); } } @@ -529,10 +536,11 @@ where V: HashStable, { fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { - let mut entries: Vec<_> = - self.iter().map(|(k, v)| (k.to_stable_hash_key(hcx), v)).collect(); - entries.sort_unstable_by(|&(ref sk1, _), &(ref sk2, _)| sk1.cmp(sk2)); - entries.hash_stable(hcx, hasher); + stable_hash_reduce(hcx, hasher, self.iter(), self.len(), |hasher, hcx, (key, value)| { + let key = key.to_stable_hash_key(hcx); + key.hash_stable(hcx, hasher); + value.hash_stable(hcx, hasher); + }); } } @@ -541,26 +549,38 @@ where K: ToStableHashKey, { fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { - let mut keys: Vec<_> = self.iter().map(|k| k.to_stable_hash_key(hcx)).collect(); - keys.sort_unstable(); - keys.hash_stable(hcx, hasher); + stable_hash_reduce(hcx, hasher, self.iter(), self.len(), |hasher, hcx, key| { + let key = key.to_stable_hash_key(hcx); + key.hash_stable(hcx, hasher); + }); } } -pub fn hash_stable_hashmap( +fn stable_hash_reduce( hcx: &mut HCX, hasher: &mut StableHasher, - map: &::std::collections::HashMap, - to_stable_hash_key: F, + mut collection: C, + length: usize, + hash_function: F, ) where - K: Eq, - V: HashStable, - R: BuildHasher, - SK: HashStable + Ord, - F: Fn(&K, &HCX) -> SK, + C: Iterator, + F: Fn(&mut StableHasher, &mut HCX, I), { - let mut entries: SmallVec<[_; 3]> = - map.iter().map(|(k, v)| (to_stable_hash_key(k, hcx), v)).collect(); - entries.sort_unstable_by(|&(ref sk1, _), &(ref sk2, _)| sk1.cmp(sk2)); - entries.hash_stable(hcx, hasher); + length.hash_stable(hcx, hasher); + + match length { + 1 => { + hash_function(hasher, hcx, collection.next().unwrap()); + } + _ => { + let hash = collection + .map(|value| { + let mut hasher = StableHasher::new(); + hash_function(&mut hasher, hcx, value); + hasher.finish::() + }) + .reduce(|accum, value| accum.wrapping_add(value)); + hash.hash_stable(hcx, hasher); + } + } }