1use std::hash::{BuildHasher, Hash, Hasher};
2use std::marker::PhantomData;
3use std::mem;
4use std::num::NonZero;
5
6use rustc_index::bit_set::{self, DenseBitSet};
7use rustc_index::{Idx, IndexSlice, IndexVec};
8use smallvec::SmallVec;
9use thin_vec::ThinVec;
10
11#[cfg(test)]
12mod tests;
13
14use rustc_hashes::{Hash64, Hash128};
15pub use rustc_stable_hash::{
16 FromStableHash, SipHasher128Hash as StableHasherHash, StableSipHasher128 as StableHasher,
17};
18
19pub trait StableHashCtxt {
24 fn stable_hash_span(&mut self, span: RawSpan, hasher: &mut StableHasher);
26
27 fn def_path_hash(&self, def_id: RawDefId) -> RawDefPathHash;
29
30 fn stable_hash_controls(&self) -> StableHashControls;
32
33 fn assert_default_stable_hash_controls(&self, msg: &str);
36}
37
38pub struct RawSpan(pub u32, pub u16, pub u16);
41
42pub struct RawDefId(pub u32, pub u32);
45
46pub struct RawDefPathHash(pub [u8; 16]);
49
50pub trait StableHash {
77 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher);
78}
79
80pub trait ToStableHashKey {
84 type KeyType: Ord + Sized + StableHash;
85 fn to_stable_hash_key<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx) -> Self::KeyType;
86}
87
88pub trait StableOrd: Ord {
118 const CAN_USE_UNSTABLE_SORT: bool;
119
120 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: ();
123}
124
125impl<T: StableOrd> StableOrd for &T {
126 const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT;
127
128 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
132}
133
134pub trait StableCompare {
145 const CAN_USE_UNSTABLE_SORT: bool;
146
147 fn stable_cmp(&self, other: &Self) -> std::cmp::Ordering;
148}
149
150impl<T: StableOrd> StableCompare for T {
153 const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT;
154
155 fn stable_cmp(&self, other: &Self) -> std::cmp::Ordering {
156 self.cmp(other)
157 }
158}
159
160macro_rules! impl_stable_traits_for_trivial_type {
170 ($t:ty) => {
171 impl $crate::stable_hash::StableHash for $t {
172 #[inline]
173 fn stable_hash<Hcx>(
174 &self,
175 _: &mut Hcx,
176 hasher: &mut $crate::stable_hash::StableHasher,
177 ) {
178 ::std::hash::Hash::hash(self, hasher);
179 }
180 }
181
182 impl $crate::stable_hash::StableOrd for $t {
183 const CAN_USE_UNSTABLE_SORT: bool = true;
184
185 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
188 }
189 };
190}
191
192pub(crate) use impl_stable_traits_for_trivial_type;
193
194impl crate::stable_hash::StableHash for i8 {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for i8 {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(i8);
195impl crate::stable_hash::StableHash for i16 {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for i16 {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(i16);
196impl crate::stable_hash::StableHash for i32 {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for i32 {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(i32);
197impl crate::stable_hash::StableHash for i64 {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for i64 {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(i64);
198impl crate::stable_hash::StableHash for isize {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for isize {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(isize);
199
200impl crate::stable_hash::StableHash for u8 {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for u8 {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(u8);
201impl crate::stable_hash::StableHash for u16 {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for u16 {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(u16);
202impl crate::stable_hash::StableHash for u32 {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for u32 {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(u32);
203impl crate::stable_hash::StableHash for u64 {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for u64 {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(u64);
204impl crate::stable_hash::StableHash for usize {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for usize {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(usize);
205
206impl crate::stable_hash::StableHash for u128 {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for u128 {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(u128);
207impl crate::stable_hash::StableHash for i128 {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for i128 {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(i128);
208
209impl crate::stable_hash::StableHash for char {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for char {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(char);
210impl crate::stable_hash::StableHash for () {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for () {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(());
211
212impl crate::stable_hash::StableHash for Hash64 {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for Hash64 {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(Hash64);
213
214impl StableHash for Hash128 {
217 #[inline]
218 fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher) {
219 self.as_u128().hash(hasher);
220 }
221}
222
223impl StableOrd for Hash128 {
224 const CAN_USE_UNSTABLE_SORT: bool = true;
225
226 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
229}
230
231impl StableHash for ! {
232 fn stable_hash<Hcx>(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) {
233 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
234 }
235}
236
237impl<T> StableHash for PhantomData<T> {
238 fn stable_hash<Hcx>(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) {}
239}
240
241impl<T: StableHash + std::num::ZeroablePrimitive> StableHash for NonZero<T> {
242 #[inline]
243 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
244 self.get().stable_hash(hcx, hasher)
245 }
246}
247
248impl StableHash for f32 {
249 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
250 let val: u32 = self.to_bits();
251 val.stable_hash(hcx, hasher);
252 }
253}
254
255impl StableHash for f64 {
256 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
257 let val: u64 = self.to_bits();
258 val.stable_hash(hcx, hasher);
259 }
260}
261
262impl StableHash for ::std::cmp::Ordering {
263 #[inline]
264 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
265 (*self as i8).stable_hash(hcx, hasher);
266 }
267}
268
269impl<T1: StableHash> StableHash for (T1,) {
270 #[inline]
271 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
272 let (ref _0,) = *self;
273 _0.stable_hash(hcx, hasher);
274 }
275}
276
277impl<T1: StableHash, T2: StableHash> StableHash for (T1, T2) {
278 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
279 let (ref _0, ref _1) = *self;
280 _0.stable_hash(hcx, hasher);
281 _1.stable_hash(hcx, hasher);
282 }
283}
284
285impl<T1: StableOrd, T2: StableOrd> StableOrd for (T1, T2) {
286 const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT && T2::CAN_USE_UNSTABLE_SORT;
287
288 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
291}
292
293impl<T1, T2, T3> StableHash for (T1, T2, T3)
294where
295 T1: StableHash,
296 T2: StableHash,
297 T3: StableHash,
298{
299 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
300 let (ref _0, ref _1, ref _2) = *self;
301 _0.stable_hash(hcx, hasher);
302 _1.stable_hash(hcx, hasher);
303 _2.stable_hash(hcx, hasher);
304 }
305}
306
307impl<T1: StableOrd, T2: StableOrd, T3: StableOrd> StableOrd for (T1, T2, T3) {
308 const CAN_USE_UNSTABLE_SORT: bool =
309 T1::CAN_USE_UNSTABLE_SORT && T2::CAN_USE_UNSTABLE_SORT && T3::CAN_USE_UNSTABLE_SORT;
310
311 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
314}
315
316impl<T1, T2, T3, T4> StableHash for (T1, T2, T3, T4)
317where
318 T1: StableHash,
319 T2: StableHash,
320 T3: StableHash,
321 T4: StableHash,
322{
323 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
324 let (ref _0, ref _1, ref _2, ref _3) = *self;
325 _0.stable_hash(hcx, hasher);
326 _1.stable_hash(hcx, hasher);
327 _2.stable_hash(hcx, hasher);
328 _3.stable_hash(hcx, hasher);
329 }
330}
331
332impl<T1: StableOrd, T2: StableOrd, T3: StableOrd, T4: StableOrd> StableOrd for (T1, T2, T3, T4) {
333 const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT
334 && T2::CAN_USE_UNSTABLE_SORT
335 && T3::CAN_USE_UNSTABLE_SORT
336 && T4::CAN_USE_UNSTABLE_SORT;
337
338 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
341}
342
343impl<T: StableHash> StableHash for [T] {
344 default fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
345 self.len().stable_hash(hcx, hasher);
346 for item in self {
347 item.stable_hash(hcx, hasher);
348 }
349 }
350}
351
352impl StableHash for [u8] {
353 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
354 self.len().stable_hash(hcx, hasher);
355 hasher.write(self);
356 }
357}
358
359impl<T: StableHash> StableHash for Vec<T> {
360 #[inline]
361 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
362 self[..].stable_hash(hcx, hasher);
363 }
364}
365
366impl<K, V, R> StableHash for indexmap::IndexMap<K, V, R>
367where
368 K: StableHash + Eq + Hash,
369 V: StableHash,
370 R: BuildHasher,
371{
372 #[inline]
373 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
374 self.len().stable_hash(hcx, hasher);
375 for kv in self {
376 kv.stable_hash(hcx, hasher);
377 }
378 }
379}
380
381impl<K, R> StableHash for indexmap::IndexSet<K, R>
382where
383 K: StableHash + Eq + Hash,
384 R: BuildHasher,
385{
386 #[inline]
387 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
388 self.len().stable_hash(hcx, hasher);
389 for key in self {
390 key.stable_hash(hcx, hasher);
391 }
392 }
393}
394
395impl<A, const N: usize> StableHash for SmallVec<[A; N]>
396where
397 A: StableHash,
398{
399 #[inline]
400 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
401 self[..].stable_hash(hcx, hasher);
402 }
403}
404
405impl<T: StableHash> StableHash for ThinVec<T> {
406 #[inline]
407 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
408 self[..].stable_hash(hcx, hasher);
409 }
410}
411
412impl<T: ?Sized + StableHash> StableHash for Box<T> {
413 #[inline]
414 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
415 (**self).stable_hash(hcx, hasher);
416 }
417}
418
419impl<T: ?Sized + StableHash> StableHash for ::std::rc::Rc<T> {
420 #[inline]
421 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
422 (**self).stable_hash(hcx, hasher);
423 }
424}
425
426impl<T: ?Sized + StableHash> StableHash for ::std::sync::Arc<T> {
427 #[inline]
428 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
429 (**self).stable_hash(hcx, hasher);
430 }
431}
432
433impl StableHash for str {
434 #[inline]
435 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
436 self.as_bytes().stable_hash(hcx, hasher);
437 }
438}
439
440impl StableOrd for &str {
441 const CAN_USE_UNSTABLE_SORT: bool = true;
442
443 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
446}
447
448impl StableHash for String {
449 #[inline]
450 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
451 self[..].stable_hash(hcx, hasher);
452 }
453}
454
455impl StableOrd for String {
456 const CAN_USE_UNSTABLE_SORT: bool = true;
457
458 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
461}
462
463impl StableHash for bool {
464 #[inline]
465 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
466 (if *self { 1u8 } else { 0u8 }).stable_hash(hcx, hasher);
467 }
468}
469
470impl StableOrd for bool {
471 const CAN_USE_UNSTABLE_SORT: bool = true;
472
473 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
475}
476
477impl<T> StableHash for Option<T>
478where
479 T: StableHash,
480{
481 #[inline]
482 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
483 if let Some(ref value) = *self {
484 1u8.stable_hash(hcx, hasher);
485 value.stable_hash(hcx, hasher);
486 } else {
487 0u8.stable_hash(hcx, hasher);
488 }
489 }
490}
491
492impl<T: StableOrd> StableOrd for Option<T> {
493 const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT;
494
495 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
497}
498
499impl<T1, T2> StableHash for Result<T1, T2>
500where
501 T1: StableHash,
502 T2: StableHash,
503{
504 #[inline]
505 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
506 mem::discriminant(self).stable_hash(hcx, hasher);
507 match *self {
508 Ok(ref x) => x.stable_hash(hcx, hasher),
509 Err(ref x) => x.stable_hash(hcx, hasher),
510 }
511 }
512}
513
514impl<'a, T> StableHash for &'a T
515where
516 T: StableHash + ?Sized,
517{
518 #[inline]
519 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
520 (**self).stable_hash(hcx, hasher);
521 }
522}
523
524impl<T> StableHash for ::std::mem::Discriminant<T> {
525 #[inline]
526 fn stable_hash<Hcx: StableHashCtxt>(&self, _: &mut Hcx, hasher: &mut StableHasher) {
527 ::std::hash::Hash::hash(self, hasher);
528 }
529}
530
531impl<T> StableHash for ::std::range::RangeInclusive<T>
532where
533 T: StableHash,
534{
535 #[inline]
536 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
537 self.start.stable_hash(hcx, hasher);
538 self.last.stable_hash(hcx, hasher);
539 }
540}
541
542impl<I: Idx, T> StableHash for IndexSlice<I, T>
543where
544 T: StableHash,
545{
546 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
547 self.len().stable_hash(hcx, hasher);
548 for v in &self.raw {
549 v.stable_hash(hcx, hasher);
550 }
551 }
552}
553
554impl<I: Idx, T> StableHash for IndexVec<I, T>
555where
556 T: StableHash,
557{
558 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
559 self.len().stable_hash(hcx, hasher);
560 for v in &self.raw {
561 v.stable_hash(hcx, hasher);
562 }
563 }
564}
565
566impl<I: Idx> StableHash for DenseBitSet<I> {
567 fn stable_hash<Hcx: StableHashCtxt>(&self, _hcx: &mut Hcx, hasher: &mut StableHasher) {
568 ::std::hash::Hash::hash(self, hasher);
569 }
570}
571
572impl<R: Idx, C: Idx> StableHash for bit_set::BitMatrix<R, C> {
573 fn stable_hash<Hcx: StableHashCtxt>(&self, _hcx: &mut Hcx, hasher: &mut StableHasher) {
574 ::std::hash::Hash::hash(self, hasher);
575 }
576}
577
578impl crate::stable_hash::StableHash for ::std::ffi::OsStr {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for ::std::ffi::OsStr {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(::std::ffi::OsStr);
579
580impl crate::stable_hash::StableHash for ::std::path::Path {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for ::std::path::Path {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(::std::path::Path);
581impl crate::stable_hash::StableHash for ::std::path::PathBuf {
#[inline]
fn stable_hash<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hash::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hash::StableOrd for ::std::path::PathBuf {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}impl_stable_traits_for_trivial_type!(::std::path::PathBuf);
582
583impl<V> !StableHash for std::collections::HashSet<V> {}
587impl<K, V> !StableHash for std::collections::HashMap<K, V> {}
588
589impl<K, V> StableHash for ::std::collections::BTreeMap<K, V>
590where
591 K: StableHash + StableOrd,
592 V: StableHash,
593{
594 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
595 self.len().stable_hash(hcx, hasher);
596 for entry in self.iter() {
597 entry.stable_hash(hcx, hasher);
598 }
599 }
600}
601
602impl<K> StableHash for ::std::collections::BTreeSet<K>
603where
604 K: StableHash + StableOrd,
605{
606 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
607 self.len().stable_hash(hcx, hasher);
608 for entry in self.iter() {
609 entry.stable_hash(hcx, hasher);
610 }
611 }
612}
613
614#[derive(#[automatically_derived]
impl ::core::clone::Clone for StableHashControls {
#[inline]
fn clone(&self) -> StableHashControls {
let _: ::core::clone::AssertParamIsClone<bool>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for StableHashControls { }Copy, #[automatically_derived]
impl ::core::hash::Hash for StableHashControls {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.hash_spans, state)
}
}Hash, #[automatically_derived]
impl ::core::cmp::Eq for StableHashControls {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<bool>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for StableHashControls {
#[inline]
fn eq(&self, other: &StableHashControls) -> bool {
self.hash_spans == other.hash_spans
}
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for StableHashControls {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"StableHashControls", "hash_spans", &&self.hash_spans)
}
}Debug)]
622pub struct StableHashControls {
623 pub hash_spans: bool,
624}