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::Return |
154 mir::TerminatorKind::GeneratorDrop |
155 mir::TerminatorKind::Unreachable => {}
156 mir::TerminatorKind::Drop { ref location, target, unwind } => {
157 location.hash_stable(hcx, hasher);
158 target.hash_stable(hcx, hasher);
159 unwind.hash_stable(hcx, hasher);
161 mir::TerminatorKind::DropAndReplace { ref location,
165 location.hash_stable(hcx, hasher);
166 value.hash_stable(hcx, hasher);
167 target.hash_stable(hcx, hasher);
168 unwind.hash_stable(hcx, hasher);
170 mir::TerminatorKind::Yield { ref value,
173 value.hash_stable(hcx, hasher);
174 resume.hash_stable(hcx, hasher);
175 drop.hash_stable(hcx, hasher);
177 mir::TerminatorKind::Call { ref func,
181 func.hash_stable(hcx, hasher);
182 args.hash_stable(hcx, hasher);
183 destination.hash_stable(hcx, hasher);
184 cleanup.hash_stable(hcx, hasher);
186 mir::TerminatorKind::Assert { ref cond,
191 cond.hash_stable(hcx, hasher);
192 expected.hash_stable(hcx, hasher);
193 msg.hash_stable(hcx, hasher);
194 target.hash_stable(hcx, hasher);
195 cleanup.hash_stable(hcx, hasher);
197 mir::TerminatorKind::FalseEdges { ref real_target, ref imaginary_targets } => {
198 real_target.hash_stable(hcx, hasher);
199 for target in imaginary_targets {
200 target.hash_stable(hcx, hasher);
207 impl<'gcx> HashStable<StableHashingContext<'gcx>>
208 for mir::AssertMessage<'gcx> {
209 fn hash_stable<W: StableHasherResult>(&self,
210 hcx: &mut StableHashingContext<'gcx>,
211 hasher: &mut StableHasher<W>) {
212 mem::discriminant(self).hash_stable(hcx, hasher);
215 mir::AssertMessage::BoundsCheck { ref len, ref index } => {
216 len.hash_stable(hcx, hasher);
217 index.hash_stable(hcx, hasher);
219 mir::AssertMessage::Math(ref const_math_err) => {
220 const_math_err.hash_stable(hcx, hasher);
222 mir::AssertMessage::GeneratorResumedAfterReturn => (),
223 mir::AssertMessage::GeneratorResumedAfterPanic => (),
228 impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
230 impl<'gcx> HashStable<StableHashingContext<'gcx>>
231 for mir::StatementKind<'gcx> {
232 fn hash_stable<W: StableHasherResult>(&self,
233 hcx: &mut StableHashingContext<'gcx>,
234 hasher: &mut StableHasher<W>) {
235 mem::discriminant(self).hash_stable(hcx, hasher);
238 mir::StatementKind::Assign(ref place, ref rvalue) => {
239 place.hash_stable(hcx, hasher);
240 rvalue.hash_stable(hcx, hasher);
242 mir::StatementKind::SetDiscriminant { ref place, variant_index } => {
243 place.hash_stable(hcx, hasher);
244 variant_index.hash_stable(hcx, hasher);
246 mir::StatementKind::StorageLive(ref place) |
247 mir::StatementKind::StorageDead(ref place) => {
248 place.hash_stable(hcx, hasher);
250 mir::StatementKind::EndRegion(ref region_scope) => {
251 region_scope.hash_stable(hcx, hasher);
253 mir::StatementKind::Validate(ref op, ref places) => {
254 op.hash_stable(hcx, hasher);
255 places.hash_stable(hcx, hasher);
257 mir::StatementKind::Nop => {}
258 mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
259 asm.hash_stable(hcx, hasher);
260 outputs.hash_stable(hcx, hasher);
261 inputs.hash_stable(hcx, hasher);
267 impl<'gcx, T> HashStable<StableHashingContext<'gcx>>
268 for mir::ValidationOperand<'gcx, T>
269 where T: HashStable<StableHashingContext<'gcx>>
271 fn hash_stable<W: StableHasherResult>(&self,
272 hcx: &mut StableHashingContext<'gcx>,
273 hasher: &mut StableHasher<W>)
275 self.place.hash_stable(hcx, hasher);
276 self.ty.hash_stable(hcx, hasher);
277 self.re.hash_stable(hcx, hasher);
278 self.mutbl.hash_stable(hcx, hasher);
282 impl_stable_hash_for!(enum mir::ValidationOp { Acquire, Release, Suspend(region_scope) });
284 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Place<'gcx> {
285 fn hash_stable<W: StableHasherResult>(&self,
286 hcx: &mut StableHashingContext<'gcx>,
287 hasher: &mut StableHasher<W>) {
288 mem::discriminant(self).hash_stable(hcx, hasher);
290 mir::Place::Local(ref local) => {
291 local.hash_stable(hcx, hasher);
293 mir::Place::Static(ref statik) => {
294 statik.hash_stable(hcx, hasher);
296 mir::Place::Projection(ref place_projection) => {
297 place_projection.hash_stable(hcx, hasher);
303 impl<'gcx, B, V, T> HashStable<StableHashingContext<'gcx>>
304 for mir::Projection<'gcx, B, V, T>
305 where B: HashStable<StableHashingContext<'gcx>>,
306 V: HashStable<StableHashingContext<'gcx>>,
307 T: HashStable<StableHashingContext<'gcx>>
309 fn hash_stable<W: StableHasherResult>(&self,
310 hcx: &mut StableHashingContext<'gcx>,
311 hasher: &mut StableHasher<W>) {
312 let mir::Projection {
317 base.hash_stable(hcx, hasher);
318 elem.hash_stable(hcx, hasher);
322 impl<'gcx, V, T> HashStable<StableHashingContext<'gcx>>
323 for mir::ProjectionElem<'gcx, V, T>
324 where V: HashStable<StableHashingContext<'gcx>>,
325 T: HashStable<StableHashingContext<'gcx>>
327 fn hash_stable<W: StableHasherResult>(&self,
328 hcx: &mut StableHashingContext<'gcx>,
329 hasher: &mut StableHasher<W>) {
330 mem::discriminant(self).hash_stable(hcx, hasher);
332 mir::ProjectionElem::Deref => {}
333 mir::ProjectionElem::Field(field, ref ty) => {
334 field.hash_stable(hcx, hasher);
335 ty.hash_stable(hcx, hasher);
337 mir::ProjectionElem::Index(ref value) => {
338 value.hash_stable(hcx, hasher);
340 mir::ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
341 offset.hash_stable(hcx, hasher);
342 min_length.hash_stable(hcx, hasher);
343 from_end.hash_stable(hcx, hasher);
345 mir::ProjectionElem::Subslice { from, to } => {
346 from.hash_stable(hcx, hasher);
347 to.hash_stable(hcx, hasher);
349 mir::ProjectionElem::Downcast(adt_def, variant) => {
350 adt_def.hash_stable(hcx, hasher);
351 variant.hash_stable(hcx, hasher);
357 impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope });
358 impl_stable_hash_for!(struct mir::VisibilityScopeInfo {
362 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Safety {
363 fn hash_stable<W: StableHasherResult>(&self,
364 hcx: &mut StableHashingContext<'gcx>,
365 hasher: &mut StableHasher<W>) {
366 mem::discriminant(self).hash_stable(hcx, hasher);
370 mir::Safety::BuiltinUnsafe |
371 mir::Safety::FnUnsafe => {}
372 mir::Safety::ExplicitUnsafe(node_id) => {
373 node_id.hash_stable(hcx, hasher);
379 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Operand<'gcx> {
380 fn hash_stable<W: StableHasherResult>(&self,
381 hcx: &mut StableHashingContext<'gcx>,
382 hasher: &mut StableHasher<W>) {
383 mem::discriminant(self).hash_stable(hcx, hasher);
386 mir::Operand::Copy(ref place) => {
387 place.hash_stable(hcx, hasher);
389 mir::Operand::Move(ref place) => {
390 place.hash_stable(hcx, hasher);
392 mir::Operand::Constant(ref constant) => {
393 constant.hash_stable(hcx, hasher);
399 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Rvalue<'gcx> {
400 fn hash_stable<W: StableHasherResult>(&self,
401 hcx: &mut StableHashingContext<'gcx>,
402 hasher: &mut StableHasher<W>) {
403 mem::discriminant(self).hash_stable(hcx, hasher);
406 mir::Rvalue::Use(ref operand) => {
407 operand.hash_stable(hcx, hasher);
409 mir::Rvalue::Repeat(ref operand, ref val) => {
410 operand.hash_stable(hcx, hasher);
411 val.hash_stable(hcx, hasher);
413 mir::Rvalue::Ref(region, borrow_kind, ref place) => {
414 region.hash_stable(hcx, hasher);
415 borrow_kind.hash_stable(hcx, hasher);
416 place.hash_stable(hcx, hasher);
418 mir::Rvalue::Len(ref place) => {
419 place.hash_stable(hcx, hasher);
421 mir::Rvalue::Cast(cast_kind, ref operand, ty) => {
422 cast_kind.hash_stable(hcx, hasher);
423 operand.hash_stable(hcx, hasher);
424 ty.hash_stable(hcx, hasher);
426 mir::Rvalue::BinaryOp(op, ref operand1, ref operand2) |
427 mir::Rvalue::CheckedBinaryOp(op, ref operand1, ref operand2) => {
428 op.hash_stable(hcx, hasher);
429 operand1.hash_stable(hcx, hasher);
430 operand2.hash_stable(hcx, hasher);
432 mir::Rvalue::UnaryOp(op, ref operand) => {
433 op.hash_stable(hcx, hasher);
434 operand.hash_stable(hcx, hasher);
436 mir::Rvalue::Discriminant(ref place) => {
437 place.hash_stable(hcx, hasher);
439 mir::Rvalue::NullaryOp(op, ty) => {
440 op.hash_stable(hcx, hasher);
441 ty.hash_stable(hcx, hasher);
443 mir::Rvalue::Aggregate(ref kind, ref operands) => {
444 kind.hash_stable(hcx, hasher);
445 operands.hash_stable(hcx, hasher);
451 impl_stable_hash_for!(enum mir::CastKind {
459 impl<'gcx> HashStable<StableHashingContext<'gcx>>
460 for mir::AggregateKind<'gcx> {
461 fn hash_stable<W: StableHasherResult>(&self,
462 hcx: &mut StableHashingContext<'gcx>,
463 hasher: &mut StableHasher<W>) {
464 mem::discriminant(self).hash_stable(hcx, hasher);
466 mir::AggregateKind::Tuple => {}
467 mir::AggregateKind::Array(t) => {
468 t.hash_stable(hcx, hasher);
470 mir::AggregateKind::Adt(adt_def, idx, substs, active_field) => {
471 adt_def.hash_stable(hcx, hasher);
472 idx.hash_stable(hcx, hasher);
473 substs.hash_stable(hcx, hasher);
474 active_field.hash_stable(hcx, hasher);
476 mir::AggregateKind::Closure(def_id, ref substs) => {
477 def_id.hash_stable(hcx, hasher);
478 substs.hash_stable(hcx, hasher);
480 mir::AggregateKind::Generator(def_id, ref substs, ref interior) => {
481 def_id.hash_stable(hcx, hasher);
482 substs.hash_stable(hcx, hasher);
483 interior.hash_stable(hcx, hasher);
489 impl_stable_hash_for!(enum mir::BinOp {
509 impl_stable_hash_for!(enum mir::UnOp {
514 impl_stable_hash_for!(enum mir::NullOp {
519 impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
521 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Literal<'gcx> {
522 fn hash_stable<W: StableHasherResult>(&self,
523 hcx: &mut StableHashingContext<'gcx>,
524 hasher: &mut StableHasher<W>) {
525 mem::discriminant(self).hash_stable(hcx, hasher);
527 mir::Literal::Value { ref value } => {
528 value.hash_stable(hcx, hasher);
530 mir::Literal::Promoted { index } => {
531 index.hash_stable(hcx, hasher);
537 impl_stable_hash_for!(struct mir::Location { block, statement_index });
539 impl_stable_hash_for!(struct mir::ClosureRegionRequirements<'tcx> {
541 outlives_requirements
544 impl_stable_hash_for!(struct mir::ClosureOutlivesRequirement<'tcx> {
546 outlived_free_region,
550 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::ClosureOutlivesSubject<'gcx> {
551 fn hash_stable<W: StableHasherResult>(&self,
552 hcx: &mut StableHashingContext<'gcx>,
553 hasher: &mut StableHasher<W>) {
554 mem::discriminant(self).hash_stable(hcx, hasher);
556 mir::ClosureOutlivesSubject::Ty(ref ty) => {
557 ty.hash_stable(hcx, hasher);
559 mir::ClosureOutlivesSubject::Region(ref region) => {
560 region.hash_stable(hcx, hasher);