1 //! This module contains `HashStable` implementations for various HIR data
2 //! types in no particular order.
4 use crate::hir
::map
::DefPathHash
;
5 use crate::ich
::{Fingerprint, NodeIdHashingMode, StableHashingContext}
;
6 use rustc_attr
as attr
;
7 use rustc_data_structures
::stable_hasher
::{HashStable, StableHasher, ToStableHashKey}
;
9 use rustc_hir
::def_id
::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX}
;
10 use smallvec
::SmallVec
;
13 impl<'ctx
> rustc_hir
::HashStableContext
for StableHashingContext
<'ctx
> {
15 fn hash_hir_id(&mut self, hir_id
: hir
::HirId
, hasher
: &mut StableHasher
) {
17 match hcx
.node_id_hashing_mode
{
18 NodeIdHashingMode
::Ignore
=> {
21 NodeIdHashingMode
::HashDefPath
=> {
22 let hir
::HirId { owner, local_id }
= hir_id
;
24 hcx
.local_def_path_hash(owner
).hash_stable(hcx
, hasher
);
25 local_id
.hash_stable(hcx
, hasher
);
30 fn hash_body_id(&mut self, id
: hir
::BodyId
, hasher
: &mut StableHasher
) {
32 if hcx
.hash_bodies() {
33 hcx
.body_resolver
.body(id
).hash_stable(hcx
, hasher
);
37 fn hash_reference_to_item(&mut self, id
: hir
::HirId
, hasher
: &mut StableHasher
) {
40 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
41 id
.hash_stable(hcx
, hasher
);
45 fn hash_hir_mod(&mut self, module
: &hir
::Mod
<'_
>, hasher
: &mut StableHasher
) {
47 let hir
::Mod { inner: ref inner_span, ref item_ids }
= *module
;
49 inner_span
.hash_stable(hcx
, hasher
);
51 // Combining the `DefPathHash`s directly is faster than feeding them
52 // into the hasher. Because we use a commutative combine, we also don't
53 // have to sort the array.
54 let item_ids_hash
= item_ids
57 let (def_path_hash
, local_id
) = id
.id
.to_stable_hash_key(hcx
);
58 debug_assert_eq
!(local_id
, hir
::ItemLocalId
::from_u32(0));
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, ref attrs }
= *expr
;
71 span
.hash_stable(hcx
, hasher
);
72 kind
.hash_stable(hcx
, hasher
);
73 attrs
.hash_stable(hcx
, hasher
);
77 fn hash_hir_ty(&mut self, ty
: &hir
::Ty
<'_
>, hasher
: &mut StableHasher
) {
78 self.while_hashing_hir_bodies(true, |hcx
| {
79 let hir
::Ty { hir_id: _, ref kind, ref span }
= *ty
;
81 kind
.hash_stable(hcx
, hasher
);
82 span
.hash_stable(hcx
, hasher
);
86 fn hash_hir_visibility_kind(
88 vis
: &hir
::VisibilityKind
<'_
>,
89 hasher
: &mut StableHasher
,
92 mem
::discriminant(vis
).hash_stable(hcx
, hasher
);
94 hir
::VisibilityKind
::Public
| hir
::VisibilityKind
::Inherited
=> {
97 hir
::VisibilityKind
::Crate(sugar
) => {
98 sugar
.hash_stable(hcx
, hasher
);
100 hir
::VisibilityKind
::Restricted { ref path, hir_id }
=> {
101 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
102 hir_id
.hash_stable(hcx
, hasher
);
104 path
.hash_stable(hcx
, hasher
);
110 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for DefId
{
111 type KeyType
= DefPathHash
;
114 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> DefPathHash
{
115 hcx
.def_path_hash(*self)
119 impl<'a
> HashStable
<StableHashingContext
<'a
>> for LocalDefId
{
121 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
122 hcx
.def_path_hash(self.to_def_id()).hash_stable(hcx
, hasher
);
126 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for LocalDefId
{
127 type KeyType
= DefPathHash
;
130 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> DefPathHash
{
131 hcx
.def_path_hash(self.to_def_id())
135 impl<'a
> HashStable
<StableHashingContext
<'a
>> for CrateNum
{
137 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
138 hcx
.def_path_hash(DefId { krate: *self, index: CRATE_DEF_INDEX }
).hash_stable(hcx
, hasher
);
142 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for CrateNum
{
143 type KeyType
= DefPathHash
;
146 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> DefPathHash
{
147 let def_id
= DefId { krate: *self, index: CRATE_DEF_INDEX }
;
148 def_id
.to_stable_hash_key(hcx
)
152 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for hir
::ItemLocalId
{
153 type KeyType
= hir
::ItemLocalId
;
156 fn to_stable_hash_key(&self, _
: &StableHashingContext
<'a
>) -> hir
::ItemLocalId
{
161 impl<'a
> HashStable
<StableHashingContext
<'a
>> for hir
::TraitItem
<'_
> {
162 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
163 let hir
::TraitItem { hir_id: _, ident, ref attrs, ref generics, ref kind, span }
= *self;
165 hcx
.hash_hir_item_like(|hcx
| {
166 ident
.name
.hash_stable(hcx
, hasher
);
167 attrs
.hash_stable(hcx
, hasher
);
168 generics
.hash_stable(hcx
, hasher
);
169 kind
.hash_stable(hcx
, hasher
);
170 span
.hash_stable(hcx
, hasher
);
175 impl<'a
> HashStable
<StableHashingContext
<'a
>> for hir
::ImplItem
<'_
> {
176 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
188 hcx
.hash_hir_item_like(|hcx
| {
189 ident
.name
.hash_stable(hcx
, hasher
);
190 vis
.hash_stable(hcx
, hasher
);
191 defaultness
.hash_stable(hcx
, hasher
);
192 attrs
.hash_stable(hcx
, hasher
);
193 generics
.hash_stable(hcx
, hasher
);
194 kind
.hash_stable(hcx
, hasher
);
195 span
.hash_stable(hcx
, hasher
);
200 impl<'a
> HashStable
<StableHashingContext
<'a
>> for hir
::Item
<'_
> {
201 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
202 let hir
::Item { ident, ref attrs, hir_id: _, ref kind, ref vis, span }
= *self;
204 hcx
.hash_hir_item_like(|hcx
| {
205 ident
.name
.hash_stable(hcx
, hasher
);
206 attrs
.hash_stable(hcx
, hasher
);
207 kind
.hash_stable(hcx
, hasher
);
208 vis
.hash_stable(hcx
, hasher
);
209 span
.hash_stable(hcx
, hasher
);
214 impl<'a
> HashStable
<StableHashingContext
<'a
>> for hir
::Body
<'_
> {
215 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
216 let hir
::Body { params, value, generator_kind }
= self;
218 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::Ignore
, |hcx
| {
219 params
.hash_stable(hcx
, hasher
);
220 value
.hash_stable(hcx
, hasher
);
221 generator_kind
.hash_stable(hcx
, hasher
);
226 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for hir
::BodyId
{
227 type KeyType
= (DefPathHash
, hir
::ItemLocalId
);
230 fn to_stable_hash_key(
232 hcx
: &StableHashingContext
<'a
>,
233 ) -> (DefPathHash
, hir
::ItemLocalId
) {
234 let hir
::BodyId { hir_id }
= *self;
235 hir_id
.to_stable_hash_key(hcx
)
239 impl<'a
> HashStable
<StableHashingContext
<'a
>> for hir
::def_id
::DefIndex
{
240 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
241 hcx
.local_def_path_hash(*self).hash_stable(hcx
, hasher
);
245 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for hir
::def_id
::DefIndex
{
246 type KeyType
= DefPathHash
;
249 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> DefPathHash
{
250 hcx
.local_def_path_hash(*self)
254 impl<'a
> HashStable
<StableHashingContext
<'a
>> for hir
::TraitCandidate
{
255 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
256 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
257 let hir
::TraitCandidate { def_id, import_ids }
= self;
259 def_id
.hash_stable(hcx
, hasher
);
260 import_ids
.hash_stable(hcx
, hasher
);
265 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for hir
::TraitCandidate
{
266 type KeyType
= (DefPathHash
, SmallVec
<[(DefPathHash
, hir
::ItemLocalId
); 1]>);
268 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> Self::KeyType
{
269 let hir
::TraitCandidate { def_id, import_ids }
= self;
271 let import_keys
= import_ids
273 .map(|hir_id
| (hcx
.local_def_path_hash(hir_id
.owner
), hir_id
.local_id
))
275 (hcx
.def_path_hash(*def_id
), import_keys
)
279 impl<'hir
> HashStable
<StableHashingContext
<'hir
>> for attr
::InlineAttr
{
280 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'hir
>, hasher
: &mut StableHasher
) {
281 mem
::discriminant(self).hash_stable(hcx
, hasher
);
285 impl<'hir
> HashStable
<StableHashingContext
<'hir
>> for attr
::OptimizeAttr
{
286 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'hir
>, hasher
: &mut StableHasher
) {
287 mem
::discriminant(self).hash_stable(hcx
, hasher
);