From d496cca3b161d9f6a3f9202f97e45382281ba749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 14 Dec 2021 00:00:00 +0000 Subject: [PATCH 1/2] Derive hash for BitSet and BitMatrix --- compiler/rustc_index/src/bit_set.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 08f13d46ee1..241cbe23487 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -87,7 +87,7 @@ macro_rules! bit_relations_inherent_impls { /// to or greater than the domain size. All operations that involve two bitsets /// will panic if the bitsets have differing domain sizes. /// -#[derive(Eq, PartialEq, Decodable, Encodable)] +#[derive(Eq, PartialEq, Hash, Decodable, Encodable)] pub struct BitSet { domain_size: usize, words: Vec, @@ -987,7 +987,7 @@ impl GrowableBitSet { /// /// All operations that involve a row and/or column index will panic if the /// index exceeds the relevant bound. -#[derive(Clone, Eq, PartialEq, Decodable, Encodable)] +#[derive(Clone, Eq, PartialEq, Hash, Decodable, Encodable)] pub struct BitMatrix { num_rows: usize, num_columns: usize, From d0281bcb25d779a7b27cd8d5de394f2c9f72f33c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 18 Dec 2021 00:00:00 +0000 Subject: [PATCH 2/2] 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. --- .../src/stable_hasher.rs | 8 +++--- .../src/stable_hasher/tests.rs | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index b8ad66901c6..b8e6497d573 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -476,14 +476,14 @@ where } impl HashStable for bit_set::BitSet { - 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 HashStable for bit_set::BitMatrix { - 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); } } diff --git a/compiler/rustc_data_structures/src/stable_hasher/tests.rs b/compiler/rustc_data_structures/src/stable_hasher/tests.rs index cd6ff96a555..391db67d29d 100644 --- a/compiler/rustc_data_structures/src/stable_hasher/tests.rs +++ b/compiler/rustc_data_structures/src/stable_hasher/tests.rs @@ -71,3 +71,30 @@ fn test_hash_isize() { assert_eq!(h.finalize(), expected); } + +fn hash>(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 = BitSet::new_empty(1); + let b: BitSet = 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 = BitMatrix::new(1, 1); + let b: BitMatrix = BitMatrix::new(1, 2); + assert_ne!(a, b); + assert_ne!(hash(&a), hash(&b)); +}