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 HashStableContext {
23 fn span_hash_stable(&mut self, span: RawSpan, hasher: &mut StableHasher);
25
26 fn def_path_hash(&self, def_id: RawDefId) -> RawDefPathHash;
28
29 fn hashing_controls(&self) -> HashingControls;
31
32 fn assert_default_hashing_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 HashStable {
76 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher);
77}
78
79pub trait ToStableHashKey {
83 type KeyType: Ord + Sized + HashStable;
84 fn to_stable_hash_key<Hcx: HashStableContext>(&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_hasher::HashStable for $t {
171 #[inline]
172 fn hash_stable<Hcx>(
173 &self,
174 _: &mut Hcx,
175 hasher: &mut $crate::stable_hasher::StableHasher,
176 ) {
177 ::std::hash::Hash::hash(self, hasher);
178 }
179 }
180
181 impl $crate::stable_hasher::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_hasher::HashStable for i8 {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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_hasher::HashStable for i16 {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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_hasher::HashStable for i32 {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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_hasher::HashStable for i64 {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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_hasher::HashStable for isize {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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_hasher::HashStable for u8 {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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_hasher::HashStable for u16 {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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_hasher::HashStable for u32 {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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_hasher::HashStable for u64 {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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_hasher::HashStable for usize {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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_hasher::HashStable for u128 {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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_hasher::HashStable for i128 {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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_hasher::HashStable for char {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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_hasher::HashStable for () {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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_hasher::HashStable for Hash64 {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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 HashStable for Hash128 {
216 #[inline]
217 fn hash_stable<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 HashStable for ! {
231 fn hash_stable<Hcx>(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) {
232 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
233 }
234}
235
236impl<T> HashStable for PhantomData<T> {
237 fn hash_stable<Hcx>(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) {}
238}
239
240impl HashStable for NonZero<u32> {
241 #[inline]
242 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
243 self.get().hash_stable(hcx, hasher)
244 }
245}
246
247impl HashStable for NonZero<usize> {
248 #[inline]
249 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
250 self.get().hash_stable(hcx, hasher)
251 }
252}
253
254impl HashStable for f32 {
255 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
256 let val: u32 = self.to_bits();
257 val.hash_stable(hcx, hasher);
258 }
259}
260
261impl HashStable for f64 {
262 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
263 let val: u64 = self.to_bits();
264 val.hash_stable(hcx, hasher);
265 }
266}
267
268impl HashStable for ::std::cmp::Ordering {
269 #[inline]
270 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
271 (*self as i8).hash_stable(hcx, hasher);
272 }
273}
274
275impl<T1: HashStable> HashStable for (T1,) {
276 #[inline]
277 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
278 let (ref _0,) = *self;
279 _0.hash_stable(hcx, hasher);
280 }
281}
282
283impl<T1: HashStable, T2: HashStable> HashStable for (T1, T2) {
284 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
285 let (ref _0, ref _1) = *self;
286 _0.hash_stable(hcx, hasher);
287 _1.hash_stable(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> HashStable for (T1, T2, T3)
300where
301 T1: HashStable,
302 T2: HashStable,
303 T3: HashStable,
304{
305 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
306 let (ref _0, ref _1, ref _2) = *self;
307 _0.hash_stable(hcx, hasher);
308 _1.hash_stable(hcx, hasher);
309 _2.hash_stable(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> HashStable for (T1, T2, T3, T4)
323where
324 T1: HashStable,
325 T2: HashStable,
326 T3: HashStable,
327 T4: HashStable,
328{
329 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
330 let (ref _0, ref _1, ref _2, ref _3) = *self;
331 _0.hash_stable(hcx, hasher);
332 _1.hash_stable(hcx, hasher);
333 _2.hash_stable(hcx, hasher);
334 _3.hash_stable(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: HashStable> HashStable for [T] {
350 default fn hash_stable<Hcx: HashStableContext>(
351 &self,
352 hcx: &mut Hcx,
353 hasher: &mut StableHasher,
354 ) {
355 self.len().hash_stable(hcx, hasher);
356 for item in self {
357 item.hash_stable(hcx, hasher);
358 }
359 }
360}
361
362impl HashStable for [u8] {
363 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
364 self.len().hash_stable(hcx, hasher);
365 hasher.write(self);
366 }
367}
368
369impl<T: HashStable> HashStable for Vec<T> {
370 #[inline]
371 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
372 self[..].hash_stable(hcx, hasher);
373 }
374}
375
376impl<K, V, R> HashStable for indexmap::IndexMap<K, V, R>
377where
378 K: HashStable + Eq + Hash,
379 V: HashStable,
380 R: BuildHasher,
381{
382 #[inline]
383 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
384 self.len().hash_stable(hcx, hasher);
385 for kv in self {
386 kv.hash_stable(hcx, hasher);
387 }
388 }
389}
390
391impl<K, R> HashStable for indexmap::IndexSet<K, R>
392where
393 K: HashStable + Eq + Hash,
394 R: BuildHasher,
395{
396 #[inline]
397 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
398 self.len().hash_stable(hcx, hasher);
399 for key in self {
400 key.hash_stable(hcx, hasher);
401 }
402 }
403}
404
405impl<A, const N: usize> HashStable for SmallVec<[A; N]>
406where
407 A: HashStable,
408{
409 #[inline]
410 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
411 self[..].hash_stable(hcx, hasher);
412 }
413}
414
415impl<T: ?Sized + HashStable> HashStable for Box<T> {
416 #[inline]
417 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
418 (**self).hash_stable(hcx, hasher);
419 }
420}
421
422impl<T: ?Sized + HashStable> HashStable for ::std::rc::Rc<T> {
423 #[inline]
424 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
425 (**self).hash_stable(hcx, hasher);
426 }
427}
428
429impl<T: ?Sized + HashStable> HashStable for ::std::sync::Arc<T> {
430 #[inline]
431 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
432 (**self).hash_stable(hcx, hasher);
433 }
434}
435
436impl HashStable for str {
437 #[inline]
438 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
439 self.as_bytes().hash_stable(hcx, hasher);
440 }
441}
442
443impl StableOrd for &str {
444 const CAN_USE_UNSTABLE_SORT: bool = true;
445
446 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
449}
450
451impl HashStable for String {
452 #[inline]
453 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
454 self[..].hash_stable(hcx, hasher);
455 }
456}
457
458impl StableOrd for String {
459 const CAN_USE_UNSTABLE_SORT: bool = true;
460
461 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
464}
465
466impl ToStableHashKey for String {
467 type KeyType = String;
468 #[inline]
469 fn to_stable_hash_key<Hcx>(&self, _: &mut Hcx) -> Self::KeyType {
470 self.clone()
471 }
472}
473
474impl<T1: ToStableHashKey, T2: ToStableHashKey> ToStableHashKey for (T1, T2) {
475 type KeyType = (T1::KeyType, T2::KeyType);
476 #[inline]
477 fn to_stable_hash_key<Hcx: HashStableContext>(&self, hcx: &mut Hcx) -> Self::KeyType {
478 (self.0.to_stable_hash_key(hcx), self.1.to_stable_hash_key(hcx))
479 }
480}
481
482impl HashStable for bool {
483 #[inline]
484 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
485 (if *self { 1u8 } else { 0u8 }).hash_stable(hcx, hasher);
486 }
487}
488
489impl StableOrd for bool {
490 const CAN_USE_UNSTABLE_SORT: bool = true;
491
492 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
494}
495
496impl<T> HashStable for Option<T>
497where
498 T: HashStable,
499{
500 #[inline]
501 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
502 if let Some(ref value) = *self {
503 1u8.hash_stable(hcx, hasher);
504 value.hash_stable(hcx, hasher);
505 } else {
506 0u8.hash_stable(hcx, hasher);
507 }
508 }
509}
510
511impl<T: StableOrd> StableOrd for Option<T> {
512 const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT;
513
514 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
516}
517
518impl<T1, T2> HashStable for Result<T1, T2>
519where
520 T1: HashStable,
521 T2: HashStable,
522{
523 #[inline]
524 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
525 mem::discriminant(self).hash_stable(hcx, hasher);
526 match *self {
527 Ok(ref x) => x.hash_stable(hcx, hasher),
528 Err(ref x) => x.hash_stable(hcx, hasher),
529 }
530 }
531}
532
533impl<'a, T> HashStable for &'a T
534where
535 T: HashStable + ?Sized,
536{
537 #[inline]
538 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
539 (**self).hash_stable(hcx, hasher);
540 }
541}
542
543impl<T> HashStable for ::std::mem::Discriminant<T> {
544 #[inline]
545 fn hash_stable<Hcx: HashStableContext>(&self, _: &mut Hcx, hasher: &mut StableHasher) {
546 ::std::hash::Hash::hash(self, hasher);
547 }
548}
549
550impl<T> HashStable for ::std::ops::RangeInclusive<T>
551where
552 T: HashStable,
553{
554 #[inline]
555 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
556 self.start().hash_stable(hcx, hasher);
557 self.end().hash_stable(hcx, hasher);
558 }
559}
560
561impl<I: Idx, T> HashStable for IndexSlice<I, T>
562where
563 T: HashStable,
564{
565 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
566 self.len().hash_stable(hcx, hasher);
567 for v in &self.raw {
568 v.hash_stable(hcx, hasher);
569 }
570 }
571}
572
573impl<I: Idx, T> HashStable for IndexVec<I, T>
574where
575 T: HashStable,
576{
577 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
578 self.len().hash_stable(hcx, hasher);
579 for v in &self.raw {
580 v.hash_stable(hcx, hasher);
581 }
582 }
583}
584
585impl<I: Idx> HashStable for DenseBitSet<I> {
586 fn hash_stable<Hcx: HashStableContext>(&self, _hcx: &mut Hcx, hasher: &mut StableHasher) {
587 ::std::hash::Hash::hash(self, hasher);
588 }
589}
590
591impl<R: Idx, C: Idx> HashStable for bit_set::BitMatrix<R, C> {
592 fn hash_stable<Hcx: HashStableContext>(&self, _hcx: &mut Hcx, hasher: &mut StableHasher) {
593 ::std::hash::Hash::hash(self, hasher);
594 }
595}
596
597impl crate::stable_hasher::HashStable for ::std::ffi::OsStr {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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);
598
599impl crate::stable_hasher::HashStable for ::std::path::Path {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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);
600impl crate::stable_hasher::HashStable for ::std::path::PathBuf {
#[inline]
fn hash_stable<Hcx>(&self, _: &mut Hcx,
hasher: &mut crate::stable_hasher::StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
impl crate::stable_hasher::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);
601
602impl<V> !HashStable for std::collections::HashSet<V> {}
606impl<K, V> !HashStable for std::collections::HashMap<K, V> {}
607
608impl<K, V> HashStable for ::std::collections::BTreeMap<K, V>
609where
610 K: HashStable + StableOrd,
611 V: HashStable,
612{
613 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
614 self.len().hash_stable(hcx, hasher);
615 for entry in self.iter() {
616 entry.hash_stable(hcx, hasher);
617 }
618 }
619}
620
621impl<K> HashStable for ::std::collections::BTreeSet<K>
622where
623 K: HashStable + StableOrd,
624{
625 fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
626 self.len().hash_stable(hcx, hasher);
627 for entry in self.iter() {
628 entry.hash_stable(hcx, hasher);
629 }
630 }
631}
632
633#[derive(#[automatically_derived]
impl ::core::clone::Clone for HashingControls {
#[inline]
fn clone(&self) -> HashingControls {
let _: ::core::clone::AssertParamIsClone<bool>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for HashingControls { }Copy, #[automatically_derived]
impl ::core::hash::Hash for HashingControls {
#[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 HashingControls {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<bool>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for HashingControls {
#[inline]
fn eq(&self, other: &HashingControls) -> bool {
self.hash_spans == other.hash_spans
}
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for HashingControls {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"HashingControls", "hash_spans", &&self.hash_spans)
}
}Debug)]
641pub struct HashingControls {
642 pub hash_spans: bool,
643}