1 //! This module contains `HashStable` implementations for various data types
2 //! from `rustc_middle::ty` in no particular order.
4 use crate::middle
::region
;
7 use rustc_data_structures
::fingerprint
::Fingerprint
;
8 use rustc_data_structures
::fx
::FxHashMap
;
9 use rustc_data_structures
::stable_hasher
::HashingControls
;
10 use rustc_data_structures
::stable_hasher
::{HashStable, StableHasher, ToStableHashKey}
;
11 use rustc_query_system
::ich
::StableHashingContext
;
12 use std
::cell
::RefCell
;
15 impl<'a
, 'tcx
, T
> HashStable
<StableHashingContext
<'a
>> for &'tcx ty
::List
<T
>
17 T
: HashStable
<StableHashingContext
<'a
>>,
19 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
21 static CACHE
: RefCell
<FxHashMap
<(usize, usize, HashingControls
), Fingerprint
>> =
22 RefCell
::new(Default
::default());
25 let hash
= CACHE
.with(|cache
| {
26 let key
= (self.as_ptr() as usize, self.len(), hcx
.hashing_controls());
27 if let Some(&hash
) = cache
.borrow().get(&key
) {
31 let mut hasher
= StableHasher
::new();
32 (&self[..]).hash_stable(hcx
, &mut hasher
);
34 let hash
: Fingerprint
= hasher
.finish();
35 cache
.borrow_mut().insert(key
, hash
);
39 hash
.hash_stable(hcx
, hasher
);
43 impl<'a
, 'tcx
, T
> ToStableHashKey
<StableHashingContext
<'a
>> for &'tcx ty
::List
<T
>
45 T
: HashStable
<StableHashingContext
<'a
>>,
47 type KeyType
= Fingerprint
;
50 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> Fingerprint
{
51 let mut hasher
= StableHasher
::new();
52 let mut hcx
: StableHashingContext
<'a
> = hcx
.clone();
53 self.hash_stable(&mut hcx
, &mut hasher
);
58 impl<'a
, 'tcx
> HashStable
<StableHashingContext
<'a
>> for ty
::subst
::GenericArg
<'tcx
> {
59 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
60 self.unpack().hash_stable(hcx
, hasher
);
64 impl<'a
> HashStable
<StableHashingContext
<'a
>> for ty
::RegionKind
{
65 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
66 mem
::discriminant(self).hash_stable(hcx
, hasher
);
68 ty
::ReErased
| ty
::ReStatic
=> {
69 // No variant fields to hash for these ...
71 ty
::ReEmpty(universe
) => {
72 universe
.hash_stable(hcx
, hasher
);
74 ty
::ReLateBound(db
, ty
::BoundRegion { kind: ty::BrAnon(i), .. }
) => {
75 db
.hash_stable(hcx
, hasher
);
76 i
.hash_stable(hcx
, hasher
);
78 ty
::ReLateBound(db
, ty
::BoundRegion { kind: ty::BrNamed(def_id, name), .. }
) => {
79 db
.hash_stable(hcx
, hasher
);
80 def_id
.hash_stable(hcx
, hasher
);
81 name
.hash_stable(hcx
, hasher
);
83 ty
::ReLateBound(db
, ty
::BoundRegion { kind: ty::BrEnv, .. }
) => {
84 db
.hash_stable(hcx
, hasher
);
86 ty
::ReEarlyBound(ty
::EarlyBoundRegion { def_id, index, name }
) => {
87 def_id
.hash_stable(hcx
, hasher
);
88 index
.hash_stable(hcx
, hasher
);
89 name
.hash_stable(hcx
, hasher
);
91 ty
::ReFree(ref free_region
) => {
92 free_region
.hash_stable(hcx
, hasher
);
94 ty
::RePlaceholder(p
) => {
95 p
.hash_stable(hcx
, hasher
);
98 bug
!("StableHasher: unexpected region {:?}", *self)
104 impl<'a
> HashStable
<StableHashingContext
<'a
>> for ty
::RegionVid
{
106 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
107 self.index().hash_stable(hcx
, hasher
);
111 impl<'a
, 'tcx
> HashStable
<StableHashingContext
<'a
>> for ty
::ConstVid
<'tcx
> {
113 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
114 self.index
.hash_stable(hcx
, hasher
);
118 impl<'tcx
> HashStable
<StableHashingContext
<'tcx
>> for ty
::BoundVar
{
120 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'tcx
>, hasher
: &mut StableHasher
) {
121 self.index().hash_stable(hcx
, hasher
);
125 impl<'a
, 'tcx
, T
> HashStable
<StableHashingContext
<'a
>> for ty
::Binder
<'tcx
, T
>
127 T
: HashStable
<StableHashingContext
<'a
>>,
129 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
130 self.as_ref().skip_binder().hash_stable(hcx
, hasher
);
131 self.bound_vars().hash_stable(hcx
, hasher
);
135 // AllocIds get resolved to whatever they point to (to be stable)
136 impl<'a
> HashStable
<StableHashingContext
<'a
>> for mir
::interpret
::AllocId
{
137 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
138 ty
::tls
::with_opt(|tcx
| {
139 trace
!("hashing {:?}", *self);
140 let tcx
= tcx
.expect("can't hash AllocIds during hir lowering");
141 tcx
.get_global_alloc(*self).hash_stable(hcx
, hasher
);
146 // `Relocations` with default type parameters is a sorted map.
147 impl<'a
, Tag
> HashStable
<StableHashingContext
<'a
>> for mir
::interpret
::Relocations
<Tag
>
149 Tag
: HashStable
<StableHashingContext
<'a
>>,
151 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
152 self.len().hash_stable(hcx
, hasher
);
153 for reloc
in self.iter() {
154 reloc
.hash_stable(hcx
, hasher
);
159 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for region
::Scope
{
160 type KeyType
= region
::Scope
;
163 fn to_stable_hash_key(&self, _
: &StableHashingContext
<'a
>) -> region
::Scope
{