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> {
32 impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref });
33 impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
35 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
36 for mir::Terminator<'tcx> {
38 fn hash_stable<W: StableHasherResult>(&self,
39 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
40 hasher: &mut StableHasher<W>) {
46 let hash_spans_unconditionally = match *kind {
47 mir::TerminatorKind::Assert { .. } => {
48 // Assert terminators generate a panic message that contains the
49 // source location, so we always have to feed its span into the
53 mir::TerminatorKind::Goto { .. } |
54 mir::TerminatorKind::SwitchInt { .. } |
55 mir::TerminatorKind::Resume |
56 mir::TerminatorKind::Return |
57 mir::TerminatorKind::Unreachable |
58 mir::TerminatorKind::Drop { .. } |
59 mir::TerminatorKind::DropAndReplace { .. } |
60 mir::TerminatorKind::Call { .. } => false,
63 if hash_spans_unconditionally {
64 hcx.while_hashing_spans(true, |hcx| {
65 source_info.hash_stable(hcx, hasher);
68 source_info.hash_stable(hcx, hasher);
71 kind.hash_stable(hcx, hasher);
76 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Local {
78 fn hash_stable<W: StableHasherResult>(&self,
79 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
80 hasher: &mut StableHasher<W>) {
81 use rustc_data_structures::indexed_vec::Idx;
82 self.index().hash_stable(hcx, hasher);
86 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::BasicBlock {
88 fn hash_stable<W: StableHasherResult>(&self,
89 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
90 hasher: &mut StableHasher<W>) {
91 use rustc_data_structures::indexed_vec::Idx;
92 self.index().hash_stable(hcx, hasher);
96 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Field {
98 fn hash_stable<W: StableHasherResult>(&self,
99 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
100 hasher: &mut StableHasher<W>) {
101 use rustc_data_structures::indexed_vec::Idx;
102 self.index().hash_stable(hcx, hasher);
106 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
107 for mir::VisibilityScope {
109 fn hash_stable<W: StableHasherResult>(&self,
110 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
111 hasher: &mut StableHasher<W>) {
112 use rustc_data_structures::indexed_vec::Idx;
113 self.index().hash_stable(hcx, hasher);
117 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Promoted {
119 fn hash_stable<W: StableHasherResult>(&self,
120 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
121 hasher: &mut StableHasher<W>) {
122 use rustc_data_structures::indexed_vec::Idx;
123 self.index().hash_stable(hcx, hasher);
127 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
128 for mir::TerminatorKind<'tcx> {
129 fn hash_stable<W: StableHasherResult>(&self,
130 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
131 hasher: &mut StableHasher<W>) {
132 mem::discriminant(self).hash_stable(hcx, hasher);
135 mir::TerminatorKind::Goto { ref target } => {
136 target.hash_stable(hcx, hasher);
138 mir::TerminatorKind::SwitchInt { ref discr,
142 discr.hash_stable(hcx, hasher);
143 switch_ty.hash_stable(hcx, hasher);
144 values.hash_stable(hcx, hasher);
145 targets.hash_stable(hcx, hasher);
147 mir::TerminatorKind::Resume |
148 mir::TerminatorKind::Return |
149 mir::TerminatorKind::Unreachable => {}
150 mir::TerminatorKind::Drop { ref location, target, unwind } => {
151 location.hash_stable(hcx, hasher);
152 target.hash_stable(hcx, hasher);
153 unwind.hash_stable(hcx, hasher);
155 mir::TerminatorKind::DropAndReplace { ref location,
159 location.hash_stable(hcx, hasher);
160 value.hash_stable(hcx, hasher);
161 target.hash_stable(hcx, hasher);
162 unwind.hash_stable(hcx, hasher);
164 mir::TerminatorKind::Call { ref func,
168 func.hash_stable(hcx, hasher);
169 args.hash_stable(hcx, hasher);
170 destination.hash_stable(hcx, hasher);
171 cleanup.hash_stable(hcx, hasher);
173 mir::TerminatorKind::Assert { ref cond,
178 cond.hash_stable(hcx, hasher);
179 expected.hash_stable(hcx, hasher);
180 msg.hash_stable(hcx, hasher);
181 target.hash_stable(hcx, hasher);
182 cleanup.hash_stable(hcx, hasher);
188 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
189 for mir::AssertMessage<'tcx> {
190 fn hash_stable<W: StableHasherResult>(&self,
191 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
192 hasher: &mut StableHasher<W>) {
193 mem::discriminant(self).hash_stable(hcx, hasher);
196 mir::AssertMessage::BoundsCheck { ref len, ref index } => {
197 len.hash_stable(hcx, hasher);
198 index.hash_stable(hcx, hasher);
200 mir::AssertMessage::Math(ref const_math_err) => {
201 const_math_err.hash_stable(hcx, hasher);
207 impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
209 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
210 for mir::StatementKind<'tcx> {
211 fn hash_stable<W: StableHasherResult>(&self,
212 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
213 hasher: &mut StableHasher<W>) {
214 mem::discriminant(self).hash_stable(hcx, hasher);
217 mir::StatementKind::Assign(ref lvalue, ref rvalue) => {
218 lvalue.hash_stable(hcx, hasher);
219 rvalue.hash_stable(hcx, hasher);
221 mir::StatementKind::SetDiscriminant { ref lvalue, variant_index } => {
222 lvalue.hash_stable(hcx, hasher);
223 variant_index.hash_stable(hcx, hasher);
225 mir::StatementKind::StorageLive(ref lvalue) |
226 mir::StatementKind::StorageDead(ref lvalue) => {
227 lvalue.hash_stable(hcx, hasher);
229 mir::StatementKind::EndRegion(ref extents) => {
230 extents.hash_stable(hcx, hasher);
232 mir::StatementKind::Nop => {}
233 mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
234 asm.hash_stable(hcx, hasher);
235 outputs.hash_stable(hcx, hasher);
236 inputs.hash_stable(hcx, hasher);
242 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Lvalue<'tcx> {
243 fn hash_stable<W: StableHasherResult>(&self,
244 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
245 hasher: &mut StableHasher<W>) {
246 mem::discriminant(self).hash_stable(hcx, hasher);
248 mir::Lvalue::Local(ref local) => {
249 local.hash_stable(hcx, hasher);
251 mir::Lvalue::Static(ref statik) => {
252 statik.hash_stable(hcx, hasher);
254 mir::Lvalue::Projection(ref lvalue_projection) => {
255 lvalue_projection.hash_stable(hcx, hasher);
261 impl<'a, 'gcx, 'tcx, B, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
262 for mir::Projection<'tcx, B, V, T>
263 where B: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
264 V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
265 T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
267 fn hash_stable<W: StableHasherResult>(&self,
268 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
269 hasher: &mut StableHasher<W>) {
270 let mir::Projection {
275 base.hash_stable(hcx, hasher);
276 elem.hash_stable(hcx, hasher);
280 impl<'a, 'gcx, 'tcx, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
281 for mir::ProjectionElem<'tcx, V, T>
282 where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
283 T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
285 fn hash_stable<W: StableHasherResult>(&self,
286 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
287 hasher: &mut StableHasher<W>) {
288 mem::discriminant(self).hash_stable(hcx, hasher);
290 mir::ProjectionElem::Deref => {}
291 mir::ProjectionElem::Field(field, ref ty) => {
292 field.hash_stable(hcx, hasher);
293 ty.hash_stable(hcx, hasher);
295 mir::ProjectionElem::Index(ref value) => {
296 value.hash_stable(hcx, hasher);
298 mir::ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
299 offset.hash_stable(hcx, hasher);
300 min_length.hash_stable(hcx, hasher);
301 from_end.hash_stable(hcx, hasher);
303 mir::ProjectionElem::Subslice { from, to } => {
304 from.hash_stable(hcx, hasher);
305 to.hash_stable(hcx, hasher);
307 mir::ProjectionElem::Downcast(adt_def, variant) => {
308 adt_def.hash_stable(hcx, hasher);
309 variant.hash_stable(hcx, hasher);
315 impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope });
317 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Operand<'tcx> {
318 fn hash_stable<W: StableHasherResult>(&self,
319 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
320 hasher: &mut StableHasher<W>) {
321 mem::discriminant(self).hash_stable(hcx, hasher);
324 mir::Operand::Consume(ref lvalue) => {
325 lvalue.hash_stable(hcx, hasher);
327 mir::Operand::Constant(ref constant) => {
328 constant.hash_stable(hcx, hasher);
334 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Rvalue<'tcx> {
335 fn hash_stable<W: StableHasherResult>(&self,
336 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
337 hasher: &mut StableHasher<W>) {
338 mem::discriminant(self).hash_stable(hcx, hasher);
341 mir::Rvalue::Use(ref operand) => {
342 operand.hash_stable(hcx, hasher);
344 mir::Rvalue::Repeat(ref operand, ref val) => {
345 operand.hash_stable(hcx, hasher);
346 val.hash_stable(hcx, hasher);
348 mir::Rvalue::Ref(region, borrow_kind, ref lvalue) => {
349 region.hash_stable(hcx, hasher);
350 borrow_kind.hash_stable(hcx, hasher);
351 lvalue.hash_stable(hcx, hasher);
353 mir::Rvalue::Len(ref lvalue) => {
354 lvalue.hash_stable(hcx, hasher);
356 mir::Rvalue::Cast(cast_kind, ref operand, ty) => {
357 cast_kind.hash_stable(hcx, hasher);
358 operand.hash_stable(hcx, hasher);
359 ty.hash_stable(hcx, hasher);
361 mir::Rvalue::BinaryOp(op, ref operand1, ref operand2) |
362 mir::Rvalue::CheckedBinaryOp(op, ref operand1, ref operand2) => {
363 op.hash_stable(hcx, hasher);
364 operand1.hash_stable(hcx, hasher);
365 operand2.hash_stable(hcx, hasher);
367 mir::Rvalue::UnaryOp(op, ref operand) => {
368 op.hash_stable(hcx, hasher);
369 operand.hash_stable(hcx, hasher);
371 mir::Rvalue::Discriminant(ref lvalue) => {
372 lvalue.hash_stable(hcx, hasher);
374 mir::Rvalue::NullaryOp(op, ty) => {
375 op.hash_stable(hcx, hasher);
376 ty.hash_stable(hcx, hasher);
378 mir::Rvalue::Aggregate(ref kind, ref operands) => {
379 kind.hash_stable(hcx, hasher);
380 operands.hash_stable(hcx, hasher);
386 impl_stable_hash_for!(enum mir::CastKind {
394 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
395 for mir::AggregateKind<'tcx> {
396 fn hash_stable<W: StableHasherResult>(&self,
397 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
398 hasher: &mut StableHasher<W>) {
399 mem::discriminant(self).hash_stable(hcx, hasher);
401 mir::AggregateKind::Tuple => {}
402 mir::AggregateKind::Array(t) => {
403 t.hash_stable(hcx, hasher);
405 mir::AggregateKind::Adt(adt_def, idx, substs, active_field) => {
406 adt_def.hash_stable(hcx, hasher);
407 idx.hash_stable(hcx, hasher);
408 substs.hash_stable(hcx, hasher);
409 active_field.hash_stable(hcx, hasher);
411 mir::AggregateKind::Closure(def_id, ref substs) => {
412 def_id.hash_stable(hcx, hasher);
413 substs.hash_stable(hcx, hasher);
419 impl_stable_hash_for!(enum mir::BinOp {
439 impl_stable_hash_for!(enum mir::UnOp {
444 impl_stable_hash_for!(enum mir::NullOp {
449 impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
451 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Literal<'tcx> {
452 fn hash_stable<W: StableHasherResult>(&self,
453 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
454 hasher: &mut StableHasher<W>) {
455 mem::discriminant(self).hash_stable(hcx, hasher);
457 mir::Literal::Item { def_id, substs } => {
458 def_id.hash_stable(hcx, hasher);
459 substs.hash_stable(hcx, hasher);
461 mir::Literal::Value { ref value } => {
462 value.hash_stable(hcx, hasher);
464 mir::Literal::Promoted { index } => {
465 index.hash_stable(hcx, hasher);
471 impl_stable_hash_for!(struct mir::Location { block, statement_index });