Implement StableHash for BitSet and BitMatrix via Hash

This fixes an issue where bit sets / bit matrices the same word
content but a different domain size would receive the same hash.
This commit is contained in:
Tomasz Miąsko 2021-12-18 00:00:00 +00:00
parent d496cca3b1
commit d0281bcb25
2 changed files with 31 additions and 4 deletions

View file

@ -476,14 +476,14 @@ where
}
impl<I: vec::Idx, CTX> HashStable<CTX> for bit_set::BitSet<I> {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.words().hash_stable(ctx, hasher);
fn hash_stable(&self, _ctx: &mut CTX, hasher: &mut StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl<R: vec::Idx, C: vec::Idx, CTX> HashStable<CTX> for bit_set::BitMatrix<R, C> {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.words().hash_stable(ctx, hasher);
fn hash_stable(&self, _ctx: &mut CTX, hasher: &mut StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}

View file

@ -71,3 +71,30 @@ fn test_hash_isize() {
assert_eq!(h.finalize(), expected);
}
fn hash<T: HashStable<()>>(t: &T) -> u128 {
let mut h = StableHasher::new();
let ctx = &mut ();
t.hash_stable(ctx, &mut h);
h.finish()
}
// Check that bit set hash includes the domain size.
#[test]
fn test_hash_bit_set() {
use rustc_index::bit_set::BitSet;
let a: BitSet<usize> = BitSet::new_empty(1);
let b: BitSet<usize> = BitSet::new_empty(2);
assert_ne!(a, b);
assert_ne!(hash(&a), hash(&b));
}
// Check that bit matrix hash includes the matrix dimensions.
#[test]
fn test_hash_bit_matrix() {
use rustc_index::bit_set::BitMatrix;
let a: BitMatrix<usize, usize> = BitMatrix::new(1, 1);
let b: BitMatrix<usize, usize> = BitMatrix::new(1, 2);
assert_ne!(a, b);
assert_ne!(hash(&a), hash(&b));
}