1 //! This module contains `HashStable` implementations for various HIR data
2 //! types in no particular order.
4 use crate::ich
::{NodeIdHashingMode, StableHashingContext}
;
5 use rustc_attr
as attr
;
6 use rustc_data_structures
::fingerprint
::Fingerprint
;
7 use rustc_data_structures
::stable_hasher
::{HashStable, StableHasher, ToStableHashKey}
;
9 use rustc_hir
::def_id
::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX}
;
10 use rustc_hir
::definitions
::DefPathHash
;
11 use smallvec
::SmallVec
;
14 impl<'ctx
> rustc_hir
::HashStableContext
for StableHashingContext
<'ctx
> {
16 fn hash_hir_id(&mut self, hir_id
: hir
::HirId
, hasher
: &mut StableHasher
) {
18 match hcx
.node_id_hashing_mode
{
19 NodeIdHashingMode
::Ignore
=> {
22 NodeIdHashingMode
::HashDefPath
=> {
23 let hir
::HirId { owner, local_id }
= hir_id
;
25 hcx
.local_def_path_hash(owner
).hash_stable(hcx
, hasher
);
26 local_id
.hash_stable(hcx
, hasher
);
31 fn hash_body_id(&mut self, id
: hir
::BodyId
, hasher
: &mut StableHasher
) {
33 if hcx
.hash_bodies() {
34 hcx
.body_resolver
.body(id
).hash_stable(hcx
, hasher
);
38 fn hash_reference_to_item(&mut self, id
: hir
::HirId
, hasher
: &mut StableHasher
) {
41 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
42 id
.hash_stable(hcx
, hasher
);
46 fn hash_hir_mod(&mut self, module
: &hir
::Mod
<'_
>, hasher
: &mut StableHasher
) {
48 let hir
::Mod { inner: ref inner_span, ref item_ids }
= *module
;
50 inner_span
.hash_stable(hcx
, hasher
);
52 // Combining the `DefPathHash`s directly is faster than feeding them
53 // into the hasher. Because we use a commutative combine, we also don't
54 // have to sort the array.
55 let item_ids_hash
= item_ids
58 let def_path_hash
= id
.to_stable_hash_key(hcx
);
61 .fold(Fingerprint
::ZERO
, |a
, b
| a
.combine_commutative(b
));
63 item_ids
.len().hash_stable(hcx
, hasher
);
64 item_ids_hash
.hash_stable(hcx
, hasher
);
67 fn hash_hir_expr(&mut self, expr
: &hir
::Expr
<'_
>, hasher
: &mut StableHasher
) {
68 self.while_hashing_hir_bodies(true, |hcx
| {
69 let hir
::Expr { hir_id: _, ref span, ref kind }
= *expr
;
71 span
.hash_stable(hcx
, hasher
);
72 kind
.hash_stable(hcx
, hasher
);
76 fn hash_hir_ty(&mut self, ty
: &hir
::Ty
<'_
>, hasher
: &mut StableHasher
) {
77 self.while_hashing_hir_bodies(true, |hcx
| {
78 let hir
::Ty { hir_id: _, ref kind, ref span }
= *ty
;
80 kind
.hash_stable(hcx
, hasher
);
81 span
.hash_stable(hcx
, hasher
);
85 fn hash_hir_visibility_kind(
87 vis
: &hir
::VisibilityKind
<'_
>,
88 hasher
: &mut StableHasher
,
91 mem
::discriminant(vis
).hash_stable(hcx
, hasher
);
93 hir
::VisibilityKind
::Public
| hir
::VisibilityKind
::Inherited
=> {
96 hir
::VisibilityKind
::Crate(sugar
) => {
97 sugar
.hash_stable(hcx
, hasher
);
99 hir
::VisibilityKind
::Restricted { ref path, hir_id }
=> {
100 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
101 hir_id
.hash_stable(hcx
, hasher
);
103 path
.hash_stable(hcx
, hasher
);
108 fn hash_hir_item_like
<F
: FnOnce(&mut Self)>(&mut self, f
: F
) {
109 let prev_hash_node_ids
= self.node_id_hashing_mode
;
110 self.node_id_hashing_mode
= NodeIdHashingMode
::Ignore
;
114 self.node_id_hashing_mode
= prev_hash_node_ids
;
118 fn local_def_path_hash(&self, def_id
: LocalDefId
) -> DefPathHash
{
119 self.local_def_path_hash(def_id
)
123 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for DefId
{
124 type KeyType
= DefPathHash
;
127 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> DefPathHash
{
128 hcx
.def_path_hash(*self)
132 impl<'a
> HashStable
<StableHashingContext
<'a
>> for LocalDefId
{
134 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
135 hcx
.def_path_hash(self.to_def_id()).hash_stable(hcx
, hasher
);
139 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for LocalDefId
{
140 type KeyType
= DefPathHash
;
143 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> DefPathHash
{
144 hcx
.def_path_hash(self.to_def_id())
148 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for CrateNum
{
149 type KeyType
= DefPathHash
;
152 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> DefPathHash
{
153 let def_id
= DefId { krate: *self, index: CRATE_DEF_INDEX }
;
154 def_id
.to_stable_hash_key(hcx
)
158 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for hir
::ItemLocalId
{
159 type KeyType
= hir
::ItemLocalId
;
162 fn to_stable_hash_key(&self, _
: &StableHashingContext
<'a
>) -> hir
::ItemLocalId
{
167 impl<'a
> HashStable
<StableHashingContext
<'a
>> for hir
::Body
<'_
> {
168 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
169 let hir
::Body { params, value, generator_kind }
= self;
171 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::Ignore
, |hcx
| {
172 params
.hash_stable(hcx
, hasher
);
173 value
.hash_stable(hcx
, hasher
);
174 generator_kind
.hash_stable(hcx
, hasher
);
179 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for hir
::BodyId
{
180 type KeyType
= (DefPathHash
, hir
::ItemLocalId
);
183 fn to_stable_hash_key(
185 hcx
: &StableHashingContext
<'a
>,
186 ) -> (DefPathHash
, hir
::ItemLocalId
) {
187 let hir
::BodyId { hir_id }
= *self;
188 hir_id
.to_stable_hash_key(hcx
)
192 impl<'a
> HashStable
<StableHashingContext
<'a
>> for hir
::TraitCandidate
{
193 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
194 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
195 let hir
::TraitCandidate { def_id, import_ids }
= self;
197 def_id
.hash_stable(hcx
, hasher
);
198 import_ids
.hash_stable(hcx
, hasher
);
203 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for hir
::TraitCandidate
{
204 type KeyType
= (DefPathHash
, SmallVec
<[DefPathHash
; 1]>);
206 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> Self::KeyType
{
207 let hir
::TraitCandidate { def_id, import_ids }
= self;
210 hcx
.def_path_hash(*def_id
),
211 import_ids
.iter().map(|def_id
| hcx
.local_def_path_hash(*def_id
)).collect(),
216 impl<'hir
> HashStable
<StableHashingContext
<'hir
>> for attr
::InlineAttr
{
217 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'hir
>, hasher
: &mut StableHasher
) {
218 mem
::discriminant(self).hash_stable(hcx
, hasher
);
222 impl<'hir
> HashStable
<StableHashingContext
<'hir
>> for attr
::InstructionSetAttr
{
223 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'hir
>, hasher
: &mut StableHasher
) {
224 mem
::discriminant(self).hash_stable(hcx
, hasher
);
228 impl<'hir
> HashStable
<StableHashingContext
<'hir
>> for attr
::OptimizeAttr
{
229 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'hir
>, hasher
: &mut StableHasher
) {
230 mem
::discriminant(self).hash_stable(hcx
, hasher
);