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> {
34 impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref, mutability });
35 impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
36 impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, kind });
37 impl_stable_hash_for!(struct mir::UnsafetyCheckResult { violations, unsafe_blocks });
39 impl<'gcx> HashStable<StableHashingContext<'gcx>>
40 for mir::UnsafetyViolationKind {
42 fn hash_stable<W: StableHasherResult>(&self,
43 hcx: &mut StableHashingContext<'gcx>,
44 hasher: &mut StableHasher<W>) {
46 mem::discriminant(self).hash_stable(hcx, hasher);
49 mir::UnsafetyViolationKind::General => {}
50 mir::UnsafetyViolationKind::ExternStatic(lint_node_id) |
51 mir::UnsafetyViolationKind::BorrowPacked(lint_node_id) => {
52 lint_node_id.hash_stable(hcx, hasher);
59 impl_stable_hash_for!(struct mir::Terminator<'tcx> {
64 impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for mir::ClearCrossCrate<T>
65 where T: HashStable<StableHashingContext<'gcx>>
68 fn hash_stable<W: StableHasherResult>(&self,
69 hcx: &mut StableHashingContext<'gcx>,
70 hasher: &mut StableHasher<W>) {
71 mem::discriminant(self).hash_stable(hcx, hasher);
73 mir::ClearCrossCrate::Clear => {}
74 mir::ClearCrossCrate::Set(ref value) => {
75 value.hash_stable(hcx, hasher);
81 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Local {
83 fn hash_stable<W: StableHasherResult>(&self,
84 hcx: &mut StableHashingContext<'gcx>,
85 hasher: &mut StableHasher<W>) {
86 use rustc_data_structures::indexed_vec::Idx;
87 self.index().hash_stable(hcx, hasher);
91 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::BasicBlock {
93 fn hash_stable<W: StableHasherResult>(&self,
94 hcx: &mut StableHashingContext<'gcx>,
95 hasher: &mut StableHasher<W>) {
96 use rustc_data_structures::indexed_vec::Idx;
97 self.index().hash_stable(hcx, hasher);
101 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Field {
103 fn hash_stable<W: StableHasherResult>(&self,
104 hcx: &mut StableHashingContext<'gcx>,
105 hasher: &mut StableHasher<W>) {
106 use rustc_data_structures::indexed_vec::Idx;
107 self.index().hash_stable(hcx, hasher);
111 impl<'gcx> HashStable<StableHashingContext<'gcx>>
112 for mir::VisibilityScope {
114 fn hash_stable<W: StableHasherResult>(&self,
115 hcx: &mut StableHashingContext<'gcx>,
116 hasher: &mut StableHasher<W>) {
117 use rustc_data_structures::indexed_vec::Idx;
118 self.index().hash_stable(hcx, hasher);
122 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Promoted {
124 fn hash_stable<W: StableHasherResult>(&self,
125 hcx: &mut StableHashingContext<'gcx>,
126 hasher: &mut StableHasher<W>) {
127 use rustc_data_structures::indexed_vec::Idx;
128 self.index().hash_stable(hcx, hasher);
132 impl<'gcx> HashStable<StableHashingContext<'gcx>>
133 for mir::TerminatorKind<'gcx> {
134 fn hash_stable<W: StableHasherResult>(&self,
135 hcx: &mut StableHashingContext<'gcx>,
136 hasher: &mut StableHasher<W>) {
137 mem::discriminant(self).hash_stable(hcx, hasher);
140 mir::TerminatorKind::Goto { ref target } => {
141 target.hash_stable(hcx, hasher);
143 mir::TerminatorKind::SwitchInt { ref discr,
147 discr.hash_stable(hcx, hasher);
148 switch_ty.hash_stable(hcx, hasher);
149 values.hash_stable(hcx, hasher);
150 targets.hash_stable(hcx, hasher);
152 mir::TerminatorKind::Resume |
153 mir::TerminatorKind::Abort |
154 mir::TerminatorKind::Return |
155 mir::TerminatorKind::GeneratorDrop |
156 mir::TerminatorKind::Unreachable => {}
157 mir::TerminatorKind::Drop { ref location, target, unwind } => {
158 location.hash_stable(hcx, hasher);
159 target.hash_stable(hcx, hasher);
160 unwind.hash_stable(hcx, hasher);
162 mir::TerminatorKind::DropAndReplace { ref location,
166 location.hash_stable(hcx, hasher);
167 value.hash_stable(hcx, hasher);
168 target.hash_stable(hcx, hasher);
169 unwind.hash_stable(hcx, hasher);
171 mir::TerminatorKind::Yield { ref value,
174 value.hash_stable(hcx, hasher);
175 resume.hash_stable(hcx, hasher);
176 drop.hash_stable(hcx, hasher);
178 mir::TerminatorKind::Call { ref func,
182 func.hash_stable(hcx, hasher);
183 args.hash_stable(hcx, hasher);
184 destination.hash_stable(hcx, hasher);
185 cleanup.hash_stable(hcx, hasher);
187 mir::TerminatorKind::Assert { ref cond,
192 cond.hash_stable(hcx, hasher);
193 expected.hash_stable(hcx, hasher);
194 msg.hash_stable(hcx, hasher);
195 target.hash_stable(hcx, hasher);
196 cleanup.hash_stable(hcx, hasher);
198 mir::TerminatorKind::FalseEdges { ref real_target, ref imaginary_targets } => {
199 real_target.hash_stable(hcx, hasher);
200 for target in imaginary_targets {
201 target.hash_stable(hcx, hasher);
208 impl<'gcx> HashStable<StableHashingContext<'gcx>>
209 for mir::AssertMessage<'gcx> {
210 fn hash_stable<W: StableHasherResult>(&self,
211 hcx: &mut StableHashingContext<'gcx>,
212 hasher: &mut StableHasher<W>) {
213 mem::discriminant(self).hash_stable(hcx, hasher);
216 mir::AssertMessage::BoundsCheck { ref len, ref index } => {
217 len.hash_stable(hcx, hasher);
218 index.hash_stable(hcx, hasher);
220 mir::AssertMessage::Math(ref const_math_err) => {
221 const_math_err.hash_stable(hcx, hasher);
223 mir::AssertMessage::GeneratorResumedAfterReturn => (),
224 mir::AssertMessage::GeneratorResumedAfterPanic => (),
229 impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
231 impl<'gcx> HashStable<StableHashingContext<'gcx>>
232 for mir::StatementKind<'gcx> {
233 fn hash_stable<W: StableHasherResult>(&self,
234 hcx: &mut StableHashingContext<'gcx>,
235 hasher: &mut StableHasher<W>) {
236 mem::discriminant(self).hash_stable(hcx, hasher);
239 mir::StatementKind::Assign(ref place, ref rvalue) => {
240 place.hash_stable(hcx, hasher);
241 rvalue.hash_stable(hcx, hasher);
243 mir::StatementKind::SetDiscriminant { ref place, variant_index } => {
244 place.hash_stable(hcx, hasher);
245 variant_index.hash_stable(hcx, hasher);
247 mir::StatementKind::StorageLive(ref place) |
248 mir::StatementKind::StorageDead(ref place) => {
249 place.hash_stable(hcx, hasher);
251 mir::StatementKind::EndRegion(ref region_scope) => {
252 region_scope.hash_stable(hcx, hasher);
254 mir::StatementKind::Validate(ref op, ref places) => {
255 op.hash_stable(hcx, hasher);
256 places.hash_stable(hcx, hasher);
258 mir::StatementKind::Nop => {}
259 mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
260 asm.hash_stable(hcx, hasher);
261 outputs.hash_stable(hcx, hasher);
262 inputs.hash_stable(hcx, hasher);
268 impl<'gcx, T> HashStable<StableHashingContext<'gcx>>
269 for mir::ValidationOperand<'gcx, T>
270 where T: HashStable<StableHashingContext<'gcx>>
272 fn hash_stable<W: StableHasherResult>(&self,
273 hcx: &mut StableHashingContext<'gcx>,
274 hasher: &mut StableHasher<W>)
276 self.place.hash_stable(hcx, hasher);
277 self.ty.hash_stable(hcx, hasher);
278 self.re.hash_stable(hcx, hasher);
279 self.mutbl.hash_stable(hcx, hasher);
283 impl_stable_hash_for!(enum mir::ValidationOp { Acquire, Release, Suspend(region_scope) });
285 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Place<'gcx> {
286 fn hash_stable<W: StableHasherResult>(&self,
287 hcx: &mut StableHashingContext<'gcx>,
288 hasher: &mut StableHasher<W>) {
289 mem::discriminant(self).hash_stable(hcx, hasher);
291 mir::Place::Local(ref local) => {
292 local.hash_stable(hcx, hasher);
294 mir::Place::Static(ref statik) => {
295 statik.hash_stable(hcx, hasher);
297 mir::Place::Projection(ref place_projection) => {
298 place_projection.hash_stable(hcx, hasher);
304 impl<'gcx, B, V, T> HashStable<StableHashingContext<'gcx>>
305 for mir::Projection<'gcx, B, V, T>
306 where B: HashStable<StableHashingContext<'gcx>>,
307 V: HashStable<StableHashingContext<'gcx>>,
308 T: HashStable<StableHashingContext<'gcx>>
310 fn hash_stable<W: StableHasherResult>(&self,
311 hcx: &mut StableHashingContext<'gcx>,
312 hasher: &mut StableHasher<W>) {
313 let mir::Projection {
318 base.hash_stable(hcx, hasher);
319 elem.hash_stable(hcx, hasher);
323 impl<'gcx, V, T> HashStable<StableHashingContext<'gcx>>
324 for mir::ProjectionElem<'gcx, V, T>
325 where V: HashStable<StableHashingContext<'gcx>>,
326 T: HashStable<StableHashingContext<'gcx>>
328 fn hash_stable<W: StableHasherResult>(&self,
329 hcx: &mut StableHashingContext<'gcx>,
330 hasher: &mut StableHasher<W>) {
331 mem::discriminant(self).hash_stable(hcx, hasher);
333 mir::ProjectionElem::Deref => {}
334 mir::ProjectionElem::Field(field, ref ty) => {
335 field.hash_stable(hcx, hasher);
336 ty.hash_stable(hcx, hasher);
338 mir::ProjectionElem::Index(ref value) => {
339 value.hash_stable(hcx, hasher);
341 mir::ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
342 offset.hash_stable(hcx, hasher);
343 min_length.hash_stable(hcx, hasher);
344 from_end.hash_stable(hcx, hasher);
346 mir::ProjectionElem::Subslice { from, to } => {
347 from.hash_stable(hcx, hasher);
348 to.hash_stable(hcx, hasher);
350 mir::ProjectionElem::Downcast(adt_def, variant) => {
351 adt_def.hash_stable(hcx, hasher);
352 variant.hash_stable(hcx, hasher);
358 impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope });
359 impl_stable_hash_for!(struct mir::VisibilityScopeInfo {
363 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Safety {
364 fn hash_stable<W: StableHasherResult>(&self,
365 hcx: &mut StableHashingContext<'gcx>,
366 hasher: &mut StableHasher<W>) {
367 mem::discriminant(self).hash_stable(hcx, hasher);
371 mir::Safety::BuiltinUnsafe |
372 mir::Safety::FnUnsafe => {}
373 mir::Safety::ExplicitUnsafe(node_id) => {
374 node_id.hash_stable(hcx, hasher);
380 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Operand<'gcx> {
381 fn hash_stable<W: StableHasherResult>(&self,
382 hcx: &mut StableHashingContext<'gcx>,
383 hasher: &mut StableHasher<W>) {
384 mem::discriminant(self).hash_stable(hcx, hasher);
387 mir::Operand::Copy(ref place) => {
388 place.hash_stable(hcx, hasher);
390 mir::Operand::Move(ref place) => {
391 place.hash_stable(hcx, hasher);
393 mir::Operand::Constant(ref constant) => {
394 constant.hash_stable(hcx, hasher);
400 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Rvalue<'gcx> {
401 fn hash_stable<W: StableHasherResult>(&self,
402 hcx: &mut StableHashingContext<'gcx>,
403 hasher: &mut StableHasher<W>) {
404 mem::discriminant(self).hash_stable(hcx, hasher);
407 mir::Rvalue::Use(ref operand) => {
408 operand.hash_stable(hcx, hasher);
410 mir::Rvalue::Repeat(ref operand, ref val) => {
411 operand.hash_stable(hcx, hasher);
412 val.hash_stable(hcx, hasher);
414 mir::Rvalue::Ref(region, borrow_kind, ref place) => {
415 region.hash_stable(hcx, hasher);
416 borrow_kind.hash_stable(hcx, hasher);
417 place.hash_stable(hcx, hasher);
419 mir::Rvalue::Len(ref place) => {
420 place.hash_stable(hcx, hasher);
422 mir::Rvalue::Cast(cast_kind, ref operand, ty) => {
423 cast_kind.hash_stable(hcx, hasher);
424 operand.hash_stable(hcx, hasher);
425 ty.hash_stable(hcx, hasher);
427 mir::Rvalue::BinaryOp(op, ref operand1, ref operand2) |
428 mir::Rvalue::CheckedBinaryOp(op, ref operand1, ref operand2) => {
429 op.hash_stable(hcx, hasher);
430 operand1.hash_stable(hcx, hasher);
431 operand2.hash_stable(hcx, hasher);
433 mir::Rvalue::UnaryOp(op, ref operand) => {
434 op.hash_stable(hcx, hasher);
435 operand.hash_stable(hcx, hasher);
437 mir::Rvalue::Discriminant(ref place) => {
438 place.hash_stable(hcx, hasher);
440 mir::Rvalue::NullaryOp(op, ty) => {
441 op.hash_stable(hcx, hasher);
442 ty.hash_stable(hcx, hasher);
444 mir::Rvalue::Aggregate(ref kind, ref operands) => {
445 kind.hash_stable(hcx, hasher);
446 operands.hash_stable(hcx, hasher);
452 impl_stable_hash_for!(enum mir::CastKind {
460 impl<'gcx> HashStable<StableHashingContext<'gcx>>
461 for mir::AggregateKind<'gcx> {
462 fn hash_stable<W: StableHasherResult>(&self,
463 hcx: &mut StableHashingContext<'gcx>,
464 hasher: &mut StableHasher<W>) {
465 mem::discriminant(self).hash_stable(hcx, hasher);
467 mir::AggregateKind::Tuple => {}
468 mir::AggregateKind::Array(t) => {
469 t.hash_stable(hcx, hasher);
471 mir::AggregateKind::Adt(adt_def, idx, substs, active_field) => {
472 adt_def.hash_stable(hcx, hasher);
473 idx.hash_stable(hcx, hasher);
474 substs.hash_stable(hcx, hasher);
475 active_field.hash_stable(hcx, hasher);
477 mir::AggregateKind::Closure(def_id, ref substs) => {
478 def_id.hash_stable(hcx, hasher);
479 substs.hash_stable(hcx, hasher);
481 mir::AggregateKind::Generator(def_id, ref substs, ref interior) => {
482 def_id.hash_stable(hcx, hasher);
483 substs.hash_stable(hcx, hasher);
484 interior.hash_stable(hcx, hasher);
490 impl_stable_hash_for!(enum mir::BinOp {
510 impl_stable_hash_for!(enum mir::UnOp {
515 impl_stable_hash_for!(enum mir::NullOp {
520 impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
522 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Literal<'gcx> {
523 fn hash_stable<W: StableHasherResult>(&self,
524 hcx: &mut StableHashingContext<'gcx>,
525 hasher: &mut StableHasher<W>) {
526 mem::discriminant(self).hash_stable(hcx, hasher);
528 mir::Literal::Value { ref value } => {
529 value.hash_stable(hcx, hasher);
531 mir::Literal::Promoted { index } => {
532 index.hash_stable(hcx, hasher);
538 impl_stable_hash_for!(struct mir::Location { block, statement_index });
540 impl_stable_hash_for!(struct mir::ClosureRegionRequirements<'tcx> {
542 outlives_requirements
545 impl_stable_hash_for!(struct mir::ClosureOutlivesRequirement<'tcx> {
547 outlived_free_region,
551 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::ClosureOutlivesSubject<'gcx> {
552 fn hash_stable<W: StableHasherResult>(&self,
553 hcx: &mut StableHashingContext<'gcx>,
554 hasher: &mut StableHasher<W>) {
555 mem::discriminant(self).hash_stable(hcx, hasher);
557 mir::ClosureOutlivesSubject::Ty(ref ty) => {
558 ty.hash_stable(hcx, hasher);
560 mir::ClosureOutlivesSubject::Region(ref region) => {
561 region.hash_stable(hcx, hasher);