1use std::hash::{BuildHasher, Hash, Hasher};
2use std::marker::PhantomData;
3use std::num::NonZero;
4
5use rustc_index::bit_set::{self, DenseBitSet};
6use rustc_index::{Idx, IndexSlice, IndexVec};
7use rustc_macros::StableHash;
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 DummyStableHashCtxt;
43
44impl StableHashCtxt for DummyStableHashCtxt {
45 fn stable_hash_span(&mut self, _span: RawSpan, _hasher: &mut StableHasher) {
46 {
::core::panicking::panic_fmt(format_args!("method on dummy stable-hash context was unexpectedly called"));
};panic!("method on dummy stable-hash context was unexpectedly called");
47 }
48 fn def_path_hash(&self, _def_id: RawDefId) -> Fingerprint {
49 {
::core::panicking::panic_fmt(format_args!("method on dummy stable-hash context was unexpectedly called"));
};panic!("method on dummy stable-hash context was unexpectedly called");
50 }
51 fn stable_hash_controls(&self) -> StableHashControls {
52 {
::core::panicking::panic_fmt(format_args!("method on dummy stable-hash context was unexpectedly called"));
};panic!("method on dummy stable-hash context was unexpectedly called");
53 }
54 fn assert_default_stable_hash_controls(&self, _msg: &str) {
55 {
::core::panicking::panic_fmt(format_args!("method on dummy stable-hash context was unexpectedly called"));
};panic!("method on dummy stable-hash context was unexpectedly called");
56 }
57}
58
59pub struct RawSpan(pub u64);
62
63pub struct RawDefId(pub u32, pub u32);
66
67pub trait StableHash {
106 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher);
107}
108
109pub trait ToStableHashKey {
113 type KeyType: Ord + Sized + StableHash;
114 fn to_stable_hash_key<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx) -> Self::KeyType;
115}
116
117pub trait StableOrd: Ord {
147 const CAN_USE_UNSTABLE_SORT: bool;
148
149 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: ();
152}
153
154impl<T: StableOrd> StableOrd for &T {
155 const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT;
156
157 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
161}
162
163pub trait StableCompare {
174 const CAN_USE_UNSTABLE_SORT: bool;
175
176 fn stable_cmp(&self, other: &Self) -> std::cmp::Ordering;
177}
178
179impl<T: StableOrd> StableCompare for T {
182 const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT;
183
184 fn stable_cmp(&self, other: &Self) -> std::cmp::Ordering {
185 self.cmp(other)
186 }
187}
188
189macro_rules! impl_stable_traits_for_trivial_type {
199 ($t:ty) => {
200 impl $crate::stable_hash::StableHash for $t {
201 #[inline]
202 fn stable_hash<Hcx>(
203 &self,
204 _: &mut Hcx,
205 hasher: &mut $crate::stable_hash::StableHasher,
206 ) {
207 ::std::hash::Hash::hash(self, hasher);
208 }
209 }
210
211 impl $crate::stable_hash::StableOrd for $t {
212 const CAN_USE_UNSTABLE_SORT: bool = true;
213
214 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
217 }
218 };
219}
220
221pub(crate) use impl_stable_traits_for_trivial_type;
222
223impl 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);
224impl 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);
225impl 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);
226impl 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);
227impl 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);
228
229impl 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);
230impl 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);
231impl 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);
232impl 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);
233impl 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);
234
235impl 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);
236impl 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);
237
238impl 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);
239impl 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!(());
240
241impl 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);
242
243impl StableHash for Hash128 {
246 #[inline]
247 fn stable_hash<Hcx>(&self, _: &mut Hcx, hasher: &mut StableHasher) {
248 self.as_u128().hash(hasher);
249 }
250}
251
252impl StableOrd for Hash128 {
253 const CAN_USE_UNSTABLE_SORT: bool = true;
254
255 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
258}
259
260impl StableHash for ! {
261 fn stable_hash<Hcx>(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) {
262 ::core::panicking::unreachable_default_msg()unreachable!()
263 }
264}
265
266impl<T> StableHash for PhantomData<T> {
267 fn stable_hash<Hcx>(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) {}
268}
269
270impl<T: StableHash + std::num::ZeroablePrimitive> StableHash for NonZero<T> {
271 #[inline]
272 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
273 self.get().stable_hash(hcx, hasher)
274 }
275}
276
277impl StableHash for f32 {
278 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
279 let val: u32 = self.to_bits();
280 val.stable_hash(hcx, hasher);
281 }
282}
283
284impl StableHash for f64 {
285 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
286 let val: u64 = self.to_bits();
287 val.stable_hash(hcx, hasher);
288 }
289}
290
291impl StableHash for ::std::cmp::Ordering {
292 #[inline]
293 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
294 (*self as i8).stable_hash(hcx, hasher);
295 }
296}
297
298impl<T1: StableHash> StableHash for (T1,) {
299 #[inline]
300 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
301 let (ref _0,) = *self;
302 _0.stable_hash(hcx, hasher);
303 }
304}
305
306impl<T1: StableHash, T2: StableHash> StableHash for (T1, T2) {
307 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
308 let (ref _0, ref _1) = *self;
309 _0.stable_hash(hcx, hasher);
310 _1.stable_hash(hcx, hasher);
311 }
312}
313
314impl<T1: StableOrd, T2: StableOrd> StableOrd for (T1, T2) {
315 const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT && T2::CAN_USE_UNSTABLE_SORT;
316
317 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
320}
321
322impl<T1, T2, T3> StableHash for (T1, T2, T3)
323where
324 T1: StableHash,
325 T2: StableHash,
326 T3: StableHash,
327{
328 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
329 let (ref _0, ref _1, ref _2) = *self;
330 _0.stable_hash(hcx, hasher);
331 _1.stable_hash(hcx, hasher);
332 _2.stable_hash(hcx, hasher);
333 }
334}
335
336impl<T1: StableOrd, T2: StableOrd, T3: StableOrd> StableOrd for (T1, T2, T3) {
337 const CAN_USE_UNSTABLE_SORT: bool =
338 T1::CAN_USE_UNSTABLE_SORT && T2::CAN_USE_UNSTABLE_SORT && T3::CAN_USE_UNSTABLE_SORT;
339
340 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
343}
344
345impl<T1, T2, T3, T4> StableHash for (T1, T2, T3, T4)
346where
347 T1: StableHash,
348 T2: StableHash,
349 T3: StableHash,
350 T4: StableHash,
351{
352 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
353 let (ref _0, ref _1, ref _2, ref _3) = *self;
354 _0.stable_hash(hcx, hasher);
355 _1.stable_hash(hcx, hasher);
356 _2.stable_hash(hcx, hasher);
357 _3.stable_hash(hcx, hasher);
358 }
359}
360
361impl<T1: StableOrd, T2: StableOrd, T3: StableOrd, T4: StableOrd> StableOrd for (T1, T2, T3, T4) {
362 const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT
363 && T2::CAN_USE_UNSTABLE_SORT
364 && T3::CAN_USE_UNSTABLE_SORT
365 && T4::CAN_USE_UNSTABLE_SORT;
366
367 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
370}
371
372impl<T: StableHash> StableHash for [T] {
373 default fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
374 self.len().stable_hash(hcx, hasher);
375 for item in self {
376 item.stable_hash(hcx, hasher);
377 }
378 }
379}
380
381impl StableHash for [u8] {
382 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
383 self.len().stable_hash(hcx, hasher);
384 hasher.write(self);
385 }
386}
387
388impl<T: StableHash> StableHash for Vec<T> {
389 #[inline]
390 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
391 self[..].stable_hash(hcx, hasher);
392 }
393}
394
395impl<K, V, R> StableHash for indexmap::IndexMap<K, V, R>
396where
397 K: StableHash + Eq + Hash,
398 V: StableHash,
399 R: BuildHasher,
400{
401 #[inline]
402 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
403 self.len().stable_hash(hcx, hasher);
404 for kv in self {
405 kv.stable_hash(hcx, hasher);
406 }
407 }
408}
409
410impl<K, R> StableHash for indexmap::IndexSet<K, R>
411where
412 K: StableHash + Eq + Hash,
413 R: BuildHasher,
414{
415 #[inline]
416 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
417 self.len().stable_hash(hcx, hasher);
418 for key in self {
419 key.stable_hash(hcx, hasher);
420 }
421 }
422}
423
424impl<A, const N: usize> StableHash for SmallVec<[A; N]>
425where
426 A: StableHash,
427{
428 #[inline]
429 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
430 self[..].stable_hash(hcx, hasher);
431 }
432}
433
434impl<T: StableHash> StableHash for ThinVec<T> {
435 #[inline]
436 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
437 self[..].stable_hash(hcx, hasher);
438 }
439}
440
441impl<T: ?Sized + StableHash> StableHash for Box<T> {
442 #[inline]
443 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
444 (**self).stable_hash(hcx, hasher);
445 }
446}
447
448impl<T: ?Sized + StableHash> StableHash for ::std::rc::Rc<T> {
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<T: ?Sized + StableHash> StableHash for ::std::sync::Arc<T> {
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 StableHash for str {
463 #[inline]
464 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
465 self.as_bytes().stable_hash(hcx, hasher);
466 }
467}
468
469impl StableOrd for &str {
470 const CAN_USE_UNSTABLE_SORT: bool = true;
471
472 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
475}
476
477impl StableHash for String {
478 #[inline]
479 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
480 self[..].stable_hash(hcx, hasher);
481 }
482}
483
484impl StableOrd for String {
485 const CAN_USE_UNSTABLE_SORT: bool = true;
486
487 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
490}
491
492impl StableHash for bool {
493 #[inline]
494 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
495 (if *self { 1u8 } else { 0u8 }).stable_hash(hcx, hasher);
496 }
497}
498
499impl StableOrd for bool {
500 const CAN_USE_UNSTABLE_SORT: bool = true;
501
502 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
504}
505
506impl<T> StableHash for Option<T>
507where
508 T: StableHash,
509{
510 #[inline]
511 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
512 if let Some(ref value) = *self {
513 1u8.stable_hash(hcx, hasher);
514 value.stable_hash(hcx, hasher);
515 } else {
516 0u8.stable_hash(hcx, hasher);
517 }
518 }
519}
520
521impl<T: StableOrd> StableOrd for Option<T> {
522 const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT;
523
524 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
526}
527
528impl<T1, T2> StableHash for Result<T1, T2>
529where
530 T1: StableHash,
531 T2: StableHash,
532{
533 #[inline]
534 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
535 #[derive(const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for Tag {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
Tag::Ok => 0u8.stable_hash(__hcx, __hasher),
Tag::Err => 1u8.stable_hash(__hcx, __hasher),
}
match *self { Tag::Ok => {} Tag::Err => {} }
}
}
};StableHash)]
536 enum Tag {
537 Ok,
538 Err,
539 }
540 match *self {
541 Ok(ref x) => {
542 Tag::Ok.stable_hash(hcx, hasher);
543 x.stable_hash(hcx, hasher);
544 }
545 Err(ref x) => {
546 Tag::Err.stable_hash(hcx, hasher);
547 x.stable_hash(hcx, hasher);
548 }
549 }
550 }
551}
552
553impl<'a, T> StableHash for &'a T
554where
555 T: StableHash + ?Sized,
556{
557 #[inline]
558 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
559 (**self).stable_hash(hcx, hasher);
560 }
561}
562
563impl<T> !StableHash for std::mem::Discriminant<T> {}
576
577impl<T> StableHash for ::std::range::RangeInclusive<T>
578where
579 T: StableHash,
580{
581 #[inline]
582 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
583 self.start.stable_hash(hcx, hasher);
584 self.last.stable_hash(hcx, hasher);
585 }
586}
587
588impl<I: Idx, T> StableHash for IndexSlice<I, T>
589where
590 T: StableHash,
591{
592 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
593 self.len().stable_hash(hcx, hasher);
594 for v in &self.raw {
595 v.stable_hash(hcx, hasher);
596 }
597 }
598}
599
600impl<I: Idx, T> StableHash for IndexVec<I, T>
601where
602 T: StableHash,
603{
604 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
605 self.len().stable_hash(hcx, hasher);
606 for v in &self.raw {
607 v.stable_hash(hcx, hasher);
608 }
609 }
610}
611
612impl<I: Idx> StableHash for DenseBitSet<I> {
613 fn stable_hash<Hcx: StableHashCtxt>(&self, _hcx: &mut Hcx, hasher: &mut StableHasher) {
614 ::std::hash::Hash::hash(self, hasher);
615 }
616}
617
618impl<R: Idx, C: Idx> StableHash for bit_set::BitMatrix<R, C> {
619 fn stable_hash<Hcx: StableHashCtxt>(&self, _hcx: &mut Hcx, hasher: &mut StableHasher) {
620 ::std::hash::Hash::hash(self, hasher);
621 }
622}
623
624impl 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);
625
626impl StableHash for std::path::Path {
627 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
628 use std::path::{Component, Prefix};
629
630 #[derive(const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for Tag {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
Tag::StartOfPath => 0u8.stable_hash(__hcx, __hasher),
Tag::PrefixVerbatim => 1u8.stable_hash(__hcx, __hasher),
Tag::PrefixVerbatimUNC => 2u8.stable_hash(__hcx, __hasher),
Tag::PrefixVerbatimDisk => 3u8.stable_hash(__hcx, __hasher),
Tag::PrefixDeviceNS => 4u8.stable_hash(__hcx, __hasher),
Tag::PrefixUNC => 5u8.stable_hash(__hcx, __hasher),
Tag::PrefixDisk => 6u8.stable_hash(__hcx, __hasher),
Tag::RootDir => 7u8.stable_hash(__hcx, __hasher),
Tag::CurDir => 8u8.stable_hash(__hcx, __hasher),
Tag::ParentDir => 9u8.stable_hash(__hcx, __hasher),
Tag::Normal => 10u8.stable_hash(__hcx, __hasher),
Tag::EndOfPath => 11u8.stable_hash(__hcx, __hasher),
}
match *self {
Tag::StartOfPath => {}
Tag::PrefixVerbatim => {}
Tag::PrefixVerbatimUNC => {}
Tag::PrefixVerbatimDisk => {}
Tag::PrefixDeviceNS => {}
Tag::PrefixUNC => {}
Tag::PrefixDisk => {}
Tag::RootDir => {}
Tag::CurDir => {}
Tag::ParentDir => {}
Tag::Normal => {}
Tag::EndOfPath => {}
}
}
}
};StableHash)]
632 enum Tag {
633 StartOfPath,
634 PrefixVerbatim,
635 PrefixVerbatimUNC,
636 PrefixVerbatimDisk,
637 PrefixDeviceNS,
638 PrefixUNC,
639 PrefixDisk,
640 RootDir,
641 CurDir,
642 ParentDir,
643 Normal,
644 EndOfPath,
645 }
646
647 Tag::StartOfPath.stable_hash(hcx, hasher);
649
650 for (i, component) in self.components().enumerate() {
651 i.stable_hash(hcx, hasher);
654 match component {
655 Component::Prefix(prefix) => match prefix.kind() {
656 Prefix::Verbatim(os_str) => {
657 Tag::PrefixVerbatim.stable_hash(hcx, hasher);
658 os_str.stable_hash(hcx, hasher);
659 }
660 Prefix::VerbatimUNC(host, share) => {
661 Tag::PrefixVerbatimUNC.stable_hash(hcx, hasher);
662 host.stable_hash(hcx, hasher);
663 share.stable_hash(hcx, hasher);
664 }
665 Prefix::VerbatimDisk(letter) => {
666 Tag::PrefixVerbatimDisk.stable_hash(hcx, hasher);
667 letter.stable_hash(hcx, hasher);
668 }
669 Prefix::DeviceNS(os_str) => {
670 Tag::PrefixDeviceNS.stable_hash(hcx, hasher);
671 os_str.stable_hash(hcx, hasher);
672 }
673 Prefix::UNC(host, share) => {
674 Tag::PrefixUNC.stable_hash(hcx, hasher);
675 host.stable_hash(hcx, hasher);
676 share.stable_hash(hcx, hasher);
677 }
678 Prefix::Disk(letter) => {
679 Tag::PrefixDisk.stable_hash(hcx, hasher);
680 letter.stable_hash(hcx, hasher);
681 }
682 },
683 Component::RootDir => Tag::RootDir.stable_hash(hcx, hasher),
684 Component::CurDir => Tag::CurDir.stable_hash(hcx, hasher),
685 Component::ParentDir => Tag::ParentDir.stable_hash(hcx, hasher),
686 Component::Normal(os_str) => {
687 Tag::Normal.stable_hash(hcx, hasher);
688 os_str.stable_hash(hcx, hasher);
689 }
690 }
691 }
692
693 Tag::EndOfPath.stable_hash(hcx, hasher);
696 }
697}
698
699impl StableOrd for std::path::Path {
700 const CAN_USE_UNSTABLE_SORT: bool = true;
702 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
704}
705
706impl StableHash for std::path::PathBuf {
707 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
708 self.as_path().stable_hash(hcx, hasher);
709 }
710}
711
712impl StableOrd for std::path::PathBuf {
713 const CAN_USE_UNSTABLE_SORT: bool = <std::path::Path as StableOrd>::CAN_USE_UNSTABLE_SORT;
714 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
716}
717
718impl<V> !StableHash for std::collections::HashSet<V> {}
722impl<K, V> !StableHash for std::collections::HashMap<K, V> {}
723
724impl<K, V> StableHash for ::std::collections::BTreeMap<K, V>
725where
726 K: StableHash + StableOrd,
727 V: StableHash,
728{
729 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
730 self.len().stable_hash(hcx, hasher);
731 for entry in self.iter() {
732 entry.stable_hash(hcx, hasher);
733 }
734 }
735}
736
737impl<K> StableHash for ::std::collections::BTreeSet<K>
738where
739 K: StableHash + StableOrd,
740{
741 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
742 self.len().stable_hash(hcx, hasher);
743 for entry in self.iter() {
744 entry.stable_hash(hcx, hasher);
745 }
746 }
747}
748
749#[derive(#[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for StableHashControls {
}
#[automatically_derived]impl ::core::clone::Clone for StableHashControls {
#[inline]
fn clone(&self) -> Self {
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: &Self) -> 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)]
757pub struct StableHashControls {
758 pub hash_spans: bool,
759}