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,
20 impl_stable_hash_for!(struct mir::GeneratorLayout<'tcx> { fields });
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> {
33 impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref });
34 impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
36 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
37 for mir::Terminator<'gcx> {
39 fn hash_stable<W: StableHasherResult>(&self,
40 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
41 hasher: &mut StableHasher<W>) {
47 let hash_spans_unconditionally = match *kind {
48 mir::TerminatorKind::Assert { .. } => {
49 // Assert terminators generate a panic message that contains the
50 // source location, so we always have to feed its span into the
54 mir::TerminatorKind::Goto { .. } |
55 mir::TerminatorKind::SwitchInt { .. } |
56 mir::TerminatorKind::Resume |
57 mir::TerminatorKind::Return |
58 mir::TerminatorKind::GeneratorDrop |
59 mir::TerminatorKind::Unreachable |
60 mir::TerminatorKind::Drop { .. } |
61 mir::TerminatorKind::DropAndReplace { .. } |
62 mir::TerminatorKind::Yield { .. } |
63 mir::TerminatorKind::Call { .. } => false,
66 if hash_spans_unconditionally {
67 hcx.while_hashing_spans(true, |hcx| {
68 source_info.hash_stable(hcx, hasher);
71 source_info.hash_stable(hcx, hasher);
74 kind.hash_stable(hcx, hasher);
79 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Local {
81 fn hash_stable<W: StableHasherResult>(&self,
82 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
83 hasher: &mut StableHasher<W>) {
84 use rustc_data_structures::indexed_vec::Idx;
85 self.index().hash_stable(hcx, hasher);
89 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::BasicBlock {
91 fn hash_stable<W: StableHasherResult>(&self,
92 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
93 hasher: &mut StableHasher<W>) {
94 use rustc_data_structures::indexed_vec::Idx;
95 self.index().hash_stable(hcx, hasher);
99 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Field {
101 fn hash_stable<W: StableHasherResult>(&self,
102 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
103 hasher: &mut StableHasher<W>) {
104 use rustc_data_structures::indexed_vec::Idx;
105 self.index().hash_stable(hcx, hasher);
109 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
110 for mir::VisibilityScope {
112 fn hash_stable<W: StableHasherResult>(&self,
113 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
114 hasher: &mut StableHasher<W>) {
115 use rustc_data_structures::indexed_vec::Idx;
116 self.index().hash_stable(hcx, hasher);
120 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Promoted {
122 fn hash_stable<W: StableHasherResult>(&self,
123 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
124 hasher: &mut StableHasher<W>) {
125 use rustc_data_structures::indexed_vec::Idx;
126 self.index().hash_stable(hcx, hasher);
130 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
131 for mir::TerminatorKind<'gcx> {
132 fn hash_stable<W: StableHasherResult>(&self,
133 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
134 hasher: &mut StableHasher<W>) {
135 mem::discriminant(self).hash_stable(hcx, hasher);
138 mir::TerminatorKind::Goto { ref target } => {
139 target.hash_stable(hcx, hasher);
141 mir::TerminatorKind::SwitchInt { ref discr,
145 discr.hash_stable(hcx, hasher);
146 switch_ty.hash_stable(hcx, hasher);
147 values.hash_stable(hcx, hasher);
148 targets.hash_stable(hcx, hasher);
150 mir::TerminatorKind::Resume |
151 mir::TerminatorKind::Return |
152 mir::TerminatorKind::GeneratorDrop |
153 mir::TerminatorKind::Unreachable => {}
154 mir::TerminatorKind::Drop { ref location, target, unwind } => {
155 location.hash_stable(hcx, hasher);
156 target.hash_stable(hcx, hasher);
157 unwind.hash_stable(hcx, hasher);
159 mir::TerminatorKind::DropAndReplace { ref location,
163 location.hash_stable(hcx, hasher);
164 value.hash_stable(hcx, hasher);
165 target.hash_stable(hcx, hasher);
166 unwind.hash_stable(hcx, hasher);
168 mir::TerminatorKind::Yield { ref value,
171 value.hash_stable(hcx, hasher);
172 resume.hash_stable(hcx, hasher);
173 drop.hash_stable(hcx, hasher);
175 mir::TerminatorKind::Call { ref func,
179 func.hash_stable(hcx, hasher);
180 args.hash_stable(hcx, hasher);
181 destination.hash_stable(hcx, hasher);
182 cleanup.hash_stable(hcx, hasher);
184 mir::TerminatorKind::Assert { ref cond,
189 cond.hash_stable(hcx, hasher);
190 expected.hash_stable(hcx, hasher);
191 msg.hash_stable(hcx, hasher);
192 target.hash_stable(hcx, hasher);
193 cleanup.hash_stable(hcx, hasher);
199 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
200 for mir::AssertMessage<'gcx> {
201 fn hash_stable<W: StableHasherResult>(&self,
202 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
203 hasher: &mut StableHasher<W>) {
204 mem::discriminant(self).hash_stable(hcx, hasher);
207 mir::AssertMessage::BoundsCheck { ref len, ref index } => {
208 len.hash_stable(hcx, hasher);
209 index.hash_stable(hcx, hasher);
211 mir::AssertMessage::Math(ref const_math_err) => {
212 const_math_err.hash_stable(hcx, hasher);
214 mir::AssertMessage::GeneratorResumedAfterReturn => (),
215 mir::AssertMessage::GeneratorResumedAfterPanic => (),
220 impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
222 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
223 for mir::StatementKind<'gcx> {
224 fn hash_stable<W: StableHasherResult>(&self,
225 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
226 hasher: &mut StableHasher<W>) {
227 mem::discriminant(self).hash_stable(hcx, hasher);
230 mir::StatementKind::Assign(ref lvalue, ref rvalue) => {
231 lvalue.hash_stable(hcx, hasher);
232 rvalue.hash_stable(hcx, hasher);
234 mir::StatementKind::SetDiscriminant { ref lvalue, variant_index } => {
235 lvalue.hash_stable(hcx, hasher);
236 variant_index.hash_stable(hcx, hasher);
238 mir::StatementKind::StorageLive(ref lvalue) |
239 mir::StatementKind::StorageDead(ref lvalue) => {
240 lvalue.hash_stable(hcx, hasher);
242 mir::StatementKind::EndRegion(ref extent) => {
243 extent.hash_stable(hcx, hasher);
245 mir::StatementKind::Validate(ref op, ref lvalues) => {
246 op.hash_stable(hcx, hasher);
247 lvalues.hash_stable(hcx, hasher);
249 mir::StatementKind::Nop => {}
250 mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
251 asm.hash_stable(hcx, hasher);
252 outputs.hash_stable(hcx, hasher);
253 inputs.hash_stable(hcx, hasher);
259 impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
260 for mir::ValidationOperand<'gcx, T>
261 where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
263 fn hash_stable<W: StableHasherResult>(&self,
264 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
265 hasher: &mut StableHasher<W>)
267 self.lval.hash_stable(hcx, hasher);
268 self.ty.hash_stable(hcx, hasher);
269 self.re.hash_stable(hcx, hasher);
270 self.mutbl.hash_stable(hcx, hasher);
274 impl_stable_hash_for!(enum mir::ValidationOp { Acquire, Release, Suspend(extent) });
276 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Lvalue<'gcx> {
277 fn hash_stable<W: StableHasherResult>(&self,
278 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
279 hasher: &mut StableHasher<W>) {
280 mem::discriminant(self).hash_stable(hcx, hasher);
282 mir::Lvalue::Local(ref local) => {
283 local.hash_stable(hcx, hasher);
285 mir::Lvalue::Static(ref statik) => {
286 statik.hash_stable(hcx, hasher);
288 mir::Lvalue::Projection(ref lvalue_projection) => {
289 lvalue_projection.hash_stable(hcx, hasher);
295 impl<'a, 'gcx, 'tcx, B, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
296 for mir::Projection<'gcx, B, V, T>
297 where B: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
298 V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
299 T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
301 fn hash_stable<W: StableHasherResult>(&self,
302 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
303 hasher: &mut StableHasher<W>) {
304 let mir::Projection {
309 base.hash_stable(hcx, hasher);
310 elem.hash_stable(hcx, hasher);
314 impl<'a, 'gcx, 'tcx, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
315 for mir::ProjectionElem<'gcx, V, T>
316 where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
317 T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
319 fn hash_stable<W: StableHasherResult>(&self,
320 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
321 hasher: &mut StableHasher<W>) {
322 mem::discriminant(self).hash_stable(hcx, hasher);
324 mir::ProjectionElem::Deref => {}
325 mir::ProjectionElem::Field(field, ref ty) => {
326 field.hash_stable(hcx, hasher);
327 ty.hash_stable(hcx, hasher);
329 mir::ProjectionElem::Index(ref value) => {
330 value.hash_stable(hcx, hasher);
332 mir::ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
333 offset.hash_stable(hcx, hasher);
334 min_length.hash_stable(hcx, hasher);
335 from_end.hash_stable(hcx, hasher);
337 mir::ProjectionElem::Subslice { from, to } => {
338 from.hash_stable(hcx, hasher);
339 to.hash_stable(hcx, hasher);
341 mir::ProjectionElem::Downcast(adt_def, variant) => {
342 adt_def.hash_stable(hcx, hasher);
343 variant.hash_stable(hcx, hasher);
349 impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope });
351 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Operand<'gcx> {
352 fn hash_stable<W: StableHasherResult>(&self,
353 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
354 hasher: &mut StableHasher<W>) {
355 mem::discriminant(self).hash_stable(hcx, hasher);
358 mir::Operand::Consume(ref lvalue) => {
359 lvalue.hash_stable(hcx, hasher);
361 mir::Operand::Constant(ref constant) => {
362 constant.hash_stable(hcx, hasher);
368 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Rvalue<'gcx> {
369 fn hash_stable<W: StableHasherResult>(&self,
370 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
371 hasher: &mut StableHasher<W>) {
372 mem::discriminant(self).hash_stable(hcx, hasher);
375 mir::Rvalue::Use(ref operand) => {
376 operand.hash_stable(hcx, hasher);
378 mir::Rvalue::Repeat(ref operand, ref val) => {
379 operand.hash_stable(hcx, hasher);
380 val.hash_stable(hcx, hasher);
382 mir::Rvalue::Ref(region, borrow_kind, ref lvalue) => {
383 region.hash_stable(hcx, hasher);
384 borrow_kind.hash_stable(hcx, hasher);
385 lvalue.hash_stable(hcx, hasher);
387 mir::Rvalue::Len(ref lvalue) => {
388 lvalue.hash_stable(hcx, hasher);
390 mir::Rvalue::Cast(cast_kind, ref operand, ty) => {
391 cast_kind.hash_stable(hcx, hasher);
392 operand.hash_stable(hcx, hasher);
393 ty.hash_stable(hcx, hasher);
395 mir::Rvalue::BinaryOp(op, ref operand1, ref operand2) |
396 mir::Rvalue::CheckedBinaryOp(op, ref operand1, ref operand2) => {
397 op.hash_stable(hcx, hasher);
398 operand1.hash_stable(hcx, hasher);
399 operand2.hash_stable(hcx, hasher);
401 mir::Rvalue::UnaryOp(op, ref operand) => {
402 op.hash_stable(hcx, hasher);
403 operand.hash_stable(hcx, hasher);
405 mir::Rvalue::Discriminant(ref lvalue) => {
406 lvalue.hash_stable(hcx, hasher);
408 mir::Rvalue::NullaryOp(op, ty) => {
409 op.hash_stable(hcx, hasher);
410 ty.hash_stable(hcx, hasher);
412 mir::Rvalue::Aggregate(ref kind, ref operands) => {
413 kind.hash_stable(hcx, hasher);
414 operands.hash_stable(hcx, hasher);
420 impl_stable_hash_for!(enum mir::CastKind {
428 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
429 for mir::AggregateKind<'gcx> {
430 fn hash_stable<W: StableHasherResult>(&self,
431 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
432 hasher: &mut StableHasher<W>) {
433 mem::discriminant(self).hash_stable(hcx, hasher);
435 mir::AggregateKind::Tuple => {}
436 mir::AggregateKind::Array(t) => {
437 t.hash_stable(hcx, hasher);
439 mir::AggregateKind::Adt(adt_def, idx, substs, active_field) => {
440 adt_def.hash_stable(hcx, hasher);
441 idx.hash_stable(hcx, hasher);
442 substs.hash_stable(hcx, hasher);
443 active_field.hash_stable(hcx, hasher);
445 mir::AggregateKind::Closure(def_id, ref substs) => {
446 def_id.hash_stable(hcx, hasher);
447 substs.hash_stable(hcx, hasher);
449 mir::AggregateKind::Generator(def_id, ref substs, ref interior) => {
450 def_id.hash_stable(hcx, hasher);
451 substs.hash_stable(hcx, hasher);
452 interior.hash_stable(hcx, hasher);
458 impl_stable_hash_for!(enum mir::BinOp {
478 impl_stable_hash_for!(enum mir::UnOp {
483 impl_stable_hash_for!(enum mir::NullOp {
488 impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
490 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Literal<'gcx> {
491 fn hash_stable<W: StableHasherResult>(&self,
492 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
493 hasher: &mut StableHasher<W>) {
494 mem::discriminant(self).hash_stable(hcx, hasher);
496 mir::Literal::Item { def_id, substs } => {
497 def_id.hash_stable(hcx, hasher);
498 substs.hash_stable(hcx, hasher);
500 mir::Literal::Value { ref value } => {
501 value.hash_stable(hcx, hasher);
503 mir::Literal::Promoted { index } => {
504 index.hash_stable(hcx, hasher);
510 impl_stable_hash_for!(struct mir::Location { block, statement_index });