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_data_structures
::stable_hasher
::{HashStable, StableHasher, ToStableHashKey}
;
8 use rustc_hir
::def_id
::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX}
;
9 use smallvec
::SmallVec
;
13 impl<'ctx
> rustc_hir
::HashStableContext
for StableHashingContext
<'ctx
> {
15 fn hash_def_id(&mut self, def_id
: DefId
, hasher
: &mut StableHasher
) {
17 hcx
.def_path_hash(def_id
).hash_stable(hcx
, hasher
);
21 fn hash_hir_id(&mut self, hir_id
: hir
::HirId
, hasher
: &mut StableHasher
) {
23 match hcx
.node_id_hashing_mode
{
24 NodeIdHashingMode
::Ignore
=> {
27 NodeIdHashingMode
::HashDefPath
=> {
28 let hir
::HirId { owner, local_id }
= hir_id
;
30 hcx
.local_def_path_hash(owner
).hash_stable(hcx
, hasher
);
31 local_id
.hash_stable(hcx
, hasher
);
36 fn hash_body_id(&mut self, id
: hir
::BodyId
, hasher
: &mut StableHasher
) {
38 if hcx
.hash_bodies() {
39 hcx
.body_resolver
.body(id
).hash_stable(hcx
, hasher
);
43 // The following implementations of HashStable for `ItemId`, `TraitItemId`, and
44 // `ImplItemId` deserve special attention. Normally we do not hash `NodeId`s within
45 // the HIR, since they just signify a HIR nodes own path. But `ItemId` et al
46 // are used when another item in the HIR is *referenced* and we certainly
47 // want to pick up on a reference changing its target, so we hash the NodeIds
50 fn hash_item_id(&mut self, id
: hir
::ItemId
, hasher
: &mut StableHasher
) {
52 let hir
::ItemId { id }
= id
;
54 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
55 id
.hash_stable(hcx
, hasher
);
59 fn hash_impl_item_id(&mut self, id
: hir
::ImplItemId
, hasher
: &mut StableHasher
) {
61 let hir
::ImplItemId { hir_id }
= id
;
63 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
64 hir_id
.hash_stable(hcx
, hasher
);
68 fn hash_trait_item_id(&mut self, id
: hir
::TraitItemId
, hasher
: &mut StableHasher
) {
70 let hir
::TraitItemId { hir_id }
= id
;
72 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
73 hir_id
.hash_stable(hcx
, hasher
);
77 fn hash_hir_mod(&mut self, module
: &hir
::Mod
<'_
>, hasher
: &mut StableHasher
) {
79 let hir
::Mod { inner: ref inner_span, ref item_ids }
= *module
;
81 inner_span
.hash_stable(hcx
, hasher
);
83 // Combining the `DefPathHash`s directly is faster than feeding them
84 // into the hasher. Because we use a commutative combine, we also don't
85 // have to sort the array.
86 let item_ids_hash
= item_ids
89 let (def_path_hash
, local_id
) = id
.id
.to_stable_hash_key(hcx
);
90 debug_assert_eq
!(local_id
, hir
::ItemLocalId
::from_u32(0));
93 .fold(Fingerprint
::ZERO
, |a
, b
| a
.combine_commutative(b
));
95 item_ids
.len().hash_stable(hcx
, hasher
);
96 item_ids_hash
.hash_stable(hcx
, hasher
);
99 fn hash_hir_expr(&mut self, expr
: &hir
::Expr
<'_
>, hasher
: &mut StableHasher
) {
100 self.while_hashing_hir_bodies(true, |hcx
| {
101 let hir
::Expr { hir_id: _, ref span, ref kind, ref attrs }
= *expr
;
103 span
.hash_stable(hcx
, hasher
);
104 kind
.hash_stable(hcx
, hasher
);
105 attrs
.hash_stable(hcx
, hasher
);
109 fn hash_hir_ty(&mut self, ty
: &hir
::Ty
<'_
>, hasher
: &mut StableHasher
) {
110 self.while_hashing_hir_bodies(true, |hcx
| {
111 let hir
::Ty { hir_id: _, ref kind, ref span }
= *ty
;
113 kind
.hash_stable(hcx
, hasher
);
114 span
.hash_stable(hcx
, hasher
);
118 fn hash_hir_visibility_kind(
120 vis
: &hir
::VisibilityKind
<'_
>,
121 hasher
: &mut StableHasher
,
124 mem
::discriminant(vis
).hash_stable(hcx
, hasher
);
126 hir
::VisibilityKind
::Public
| hir
::VisibilityKind
::Inherited
=> {
127 // No fields to hash.
129 hir
::VisibilityKind
::Crate(sugar
) => {
130 sugar
.hash_stable(hcx
, hasher
);
132 hir
::VisibilityKind
::Restricted { ref path, hir_id }
=> {
133 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
134 hir_id
.hash_stable(hcx
, hasher
);
136 path
.hash_stable(hcx
, hasher
);
142 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for DefId
{
143 type KeyType
= DefPathHash
;
146 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> DefPathHash
{
147 hcx
.def_path_hash(*self)
151 impl<'a
> HashStable
<StableHashingContext
<'a
>> for LocalDefId
{
153 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
154 hcx
.def_path_hash(self.to_def_id()).hash_stable(hcx
, hasher
);
158 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for LocalDefId
{
159 type KeyType
= DefPathHash
;
162 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> DefPathHash
{
163 hcx
.def_path_hash(self.to_def_id())
167 impl<'a
> HashStable
<StableHashingContext
<'a
>> for CrateNum
{
169 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
170 hcx
.def_path_hash(DefId { krate: *self, index: CRATE_DEF_INDEX }
).hash_stable(hcx
, hasher
);
174 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for CrateNum
{
175 type KeyType
= DefPathHash
;
178 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> DefPathHash
{
179 let def_id
= DefId { krate: *self, index: CRATE_DEF_INDEX }
;
180 def_id
.to_stable_hash_key(hcx
)
184 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for hir
::ItemLocalId
{
185 type KeyType
= hir
::ItemLocalId
;
188 fn to_stable_hash_key(&self, _
: &StableHashingContext
<'a
>) -> hir
::ItemLocalId
{
193 impl<'a
> HashStable
<StableHashingContext
<'a
>> for hir
::TraitItem
<'_
> {
194 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
195 let hir
::TraitItem { hir_id: _, ident, ref attrs, ref generics, ref kind, span }
= *self;
197 hcx
.hash_hir_item_like(|hcx
| {
198 ident
.name
.hash_stable(hcx
, hasher
);
199 attrs
.hash_stable(hcx
, hasher
);
200 generics
.hash_stable(hcx
, hasher
);
201 kind
.hash_stable(hcx
, hasher
);
202 span
.hash_stable(hcx
, hasher
);
207 impl<'a
> HashStable
<StableHashingContext
<'a
>> for hir
::ImplItem
<'_
> {
208 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
220 hcx
.hash_hir_item_like(|hcx
| {
221 ident
.name
.hash_stable(hcx
, hasher
);
222 vis
.hash_stable(hcx
, hasher
);
223 defaultness
.hash_stable(hcx
, hasher
);
224 attrs
.hash_stable(hcx
, hasher
);
225 generics
.hash_stable(hcx
, hasher
);
226 kind
.hash_stable(hcx
, hasher
);
227 span
.hash_stable(hcx
, hasher
);
232 impl<'a
> HashStable
<StableHashingContext
<'a
>> for hir
::Item
<'_
> {
233 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
234 let hir
::Item { ident, ref attrs, hir_id: _, ref kind, ref vis, span }
= *self;
236 hcx
.hash_hir_item_like(|hcx
| {
237 ident
.name
.hash_stable(hcx
, hasher
);
238 attrs
.hash_stable(hcx
, hasher
);
239 kind
.hash_stable(hcx
, hasher
);
240 vis
.hash_stable(hcx
, hasher
);
241 span
.hash_stable(hcx
, hasher
);
246 impl<'a
> HashStable
<StableHashingContext
<'a
>> for hir
::Body
<'_
> {
247 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
248 let hir
::Body { params, value, generator_kind }
= self;
250 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::Ignore
, |hcx
| {
251 params
.hash_stable(hcx
, hasher
);
252 value
.hash_stable(hcx
, hasher
);
253 generator_kind
.hash_stable(hcx
, hasher
);
258 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for hir
::BodyId
{
259 type KeyType
= (DefPathHash
, hir
::ItemLocalId
);
262 fn to_stable_hash_key(
264 hcx
: &StableHashingContext
<'a
>,
265 ) -> (DefPathHash
, hir
::ItemLocalId
) {
266 let hir
::BodyId { hir_id }
= *self;
267 hir_id
.to_stable_hash_key(hcx
)
271 impl<'a
> HashStable
<StableHashingContext
<'a
>> for hir
::def_id
::DefIndex
{
272 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
273 hcx
.local_def_path_hash(*self).hash_stable(hcx
, hasher
);
277 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for hir
::def_id
::DefIndex
{
278 type KeyType
= DefPathHash
;
281 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> DefPathHash
{
282 hcx
.local_def_path_hash(*self)
286 impl<'a
> HashStable
<StableHashingContext
<'a
>> for crate::middle
::lang_items
::LangItem
{
287 fn hash_stable(&self, _
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
288 ::std
::hash
::Hash
::hash(self, hasher
);
292 impl<'a
> HashStable
<StableHashingContext
<'a
>> for hir
::TraitCandidate
{
293 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
294 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
295 let hir
::TraitCandidate { def_id, import_ids }
= self;
297 def_id
.hash_stable(hcx
, hasher
);
298 import_ids
.hash_stable(hcx
, hasher
);
303 impl<'a
> ToStableHashKey
<StableHashingContext
<'a
>> for hir
::TraitCandidate
{
304 type KeyType
= (DefPathHash
, SmallVec
<[(DefPathHash
, hir
::ItemLocalId
); 1]>);
306 fn to_stable_hash_key(&self, hcx
: &StableHashingContext
<'a
>) -> Self::KeyType
{
307 let hir
::TraitCandidate { def_id, import_ids }
= self;
309 let import_keys
= import_ids
311 .map(|node_id
| hcx
.node_to_hir_id(*node_id
))
312 .map(|hir_id
| (hcx
.local_def_path_hash(hir_id
.owner
), hir_id
.local_id
))
314 (hcx
.def_path_hash(*def_id
), import_keys
)
318 impl<'hir
> HashStable
<StableHashingContext
<'hir
>> for attr
::InlineAttr
{
319 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'hir
>, hasher
: &mut StableHasher
) {
320 mem
::discriminant(self).hash_stable(hcx
, hasher
);
324 impl<'hir
> HashStable
<StableHashingContext
<'hir
>> for attr
::OptimizeAttr
{
325 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'hir
>, hasher
: &mut StableHasher
) {
326 mem
::discriminant(self).hash_stable(hcx
, hasher
);