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