pub trait StableHash {
// Required method
fn stable_hash<Hcx: StableHashCtxt>(
&self,
hcx: &mut Hcx,
hasher: &mut StableHasher,
);
}Expand description
Something that implements StableHash can be hashed in a way that is
stable across multiple compilation sessions.
Note that StableHash imposes rather more strict requirements than usual
hash functions:
-
Stable hashes are sometimes used as identifiers. Therefore they must conform to the corresponding
PartialEqimplementations:x == yimpliesstable_hash(x) == stable_hash(y), andx != yimpliesstable_hash(x) != stable_hash(y).
That second condition is usually not required for hash functions (e.g.
Hash). In practice this means thatstable_hashmust feed any information into the hasher that aPartialEqcomparison takes into account. See #49300 for an example where violating this invariant has caused trouble in the past. -
stable_hash()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. -
stable_hash()must be independent of the host architecture. TheStableHashertakes care of endianness andisize/usizeplatform differences.
§Consistency across compiler stages
Because the stage1 compiler is built against the bootstrap stdlib, but the stage2
compiler uses in-tree stdlib, implementations of StableHash must not rely on Hash
impls that were provided or derived by the standard library. Doing so leads to weird
bugs and CI failures that can block changes to those stdlib hash impls.
(Unfortunately, as of late 2026 we have many stable-hash impls that do leak details of stdlib hash impls.)
See https://github.com/rust-lang/rust/pull/164458 for more context.
Required Methods§
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".
Implementations on Foreign Types§
Source§impl StableHash for !
impl StableHash for !
fn stable_hash<Hcx>(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher)
Source§impl StableHash for ()
impl StableHash for ()
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for Hash64
impl StableHash for Hash64
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for Hash128
impl StableHash for Hash128
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for Ordering
impl StableHash for Ordering
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl StableHash for OsStr
impl StableHash for OsStr
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for Path
impl StableHash for Path
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl StableHash for PathBuf
impl StableHash for PathBuf
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl StableHash for String
impl StableHash for String
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl StableHash for [u8]
impl StableHash for [u8]
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl StableHash for bool
impl StableHash for bool
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl StableHash for char
impl StableHash for char
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for f32
impl StableHash for f32
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl StableHash for f64
impl StableHash for f64
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl StableHash for i8
impl StableHash for i8
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for i16
impl StableHash for i16
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for i32
impl StableHash for i32
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for i64
impl StableHash for i64
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for i128
impl StableHash for i128
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for isize
impl StableHash for isize
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for str
impl StableHash for str
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl StableHash for u8
impl StableHash for u8
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for u16
impl StableHash for u16
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for u32
impl StableHash for u32
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for u64
impl StableHash for u64
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for u128
impl StableHash for u128
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl StableHash for usize
impl StableHash for usize
fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher)
Source§impl<'a, T> StableHash for &'a Twhere
T: StableHash + ?Sized,
impl<'a, T> StableHash for &'a Twhere
T: StableHash + ?Sized,
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<A, const N: usize> StableHash for SmallVec<[A; N]>where
A: StableHash,
impl<A, const N: usize> StableHash for SmallVec<[A; N]>where
A: StableHash,
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<I: Idx, T> StableHash for IndexSlice<I, T>where
T: StableHash,
impl<I: Idx, T> StableHash for IndexSlice<I, T>where
T: StableHash,
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<I: Idx, T> StableHash for IndexVec<I, T>where
T: StableHash,
impl<I: Idx, T> StableHash for IndexVec<I, T>where
T: StableHash,
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<I: Idx> StableHash for DenseBitSet<I>
impl<I: Idx> StableHash for DenseBitSet<I>
fn stable_hash<Hcx: StableHashCtxt>( &self, _hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<K, R> StableHash for IndexSet<K, R>
impl<K, R> StableHash for IndexSet<K, R>
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<K, V, R> StableHash for IndexMap<K, V, R>
impl<K, V, R> StableHash for IndexMap<K, V, R>
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
impl<K, V> !StableHash for HashMap<K, V>
Source§impl<K, V> StableHash for BTreeMap<K, V>
impl<K, V> StableHash for BTreeMap<K, V>
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<K> StableHash for BTreeSet<K>where
K: StableHash + StableOrd,
impl<K> StableHash for BTreeSet<K>where
K: StableHash + StableOrd,
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<R: Idx, C: Idx> StableHash for BitMatrix<R, C>
impl<R: Idx, C: Idx> StableHash for BitMatrix<R, C>
fn stable_hash<Hcx: StableHashCtxt>( &self, _hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<T1, T2, T3, T4> StableHash for (T1, T2, T3, T4)
impl<T1, T2, T3, T4> StableHash for (T1, T2, T3, T4)
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<T1, T2, T3> StableHash for (T1, T2, T3)
impl<T1, T2, T3> StableHash for (T1, T2, T3)
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<T1, T2> StableHash for Result<T1, T2>where
T1: StableHash,
T2: StableHash,
impl<T1, T2> StableHash for Result<T1, T2>where
T1: StableHash,
T2: StableHash,
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<T1: StableHash, T2: StableHash> StableHash for (T1, T2)
impl<T1: StableHash, T2: StableHash> StableHash for (T1, T2)
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<T1: StableHash> StableHash for (T1,)
impl<T1: StableHash> StableHash for (T1,)
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<T: ?Sized + StableHash> StableHash for Arc<T>
impl<T: ?Sized + StableHash> StableHash for Arc<T>
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<T: ?Sized + StableHash> StableHash for Box<T>
impl<T: ?Sized + StableHash> StableHash for Box<T>
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<T: ?Sized + StableHash> StableHash for Rc<T>
impl<T: ?Sized + StableHash> StableHash for Rc<T>
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<T: StableHash + ZeroablePrimitive> StableHash for NonZero<T>
impl<T: StableHash + ZeroablePrimitive> StableHash for NonZero<T>
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<T: StableHash> StableHash for ThinVec<T>
impl<T: StableHash> StableHash for ThinVec<T>
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<T: StableHash> StableHash for Vec<T>
impl<T: StableHash> StableHash for Vec<T>
fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<T: StableHash> StableHash for [T]
impl<T: StableHash> StableHash for [T]
default fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )
Source§impl<T> !StableHash for Discriminant<T>
There is no way to stable-hash a Discriminant without leaking unstable
details of how the host compiler chooses and hashes discriminants.
impl<T> !StableHash for Discriminant<T>
There is no way to stable-hash a Discriminant without leaking unstable
details of how the host compiler chooses and hashes discriminants.
That would be bad, because stable hashes must be consistent between the stage1 compiler (built with the bootstrap compiler/stdlib) and the stage2 compiler (built with the in-tree compiler/stdlib).
See https://github.com/rust-lang/rust/issues/164734 for more context.
If you need to manually stable-hash a discriminant, instead derive StableHash
on a dedicated “tag” enum, and then hash the appropriate tag for each variant.
For an example, see the impl of StableHash for Result.