diff options
Diffstat (limited to 'compiler/rustc_data_structures/src')
| -rw-r--r-- | compiler/rustc_data_structures/src/fingerprint.rs | 30 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/lib.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/unhash.rs | 29 |
3 files changed, 59 insertions, 1 deletions
diff --git a/compiler/rustc_data_structures/src/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs index f8d631ce01e..aba0bbbac80 100644 --- a/compiler/rustc_data_structures/src/fingerprint.rs +++ b/compiler/rustc_data_structures/src/fingerprint.rs @@ -3,9 +3,10 @@ use rustc_serialize::{ opaque::{self, EncodeResult}, Decodable, Encodable, }; +use std::hash::{Hash, Hasher}; use std::mem; -#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)] +#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy)] pub struct Fingerprint(u64, u64); impl Fingerprint { @@ -76,6 +77,33 @@ impl ::std::fmt::Display for Fingerprint { } } +impl Hash for Fingerprint { + #[inline] + fn hash<H: Hasher>(&self, state: &mut H) { + state.write_fingerprint(self); + } +} + +trait FingerprintHasher { + fn write_fingerprint(&mut self, fingerprint: &Fingerprint); +} + +impl<H: Hasher> FingerprintHasher for H { + #[inline] + default fn write_fingerprint(&mut self, fingerprint: &Fingerprint) { + self.write_u64(fingerprint.0); + self.write_u64(fingerprint.1); + } +} + +impl FingerprintHasher for crate::unhash::Unhasher { + #[inline] + fn write_fingerprint(&mut self, fingerprint: &Fingerprint) { + // `Unhasher` only wants a single `u64` + self.write_u64(fingerprint.0); + } +} + impl stable_hasher::StableHasherResult for Fingerprint { #[inline] fn finish(hasher: stable_hasher::StableHasher) -> Self { diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 78b7e08ceed..de4e7a13424 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -103,6 +103,7 @@ pub use atomic_ref::AtomicRef; pub mod frozen; pub mod tagged_ptr; pub mod temp_dir; +pub mod unhash; pub struct OnDrop<F: Fn()>(pub F); diff --git a/compiler/rustc_data_structures/src/unhash.rs b/compiler/rustc_data_structures/src/unhash.rs new file mode 100644 index 00000000000..48e21a9dab1 --- /dev/null +++ b/compiler/rustc_data_structures/src/unhash.rs @@ -0,0 +1,29 @@ +use std::collections::{HashMap, HashSet}; +use std::hash::{BuildHasherDefault, Hasher}; + +pub type UnhashMap<K, V> = HashMap<K, V, BuildHasherDefault<Unhasher>>; +pub type UnhashSet<V> = HashSet<V, BuildHasherDefault<Unhasher>>; + +/// This no-op hasher expects only a single `write_u64` call. It's intended for +/// map keys that already have hash-like quality, like `Fingerprint`. +#[derive(Default)] +pub struct Unhasher { + value: u64, +} + +impl Hasher for Unhasher { + #[inline] + fn finish(&self) -> u64 { + self.value + } + + fn write(&mut self, _bytes: &[u8]) { + unimplemented!("use write_u64"); + } + + #[inline] + fn write_u64(&mut self, value: u64) { + debug_assert_eq!(0, self.value, "Unhasher doesn't mix values!"); + self.value = value; + } +} |
