]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_query_system/src/ich/impls_hir.rs
Auto merge of #89343 - Mark-Simulacrum:no-args-queries, r=cjgillot
[rust.git] / compiler / rustc_query_system / src / ich / impls_hir.rs
1 //! This module contains `HashStable` implementations for various HIR data
2 //! types in no particular order.
3
4 use crate::ich::{NodeIdHashingMode, StableHashingContext};
5 use rustc_data_structures::fingerprint::Fingerprint;
6 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
7 use rustc_hir as hir;
8 use rustc_hir::definitions::DefPathHash;
9 use smallvec::SmallVec;
10 use std::mem;
11
12 impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
13     #[inline]
14     fn hash_hir_id(&mut self, hir_id: hir::HirId, hasher: &mut StableHasher) {
15         let hcx = self;
16         match hcx.node_id_hashing_mode {
17             NodeIdHashingMode::Ignore => {
18                 // Don't do anything.
19             }
20             NodeIdHashingMode::HashDefPath => {
21                 let hir::HirId { owner, local_id } = hir_id;
22
23                 hcx.local_def_path_hash(owner).hash_stable(hcx, hasher);
24                 local_id.hash_stable(hcx, hasher);
25             }
26         }
27     }
28
29     #[inline]
30     fn hash_body_id(&mut self, id: hir::BodyId, hasher: &mut StableHasher) {
31         let hcx = self;
32         if hcx.hash_bodies() {
33             hcx.body_resolver.body(id).hash_stable(hcx, hasher);
34         }
35     }
36
37     #[inline]
38     fn hash_reference_to_item(&mut self, id: hir::HirId, hasher: &mut StableHasher) {
39         let hcx = self;
40
41         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
42             id.hash_stable(hcx, hasher);
43         })
44     }
45
46     #[inline]
47     fn hash_hir_mod(&mut self, module: &hir::Mod<'_>, hasher: &mut StableHasher) {
48         let hcx = self;
49         let hir::Mod { inner: ref inner_span, ref item_ids } = *module;
50
51         inner_span.hash_stable(hcx, hasher);
52
53         // Combining the `DefPathHash`s directly is faster than feeding them
54         // into the hasher. Because we use a commutative combine, we also don't
55         // have to sort the array.
56         let item_ids_hash = item_ids
57             .iter()
58             .map(|id| {
59                 let def_path_hash = id.to_stable_hash_key(hcx);
60                 def_path_hash.0
61             })
62             .fold(Fingerprint::ZERO, |a, b| a.combine_commutative(b));
63
64         item_ids.len().hash_stable(hcx, hasher);
65         item_ids_hash.hash_stable(hcx, hasher);
66     }
67
68     fn hash_hir_expr(&mut self, expr: &hir::Expr<'_>, hasher: &mut StableHasher) {
69         self.while_hashing_hir_bodies(true, |hcx| {
70             let hir::Expr { hir_id: _, ref span, ref kind } = *expr;
71
72             span.hash_stable(hcx, hasher);
73             kind.hash_stable(hcx, hasher);
74         })
75     }
76
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;
80
81             kind.hash_stable(hcx, hasher);
82             span.hash_stable(hcx, hasher);
83         })
84     }
85
86     fn hash_hir_visibility_kind(
87         &mut self,
88         vis: &hir::VisibilityKind<'_>,
89         hasher: &mut StableHasher,
90     ) {
91         let hcx = self;
92         mem::discriminant(vis).hash_stable(hcx, hasher);
93         match *vis {
94             hir::VisibilityKind::Public | hir::VisibilityKind::Inherited => {
95                 // No fields to hash.
96             }
97             hir::VisibilityKind::Crate(sugar) => {
98                 sugar.hash_stable(hcx, hasher);
99             }
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);
103                 });
104                 path.hash_stable(hcx, hasher);
105             }
106         }
107     }
108
109     #[inline]
110     fn hash_hir_item_like<F: FnOnce(&mut Self)>(&mut self, f: F) {
111         let prev_hash_node_ids = self.node_id_hashing_mode;
112         self.node_id_hashing_mode = NodeIdHashingMode::Ignore;
113
114         f(self);
115
116         self.node_id_hashing_mode = prev_hash_node_ids;
117     }
118 }
119
120 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body<'_> {
121     #[inline]
122     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
123         let hir::Body { params, value, generator_kind } = self;
124
125         hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
126             params.hash_stable(hcx, hasher);
127             value.hash_stable(hcx, hasher);
128             generator_kind.hash_stable(hcx, hasher);
129         });
130     }
131 }
132
133 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
134     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
135         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
136             let hir::TraitCandidate { def_id, import_ids } = self;
137
138             def_id.hash_stable(hcx, hasher);
139             import_ids.hash_stable(hcx, hasher);
140         });
141     }
142 }
143
144 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
145     type KeyType = (DefPathHash, SmallVec<[DefPathHash; 1]>);
146
147     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Self::KeyType {
148         let hir::TraitCandidate { def_id, import_ids } = self;
149
150         (
151             hcx.def_path_hash(*def_id),
152             import_ids.iter().map(|def_id| hcx.local_def_path_hash(*def_id)).collect(),
153         )
154     }
155 }