1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! This module contains `HashStable` implementations for various MIR data
12 //! types in no particular order.
14 use ich::StableHashingContext;
16 use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
21 impl_stable_hash_for!(struct mir::SourceInfo { span, scope });
22 impl_stable_hash_for!(enum mir::Mutability { Mut, Not });
23 impl_stable_hash_for!(enum mir::BorrowKind { Shared, Unique, Mut });
24 impl_stable_hash_for!(enum mir::LocalKind { Var, Temp, Arg, ReturnPointer });
25 impl_stable_hash_for!(struct mir::LocalDecl<'tcx> { mutability, ty, name, source_info });
26 impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref });
27 impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
28 impl_stable_hash_for!(struct mir::Terminator<'tcx> { source_info, kind });
30 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Local {
32 fn hash_stable<W: StableHasherResult>(&self,
33 hcx: &mut StableHashingContext<'a, 'tcx>,
34 hasher: &mut StableHasher<W>) {
35 use rustc_data_structures::indexed_vec::Idx;
36 self.index().hash_stable(hcx, hasher);
40 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::BasicBlock {
42 fn hash_stable<W: StableHasherResult>(&self,
43 hcx: &mut StableHashingContext<'a, 'tcx>,
44 hasher: &mut StableHasher<W>) {
45 use rustc_data_structures::indexed_vec::Idx;
46 self.index().hash_stable(hcx, hasher);
50 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Field {
52 fn hash_stable<W: StableHasherResult>(&self,
53 hcx: &mut StableHashingContext<'a, 'tcx>,
54 hasher: &mut StableHasher<W>) {
55 use rustc_data_structures::indexed_vec::Idx;
56 self.index().hash_stable(hcx, hasher);
60 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::VisibilityScope {
62 fn hash_stable<W: StableHasherResult>(&self,
63 hcx: &mut StableHashingContext<'a, 'tcx>,
64 hasher: &mut StableHasher<W>) {
65 use rustc_data_structures::indexed_vec::Idx;
66 self.index().hash_stable(hcx, hasher);
70 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Promoted {
72 fn hash_stable<W: StableHasherResult>(&self,
73 hcx: &mut StableHashingContext<'a, 'tcx>,
74 hasher: &mut StableHasher<W>) {
75 use rustc_data_structures::indexed_vec::Idx;
76 self.index().hash_stable(hcx, hasher);
80 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::TerminatorKind<'tcx> {
81 fn hash_stable<W: StableHasherResult>(&self,
82 hcx: &mut StableHashingContext<'a, 'tcx>,
83 hasher: &mut StableHasher<W>) {
84 mem::discriminant(self).hash_stable(hcx, hasher);
87 mir::TerminatorKind::Goto { ref target } => {
88 target.hash_stable(hcx, hasher);
90 mir::TerminatorKind::SwitchInt { ref discr,
94 discr.hash_stable(hcx, hasher);
95 switch_ty.hash_stable(hcx, hasher);
96 values.hash_stable(hcx, hasher);
97 targets.hash_stable(hcx, hasher);
99 mir::TerminatorKind::Resume |
100 mir::TerminatorKind::Return |
101 mir::TerminatorKind::Unreachable => {}
102 mir::TerminatorKind::Drop { ref location, target, unwind } => {
103 location.hash_stable(hcx, hasher);
104 target.hash_stable(hcx, hasher);
105 unwind.hash_stable(hcx, hasher);
107 mir::TerminatorKind::DropAndReplace { ref location,
111 location.hash_stable(hcx, hasher);
112 value.hash_stable(hcx, hasher);
113 target.hash_stable(hcx, hasher);
114 unwind.hash_stable(hcx, hasher);
116 mir::TerminatorKind::Call { ref func,
120 func.hash_stable(hcx, hasher);
121 args.hash_stable(hcx, hasher);
122 destination.hash_stable(hcx, hasher);
123 cleanup.hash_stable(hcx, hasher);
125 mir::TerminatorKind::Assert { ref cond,
130 cond.hash_stable(hcx, hasher);
131 expected.hash_stable(hcx, hasher);
132 msg.hash_stable(hcx, hasher);
133 target.hash_stable(hcx, hasher);
134 cleanup.hash_stable(hcx, hasher);
140 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::AssertMessage<'tcx> {
141 fn hash_stable<W: StableHasherResult>(&self,
142 hcx: &mut StableHashingContext<'a, 'tcx>,
143 hasher: &mut StableHasher<W>) {
144 mem::discriminant(self).hash_stable(hcx, hasher);
147 mir::AssertMessage::BoundsCheck { ref len, ref index } => {
148 len.hash_stable(hcx, hasher);
149 index.hash_stable(hcx, hasher);
151 mir::AssertMessage::Math(ref const_math_err) => {
152 const_math_err.hash_stable(hcx, hasher);
158 impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
160 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::StatementKind<'tcx> {
161 fn hash_stable<W: StableHasherResult>(&self,
162 hcx: &mut StableHashingContext<'a, 'tcx>,
163 hasher: &mut StableHasher<W>) {
164 mem::discriminant(self).hash_stable(hcx, hasher);
167 mir::StatementKind::Assign(ref lvalue, ref rvalue) => {
168 lvalue.hash_stable(hcx, hasher);
169 rvalue.hash_stable(hcx, hasher);
171 mir::StatementKind::SetDiscriminant { ref lvalue, variant_index } => {
172 lvalue.hash_stable(hcx, hasher);
173 variant_index.hash_stable(hcx, hasher);
175 mir::StatementKind::StorageLive(ref lvalue) |
176 mir::StatementKind::StorageDead(ref lvalue) => {
177 lvalue.hash_stable(hcx, hasher);
179 mir::StatementKind::Nop => {}
180 mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
181 asm.hash_stable(hcx, hasher);
182 outputs.hash_stable(hcx, hasher);
183 inputs.hash_stable(hcx, hasher);
189 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Lvalue<'tcx> {
190 fn hash_stable<W: StableHasherResult>(&self,
191 hcx: &mut StableHashingContext<'a, 'tcx>,
192 hasher: &mut StableHasher<W>) {
193 mem::discriminant(self).hash_stable(hcx, hasher);
195 mir::Lvalue::Local(ref local) => {
196 local.hash_stable(hcx, hasher);
198 mir::Lvalue::Static(ref statik) => {
199 statik.hash_stable(hcx, hasher);
201 mir::Lvalue::Projection(ref lvalue_projection) => {
202 lvalue_projection.hash_stable(hcx, hasher);
208 impl<'a, 'tcx, B, V> HashStable<StableHashingContext<'a, 'tcx>> for mir::Projection<'tcx, B, V>
209 where B: HashStable<StableHashingContext<'a, 'tcx>>,
210 V: HashStable<StableHashingContext<'a, 'tcx>>
212 fn hash_stable<W: StableHasherResult>(&self,
213 hcx: &mut StableHashingContext<'a, 'tcx>,
214 hasher: &mut StableHasher<W>) {
215 let mir::Projection {
220 base.hash_stable(hcx, hasher);
221 elem.hash_stable(hcx, hasher);
225 impl<'a, 'tcx, V> HashStable<StableHashingContext<'a, 'tcx>> for mir::ProjectionElem<'tcx, V>
226 where V: HashStable<StableHashingContext<'a, 'tcx>>
228 fn hash_stable<W: StableHasherResult>(&self,
229 hcx: &mut StableHashingContext<'a, 'tcx>,
230 hasher: &mut StableHasher<W>) {
231 mem::discriminant(self).hash_stable(hcx, hasher);
233 mir::ProjectionElem::Deref => {}
234 mir::ProjectionElem::Field(field, ty) => {
235 field.hash_stable(hcx, hasher);
236 ty.hash_stable(hcx, hasher);
238 mir::ProjectionElem::Index(ref value) => {
239 value.hash_stable(hcx, hasher);
241 mir::ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
242 offset.hash_stable(hcx, hasher);
243 min_length.hash_stable(hcx, hasher);
244 from_end.hash_stable(hcx, hasher);
246 mir::ProjectionElem::Subslice { from, to } => {
247 from.hash_stable(hcx, hasher);
248 to.hash_stable(hcx, hasher);
250 mir::ProjectionElem::Downcast(adt_def, variant) => {
251 adt_def.hash_stable(hcx, hasher);
252 variant.hash_stable(hcx, hasher);
258 impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope });
260 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Operand<'tcx> {
261 fn hash_stable<W: StableHasherResult>(&self,
262 hcx: &mut StableHashingContext<'a, 'tcx>,
263 hasher: &mut StableHasher<W>) {
264 mem::discriminant(self).hash_stable(hcx, hasher);
267 mir::Operand::Consume(ref lvalue) => {
268 lvalue.hash_stable(hcx, hasher);
270 mir::Operand::Constant(ref constant) => {
271 constant.hash_stable(hcx, hasher);
277 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Rvalue<'tcx> {
278 fn hash_stable<W: StableHasherResult>(&self,
279 hcx: &mut StableHashingContext<'a, 'tcx>,
280 hasher: &mut StableHasher<W>) {
281 mem::discriminant(self).hash_stable(hcx, hasher);
284 mir::Rvalue::Use(ref operand) => {
285 operand.hash_stable(hcx, hasher);
287 mir::Rvalue::Repeat(ref operand, ref val) => {
288 operand.hash_stable(hcx, hasher);
289 val.hash_stable(hcx, hasher);
291 mir::Rvalue::Ref(region, borrow_kind, ref lvalue) => {
292 region.hash_stable(hcx, hasher);
293 borrow_kind.hash_stable(hcx, hasher);
294 lvalue.hash_stable(hcx, hasher);
296 mir::Rvalue::Len(ref lvalue) => {
297 lvalue.hash_stable(hcx, hasher);
299 mir::Rvalue::Cast(cast_kind, ref operand, ty) => {
300 cast_kind.hash_stable(hcx, hasher);
301 operand.hash_stable(hcx, hasher);
302 ty.hash_stable(hcx, hasher);
304 mir::Rvalue::BinaryOp(op, ref operand1, ref operand2) |
305 mir::Rvalue::CheckedBinaryOp(op, ref operand1, ref operand2) => {
306 op.hash_stable(hcx, hasher);
307 operand1.hash_stable(hcx, hasher);
308 operand2.hash_stable(hcx, hasher);
310 mir::Rvalue::UnaryOp(op, ref operand) => {
311 op.hash_stable(hcx, hasher);
312 operand.hash_stable(hcx, hasher);
314 mir::Rvalue::Discriminant(ref lvalue) => {
315 lvalue.hash_stable(hcx, hasher);
317 mir::Rvalue::Box(ty) => {
318 ty.hash_stable(hcx, hasher);
320 mir::Rvalue::Aggregate(ref kind, ref operands) => {
321 kind.hash_stable(hcx, hasher);
322 operands.hash_stable(hcx, hasher);
328 impl_stable_hash_for!(enum mir::CastKind {
336 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::AggregateKind<'tcx> {
337 fn hash_stable<W: StableHasherResult>(&self,
338 hcx: &mut StableHashingContext<'a, 'tcx>,
339 hasher: &mut StableHasher<W>) {
340 mem::discriminant(self).hash_stable(hcx, hasher);
342 mir::AggregateKind::Tuple => {}
343 mir::AggregateKind::Array(t) => {
344 t.hash_stable(hcx, hasher);
346 mir::AggregateKind::Adt(adt_def, idx, substs, active_field) => {
347 adt_def.hash_stable(hcx, hasher);
348 idx.hash_stable(hcx, hasher);
349 substs.hash_stable(hcx, hasher);
350 active_field.hash_stable(hcx, hasher);
352 mir::AggregateKind::Closure(def_id, ref substs) => {
353 def_id.hash_stable(hcx, hasher);
354 substs.hash_stable(hcx, hasher);
360 impl_stable_hash_for!(enum mir::BinOp {
379 impl_stable_hash_for!(enum mir::UnOp {
385 impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
387 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Literal<'tcx> {
388 fn hash_stable<W: StableHasherResult>(&self,
389 hcx: &mut StableHashingContext<'a, 'tcx>,
390 hasher: &mut StableHasher<W>) {
391 mem::discriminant(self).hash_stable(hcx, hasher);
393 mir::Literal::Item { def_id, substs } => {
394 def_id.hash_stable(hcx, hasher);
395 substs.hash_stable(hcx, hasher);
397 mir::Literal::Value { ref value } => {
398 value.hash_stable(hcx, hasher);
400 mir::Literal::Promoted { index } => {
401 index.hash_stable(hcx, hasher);
407 impl_stable_hash_for!(struct mir::Location { block, statement_index });