1 //! This module contains `HashStable` implementations for various data types
2 //! from rustc::ty in no particular order.
4 use crate::ich
::{Fingerprint, StableHashingContext, NodeIdHashingMode}
;
5 use rustc_data_structures
::fx
::FxHashMap
;
6 use rustc_data_structures
::stable_hasher
::{HashStable, ToStableHashKey, StableHasher}
;
7 use std
::cell
::RefCell
;
9 use crate::middle
::region
;
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
>>
64 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
65 mem
::discriminant(self).hash_stable(hcx
, hasher
);
70 // No variant fields to hash for these ...
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
);
99 ty
::RePlaceholder(..) => {
100 bug
!("StableHasher: unexpected region {:?}", *self)
106 impl<'a
> HashStable
<StableHashingContext
<'a
>> for ty
::RegionVid
{
108 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
109 self.index().hash_stable(hcx
, hasher
);
113 impl<'a
, 'tcx
> HashStable
<StableHashingContext
<'a
>> for ty
::ConstVid
<'tcx
> {
115 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
116 self.index
.hash_stable(hcx
, hasher
);
120 impl<'tcx
> HashStable
<StableHashingContext
<'tcx
>> for ty
::BoundVar
{
122 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'tcx
>, hasher
: &mut StableHasher
) {
123 self.index().hash_stable(hcx
, hasher
);
127 impl<'a
, T
> HashStable
<StableHashingContext
<'a
>> for ty
::Binder
<T
>
129 T
: HashStable
<StableHashingContext
<'a
>>,
131 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
132 self.skip_binder().hash_stable(hcx
, hasher
);
136 // AllocIds get resolved to whatever they point to (to be stable)
137 impl<'a
> HashStable
<StableHashingContext
<'a
>> for mir
::interpret
::AllocId
{
138 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
139 ty
::tls
::with_opt(|tcx
| {
140 trace
!("hashing {:?}", *self);
141 let tcx
= tcx
.expect("can't hash AllocIds during hir lowering");
142 let alloc_kind
= tcx
.alloc_map
.lock().get(*self);
143 alloc_kind
.hash_stable(hcx
, hasher
);
148 // `Relocations` with default type parameters is a sorted map.
149 impl<'a
, Tag
> HashStable
<StableHashingContext
<'a
>>
150 for mir
::interpret
::Relocations
<Tag
>
152 Tag
: HashStable
<StableHashingContext
<'a
>>,
154 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
155 self.len().hash_stable(hcx
, hasher
);
156 for reloc
in self.iter() {
157 reloc
.hash_stable(hcx
, hasher
);
162 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for region
::Scope
{
163 type KeyType
= region
::Scope
;
166 fn to_stable_hash_key(&self, _
: &StableHashingContext
<'a
>) -> region
::Scope
{
171 impl<'a
> HashStable
<StableHashingContext
<'a
>> for ty
::TyVid
{
172 fn hash_stable(&self, _hcx
: &mut StableHashingContext
<'a
>, _hasher
: &mut StableHasher
) {
173 // `TyVid` values are confined to an inference context and hence
174 // should not be hashed.
175 bug
!("ty::TyKind::hash_stable() - can't hash a TyVid {:?}.", *self)
179 impl<'a
> HashStable
<StableHashingContext
<'a
>> for ty
::IntVid
{
180 fn hash_stable(&self, _hcx
: &mut StableHashingContext
<'a
>, _hasher
: &mut StableHasher
) {
181 // `IntVid` values are confined to an inference context and hence
182 // should not be hashed.
183 bug
!("ty::TyKind::hash_stable() - can't hash an IntVid {:?}.", *self)
187 impl<'a
> HashStable
<StableHashingContext
<'a
>> for ty
::FloatVid
{
188 fn hash_stable(&self, _hcx
: &mut StableHashingContext
<'a
>, _hasher
: &mut StableHasher
) {
189 // `FloatVid` values are confined to an inference context and hence
190 // should not be hashed.
191 bug
!("ty::TyKind::hash_stable() - can't hash a FloatVid {:?}.", *self)
195 impl<'a
, T
> HashStable
<StableHashingContext
<'a
>> for ty
::steal
::Steal
<T
>
197 T
: HashStable
<StableHashingContext
<'a
>>,
199 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
200 self.borrow().hash_stable(hcx
, hasher
);
204 impl<'a
> HashStable
<StableHashingContext
<'a
>>
205 for crate::middle
::privacy
::AccessLevels
{
206 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
207 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
208 let crate::middle
::privacy
::AccessLevels
{
212 map
.hash_stable(hcx
, hasher
);