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