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 StableHash for NonZero<u32> {
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 NonZero<usize> {
249 #[inline]
250 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
251 self.get().stable_hash(hcx, hasher)
252 }
253}
254
255impl StableHash for f32 {
256 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
257 let val: u32 = self.to_bits();
258 val.stable_hash(hcx, hasher);
259 }
260}
261
262impl StableHash for f64 {
263 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
264 let val: u64 = self.to_bits();
265 val.stable_hash(hcx, hasher);
266 }
267}
268
269impl StableHash for ::std::cmp::Ordering {
270 #[inline]
271 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
272 (*self as i8).stable_hash(hcx, hasher);
273 }
274}
275
276impl<T1: StableHash> StableHash for (T1,) {
277 #[inline]
278 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
279 let (ref _0,) = *self;
280 _0.stable_hash(hcx, hasher);
281 }
282}
283
284impl<T1: StableHash, T2: StableHash> StableHash for (T1, T2) {
285 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
286 let (ref _0, ref _1) = *self;
287 _0.stable_hash(hcx, hasher);
288 _1.stable_hash(hcx, hasher);
289 }
290}
291
292impl<T1: StableOrd, T2: StableOrd> StableOrd for (T1, T2) {
293 const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT && T2::CAN_USE_UNSTABLE_SORT;
294
295 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
298}
299
300impl<T1, T2, T3> StableHash for (T1, T2, T3)
301where
302 T1: StableHash,
303 T2: StableHash,
304 T3: StableHash,
305{
306 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
307 let (ref _0, ref _1, ref _2) = *self;
308 _0.stable_hash(hcx, hasher);
309 _1.stable_hash(hcx, hasher);
310 _2.stable_hash(hcx, hasher);
311 }
312}
313
314impl<T1: StableOrd, T2: StableOrd, T3: StableOrd> StableOrd for (T1, T2, T3) {
315 const CAN_USE_UNSTABLE_SORT: bool =
316 T1::CAN_USE_UNSTABLE_SORT && T2::CAN_USE_UNSTABLE_SORT && T3::CAN_USE_UNSTABLE_SORT;
317
318 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
321}
322
323impl<T1, T2, T3, T4> StableHash for (T1, T2, T3, T4)
324where
325 T1: StableHash,
326 T2: StableHash,
327 T3: StableHash,
328 T4: StableHash,
329{
330 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
331 let (ref _0, ref _1, ref _2, ref _3) = *self;
332 _0.stable_hash(hcx, hasher);
333 _1.stable_hash(hcx, hasher);
334 _2.stable_hash(hcx, hasher);
335 _3.stable_hash(hcx, hasher);
336 }
337}
338
339impl<T1: StableOrd, T2: StableOrd, T3: StableOrd, T4: StableOrd> StableOrd for (T1, T2, T3, T4) {
340 const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT
341 && T2::CAN_USE_UNSTABLE_SORT
342 && T3::CAN_USE_UNSTABLE_SORT
343 && T4::CAN_USE_UNSTABLE_SORT;
344
345 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
348}
349
350impl<T: StableHash> StableHash for [T] {
351 default fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
352 self.len().stable_hash(hcx, hasher);
353 for item in self {
354 item.stable_hash(hcx, hasher);
355 }
356 }
357}
358
359impl StableHash for [u8] {
360 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
361 self.len().stable_hash(hcx, hasher);
362 hasher.write(self);
363 }
364}
365
366impl<T: StableHash> StableHash for Vec<T> {
367 #[inline]
368 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
369 self[..].stable_hash(hcx, hasher);
370 }
371}
372
373impl<K, V, R> StableHash for indexmap::IndexMap<K, V, R>
374where
375 K: StableHash + Eq + Hash,
376 V: StableHash,
377 R: BuildHasher,
378{
379 #[inline]
380 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
381 self.len().stable_hash(hcx, hasher);
382 for kv in self {
383 kv.stable_hash(hcx, hasher);
384 }
385 }
386}
387
388impl<K, R> StableHash for indexmap::IndexSet<K, R>
389where
390 K: StableHash + Eq + Hash,
391 R: BuildHasher,
392{
393 #[inline]
394 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
395 self.len().stable_hash(hcx, hasher);
396 for key in self {
397 key.stable_hash(hcx, hasher);
398 }
399 }
400}
401
402impl<A, const N: usize> StableHash for SmallVec<[A; N]>
403where
404 A: StableHash,
405{
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: StableHash> StableHash for ThinVec<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 Box<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::rc::Rc<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<T: ?Sized + StableHash> StableHash for ::std::sync::Arc<T> {
434 #[inline]
435 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
436 (**self).stable_hash(hcx, hasher);
437 }
438}
439
440impl StableHash for str {
441 #[inline]
442 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
443 self.as_bytes().stable_hash(hcx, hasher);
444 }
445}
446
447impl StableOrd for &str {
448 const CAN_USE_UNSTABLE_SORT: bool = true;
449
450 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
453}
454
455impl StableHash for String {
456 #[inline]
457 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
458 self[..].stable_hash(hcx, hasher);
459 }
460}
461
462impl StableOrd for String {
463 const CAN_USE_UNSTABLE_SORT: bool = true;
464
465 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
468}
469
470impl StableHash for bool {
471 #[inline]
472 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
473 (if *self { 1u8 } else { 0u8 }).stable_hash(hcx, hasher);
474 }
475}
476
477impl StableOrd for bool {
478 const CAN_USE_UNSTABLE_SORT: bool = true;
479
480 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
482}
483
484impl<T> StableHash for Option<T>
485where
486 T: StableHash,
487{
488 #[inline]
489 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
490 if let Some(ref value) = *self {
491 1u8.stable_hash(hcx, hasher);
492 value.stable_hash(hcx, hasher);
493 } else {
494 0u8.stable_hash(hcx, hasher);
495 }
496 }
497}
498
499impl<T: StableOrd> StableOrd for Option<T> {
500 const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT;
501
502 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
504}
505
506impl<T1, T2> StableHash for Result<T1, T2>
507where
508 T1: StableHash,
509 T2: StableHash,
510{
511 #[inline]
512 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
513 mem::discriminant(self).stable_hash(hcx, hasher);
514 match *self {
515 Ok(ref x) => x.stable_hash(hcx, hasher),
516 Err(ref x) => x.stable_hash(hcx, hasher),
517 }
518 }
519}
520
521impl<'a, T> StableHash for &'a T
522where
523 T: StableHash + ?Sized,
524{
525 #[inline]
526 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
527 (**self).stable_hash(hcx, hasher);
528 }
529}
530
531impl<T> StableHash for ::std::mem::Discriminant<T> {
532 #[inline]
533 fn stable_hash<Hcx: StableHashCtxt>(&self, _: &mut Hcx, hasher: &mut StableHasher) {
534 ::std::hash::Hash::hash(self, hasher);
535 }
536}
537
538impl<T> StableHash for ::std::range::RangeInclusive<T>
539where
540 T: StableHash,
541{
542 #[inline]
543 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
544 self.start.stable_hash(hcx, hasher);
545 self.last.stable_hash(hcx, hasher);
546 }
547}
548
549impl<I: Idx, T> StableHash for IndexSlice<I, T>
550where
551 T: StableHash,
552{
553 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
554 self.len().stable_hash(hcx, hasher);
555 for v in &self.raw {
556 v.stable_hash(hcx, hasher);
557 }
558 }
559}
560
561impl<I: Idx, T> StableHash for IndexVec<I, T>
562where
563 T: StableHash,
564{
565 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
566 self.len().stable_hash(hcx, hasher);
567 for v in &self.raw {
568 v.stable_hash(hcx, hasher);
569 }
570 }
571}
572
573impl<I: Idx> StableHash for DenseBitSet<I> {
574 fn stable_hash<Hcx: StableHashCtxt>(&self, _hcx: &mut Hcx, hasher: &mut StableHasher) {
575 ::std::hash::Hash::hash(self, hasher);
576 }
577}
578
579impl<R: Idx, C: Idx> StableHash for bit_set::BitMatrix<R, C> {
580 fn stable_hash<Hcx: StableHashCtxt>(&self, _hcx: &mut Hcx, hasher: &mut StableHasher) {
581 ::std::hash::Hash::hash(self, hasher);
582 }
583}
584
585impl 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);
586
587impl 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);
588impl 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);
589
590impl<V> !StableHash for std::collections::HashSet<V> {}
594impl<K, V> !StableHash for std::collections::HashMap<K, V> {}
595
596impl<K, V> StableHash for ::std::collections::BTreeMap<K, V>
597where
598 K: StableHash + StableOrd,
599 V: StableHash,
600{
601 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
602 self.len().stable_hash(hcx, hasher);
603 for entry in self.iter() {
604 entry.stable_hash(hcx, hasher);
605 }
606 }
607}
608
609impl<K> StableHash for ::std::collections::BTreeSet<K>
610where
611 K: StableHash + StableOrd,
612{
613 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
614 self.len().stable_hash(hcx, hasher);
615 for entry in self.iter() {
616 entry.stable_hash(hcx, hasher);
617 }
618 }
619}
620
621#[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)]
629pub struct StableHashControls {
630 pub hash_spans: bool,
631}