1 //! This module contains `HashStable` implementations for various data types
2 //! from rustc::ty in no particular order.
4 use crate::ich
::{Fingerprint, NodeIdHashingMode, StableHashingContext}
;
5 use crate::middle
::region
;
8 use rustc_data_structures
::fx
::FxHashMap
;
9 use rustc_data_structures
::stable_hasher
::{HashStable, StableHasher, ToStableHashKey}
;
10 use std
::cell
::RefCell
;
13 impl<'a
, 'tcx
, T
> HashStable
<StableHashingContext
<'a
>> for &'tcx ty
::List
<T
>
15 T
: HashStable
<StableHashingContext
<'a
>>,
17 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
19 static CACHE
: RefCell
<FxHashMap
<(usize, usize), Fingerprint
>> =
20 RefCell
::new(Default
::default());
23 let hash
= CACHE
.with(|cache
| {
24 let key
= (self.as_ptr() as usize, self.len());
25 if let Some(&hash
) = cache
.borrow().get(&key
) {
29 let mut hasher
= StableHasher
::new();
30 (&self[..]).hash_stable(hcx
, &mut hasher
);
32 let hash
: Fingerprint
= hasher
.finish();
33 cache
.borrow_mut().insert(key
, hash
);
37 hash
.hash_stable(hcx
, hasher
);
41 impl<'a
, 'tcx
, T
> ToStableHashKey
<StableHashingContext
<'a
>> for &'tcx ty
::List
<T
>
43 T
: HashStable
<StableHashingContext
<'a
>>,
45 type KeyType
= Fingerprint
;
48 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> Fingerprint
{
49 let mut hasher
= StableHasher
::new();
50 let mut hcx
: StableHashingContext
<'a
> = hcx
.clone();
51 self.hash_stable(&mut hcx
, &mut hasher
);
56 impl<'a
, 'tcx
> HashStable
<StableHashingContext
<'a
>> for ty
::subst
::GenericArg
<'tcx
> {
57 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
58 self.unpack().hash_stable(hcx
, hasher
);
62 impl<'a
> HashStable
<StableHashingContext
<'a
>> for ty
::RegionKind
{
63 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
64 mem
::discriminant(self).hash_stable(hcx
, hasher
);
66 ty
::ReErased
| ty
::ReStatic
=> {
67 // No variant fields to hash for these ...
69 ty
::ReEmpty(universe
) => {
70 universe
.hash_stable(hcx
, hasher
);
72 ty
::ReLateBound(db
, ty
::BrAnon(i
)) => {
73 db
.hash_stable(hcx
, hasher
);
74 i
.hash_stable(hcx
, hasher
);
76 ty
::ReLateBound(db
, ty
::BrNamed(def_id
, name
)) => {
77 db
.hash_stable(hcx
, hasher
);
78 def_id
.hash_stable(hcx
, hasher
);
79 name
.hash_stable(hcx
, hasher
);
81 ty
::ReLateBound(db
, ty
::BrEnv
) => {
82 db
.hash_stable(hcx
, hasher
);
84 ty
::ReEarlyBound(ty
::EarlyBoundRegion { def_id, index, name }
) => {
85 def_id
.hash_stable(hcx
, hasher
);
86 index
.hash_stable(hcx
, hasher
);
87 name
.hash_stable(hcx
, hasher
);
89 ty
::ReScope(scope
) => {
90 scope
.hash_stable(hcx
, hasher
);
92 ty
::ReFree(ref free_region
) => {
93 free_region
.hash_stable(hcx
, hasher
);
95 ty
::ReClosureBound(vid
) => {
96 vid
.hash_stable(hcx
, hasher
);
98 ty
::ReVar(..) | ty
::RePlaceholder(..) => {
99 bug
!("StableHasher: unexpected region {:?}", *self)
105 impl<'a
> HashStable
<StableHashingContext
<'a
>> for ty
::RegionVid
{
107 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
108 self.index().hash_stable(hcx
, hasher
);
112 impl<'a
, 'tcx
> HashStable
<StableHashingContext
<'a
>> for ty
::ConstVid
<'tcx
> {
114 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
115 self.index
.hash_stable(hcx
, hasher
);
119 impl<'tcx
> HashStable
<StableHashingContext
<'tcx
>> for ty
::BoundVar
{
121 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'tcx
>, hasher
: &mut StableHasher
) {
122 self.index().hash_stable(hcx
, hasher
);
126 impl<'a
, T
> HashStable
<StableHashingContext
<'a
>> for ty
::Binder
<T
>
128 T
: HashStable
<StableHashingContext
<'a
>>,
130 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
131 self.skip_binder().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 let alloc_kind
= tcx
.alloc_map
.lock().get(*self);
142 alloc_kind
.hash_stable(hcx
, hasher
);
147 // `Relocations` with default type parameters is a sorted map.
148 impl<'a
, Tag
> HashStable
<StableHashingContext
<'a
>> for mir
::interpret
::Relocations
<Tag
>
150 Tag
: HashStable
<StableHashingContext
<'a
>>,
152 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
153 self.len().hash_stable(hcx
, hasher
);
154 for reloc
in self.iter() {
155 reloc
.hash_stable(hcx
, hasher
);
160 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for region
::Scope
{
161 type KeyType
= region
::Scope
;
164 fn to_stable_hash_key(&self, _
: &StableHashingContext
<'a
>) -> region
::Scope
{
169 impl<'a
> HashStable
<StableHashingContext
<'a
>> for ty
::TyVid
{
170 fn hash_stable(&self, _hcx
: &mut StableHashingContext
<'a
>, _hasher
: &mut StableHasher
) {
171 // `TyVid` values are confined to an inference context and hence
172 // should not be hashed.
173 bug
!("ty::TyKind::hash_stable() - can't hash a TyVid {:?}.", *self)
177 impl<'a
> HashStable
<StableHashingContext
<'a
>> for ty
::IntVid
{
178 fn hash_stable(&self, _hcx
: &mut StableHashingContext
<'a
>, _hasher
: &mut StableHasher
) {
179 // `IntVid` values are confined to an inference context and hence
180 // should not be hashed.
181 bug
!("ty::TyKind::hash_stable() - can't hash an IntVid {:?}.", *self)
185 impl<'a
> HashStable
<StableHashingContext
<'a
>> for ty
::FloatVid
{
186 fn hash_stable(&self, _hcx
: &mut StableHashingContext
<'a
>, _hasher
: &mut StableHasher
) {
187 // `FloatVid` values are confined to an inference context and hence
188 // should not be hashed.
189 bug
!("ty::TyKind::hash_stable() - can't hash a FloatVid {:?}.", *self)
193 impl<'a
, T
> HashStable
<StableHashingContext
<'a
>> for ty
::steal
::Steal
<T
>
195 T
: HashStable
<StableHashingContext
<'a
>>,
197 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
198 self.borrow().hash_stable(hcx
, hasher
);
202 impl<'a
> HashStable
<StableHashingContext
<'a
>> for crate::middle
::privacy
::AccessLevels
{
203 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
204 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
205 let crate::middle
::privacy
::AccessLevels { ref map }
= *self;
207 map
.hash_stable(hcx
, hasher
);