about summary refs log tree commit diff
path: root/src/librustc_data_structures
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2019-05-17 15:28:45 +0200
committerMichael Woerister <michaelwoerister@posteo>2019-05-20 10:36:31 +0200
commita79c06a9ce1986d3c4dbc27b5e51d60d77befafb (patch)
treef64898fade0fa091fcc8967c6a15ee60256b54f3 /src/librustc_data_structures
parenteed1e1ecd265071dc45abcd331272e6bb1b919d7 (diff)
downloadrust-a79c06a9ce1986d3c4dbc27b5e51d60d77befafb.tar.gz
rust-a79c06a9ce1986d3c4dbc27b5e51d60d77befafb.zip
Document requirements for HashStable implementations better.
Diffstat (limited to 'src/librustc_data_structures')
-rw-r--r--src/librustc_data_structures/stable_hasher.rs24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs
index 13e245d3c01..2b844aa24d4 100644
--- a/src/librustc_data_structures/stable_hasher.rs
+++ b/src/librustc_data_structures/stable_hasher.rs
@@ -140,6 +140,30 @@ impl<W> Hasher for StableHasher<W> {
 
 /// Something that implements `HashStable<CTX>` can be hashed in a way that is
 /// stable across multiple compilation sessions.
+///
+/// Note that `HashStable` imposes rather more strict requirements than usual
+/// hash functions:
+///
+/// - Stable hashes are sometimes used as identifiers. Therefore they must
+///   conform to the corresponding `PartialEq` implementations:
+///
+///     - `x == y` implies `hash_stable(x) == hash_stable(y)`, and
+///     - `x != y` implies `hash_stable(x) != hash_stable(y)`.
+///
+///   That second condition is usually not required for hash functions
+///   (e.g. `Hash`). In practice this means that `hash_stable` must feed any
+///   information into the hasher that a `PartialEq` comparision takes into
+///   account. See [#49300](https://github.com/rust-lang/rust/issues/49300)
+///   for an example where violating this invariant has caused trouble in the
+///   past.
+///
+/// - `hash_stable()` must be independent of the current
+///    compilation session. E.g. they must not hash memory addresses or other
+///    things that are "randomly" assigned per compilation session.
+///
+/// - `hash_stable()` must be independent of the host architecture. The
+///   `StableHasher` takes care of endianness and `isize`/`usize` platform
+///   differences.
 pub trait HashStable<CTX> {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut CTX,