1 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
4 AttributeMap, BodyId, Crate, Expr, ForeignItemId, ImplItemId, ItemId, OwnerNodes, TraitItemId,
7 use crate::hir_id::{HirId, ItemLocalId};
8 use rustc_span::def_id::DefPathHash;
10 /// Requirements for a `StableHashingContext` to be used in this crate.
11 /// This is a hack to allow using the `HashStable_Generic` derive macro
12 /// instead of implementing everything in `rustc_middle`.
13 pub trait HashStableContext:
14 rustc_ast::HashStableContext + rustc_target::HashStableContext
16 fn hash_body_id(&mut self, _: BodyId, hasher: &mut StableHasher);
17 fn hash_hir_expr(&mut self, _: &Expr<'_>, hasher: &mut StableHasher);
18 fn hash_hir_ty(&mut self, _: &Ty<'_>, hasher: &mut StableHasher);
21 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for HirId {
22 type KeyType = (DefPathHash, ItemLocalId);
25 fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) {
26 let def_path_hash = self.owner.to_stable_hash_key(hcx);
27 (def_path_hash, self.local_id)
31 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ItemLocalId {
32 type KeyType = ItemLocalId;
35 fn to_stable_hash_key(&self, _: &HirCtx) -> ItemLocalId {
40 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for BodyId {
41 type KeyType = (DefPathHash, ItemLocalId);
44 fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) {
45 let BodyId { hir_id } = *self;
46 hir_id.to_stable_hash_key(hcx)
50 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ItemId {
51 type KeyType = DefPathHash;
54 fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
55 self.def_id.to_stable_hash_key(hcx)
59 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for TraitItemId {
60 type KeyType = DefPathHash;
63 fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
64 self.def_id.to_stable_hash_key(hcx)
68 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ImplItemId {
69 type KeyType = DefPathHash;
72 fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
73 self.def_id.to_stable_hash_key(hcx)
77 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ForeignItemId {
78 type KeyType = DefPathHash;
81 fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
82 self.def_id.to_stable_hash_key(hcx)
86 impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for BodyId {
87 fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
88 hcx.hash_body_id(*self, hasher)
92 // The following implementations of HashStable for `ItemId`, `TraitItemId`, and
93 // `ImplItemId` deserve special attention. Normally we do not hash `NodeId`s within
94 // the HIR, since they just signify a HIR nodes own path. But `ItemId` et al
95 // are used when another item in the HIR is *referenced* and we certainly
96 // want to pick up on a reference changing its target, so we hash the NodeIds
99 impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Expr<'_> {
100 fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
101 hcx.hash_hir_expr(self, hasher)
105 impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Ty<'_> {
106 fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
107 hcx.hash_hir_ty(self, hasher)
111 impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for OwnerNodes<'tcx> {
112 fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
113 // We ignore the `nodes` and `bodies` fields since these refer to information included in
114 // `hash` which is hashed in the collector and used for the crate hash.
115 // `local_id_to_def_id` is also ignored because is dependent on the body, then just hashing
116 // the body satisfies the condition of two nodes being different have different
117 // `hash_stable` results.
119 hash_including_bodies,
120 hash_without_bodies: _,
123 local_id_to_def_id: _,
125 hash_including_bodies.hash_stable(hcx, hasher);
129 impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for AttributeMap<'tcx> {
130 fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
131 // We ignore the `map` since it refers to information included in `hash` which is hashed in
132 // the collector and used for the crate hash.
133 let AttributeMap { hash, map: _ } = *self;
134 hash.hash_stable(hcx, hasher);
138 impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Crate<'_> {
139 fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
140 let Crate { owners: _, hir_hash } = self;
141 hir_hash.hash_stable(hcx, hasher)