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::LocalKind { Var, Temp, Arg, ReturnPointer });
24 impl_stable_hash_for!(struct mir::LocalDecl<'tcx> {
35 impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, var_hir_id, by_ref, mutability });
36 impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
37 impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, details, kind });
38 impl_stable_hash_for!(struct mir::UnsafetyCheckResult { violations, unsafe_blocks });
40 impl_stable_hash_for!(enum mir::BorrowKind {
44 Mut { allow_two_phase_borrow },
47 impl_stable_hash_for!(enum mir::UnsafetyViolationKind {
51 ExternStatic(lint_node_id),
52 BorrowPacked(lint_node_id),
55 impl_stable_hash_for!(struct mir::Terminator<'tcx> {
60 impl_stable_hash_for!(
61 impl<T> for enum mir::ClearCrossCrate<T> [ mir::ClearCrossCrate ] {
67 impl<'a> HashStable<StableHashingContext<'a>> for mir::Local {
69 fn hash_stable<W: StableHasherResult>(&self,
70 hcx: &mut StableHashingContext<'a>,
71 hasher: &mut StableHasher<W>) {
72 self.index().hash_stable(hcx, hasher);
76 impl<'a> HashStable<StableHashingContext<'a>> for mir::BasicBlock {
78 fn hash_stable<W: StableHasherResult>(&self,
79 hcx: &mut StableHashingContext<'a>,
80 hasher: &mut StableHasher<W>) {
81 self.index().hash_stable(hcx, hasher);
85 impl<'a> HashStable<StableHashingContext<'a>> for mir::Field {
87 fn hash_stable<W: StableHasherResult>(&self,
88 hcx: &mut StableHashingContext<'a>,
89 hasher: &mut StableHasher<W>) {
90 self.index().hash_stable(hcx, hasher);
94 impl<'a> HashStable<StableHashingContext<'a>>
95 for mir::SourceScope {
97 fn hash_stable<W: StableHasherResult>(&self,
98 hcx: &mut StableHashingContext<'a>,
99 hasher: &mut StableHasher<W>) {
100 self.index().hash_stable(hcx, hasher);
104 impl<'a> HashStable<StableHashingContext<'a>> for mir::Promoted {
106 fn hash_stable<W: StableHasherResult>(&self,
107 hcx: &mut StableHashingContext<'a>,
108 hasher: &mut StableHasher<W>) {
109 self.index().hash_stable(hcx, hasher);
113 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
114 for mir::TerminatorKind<'gcx> {
115 fn hash_stable<W: StableHasherResult>(&self,
116 hcx: &mut StableHashingContext<'a>,
117 hasher: &mut StableHasher<W>) {
118 mem::discriminant(self).hash_stable(hcx, hasher);
121 mir::TerminatorKind::Goto { ref target } => {
122 target.hash_stable(hcx, hasher);
124 mir::TerminatorKind::SwitchInt { ref discr,
128 discr.hash_stable(hcx, hasher);
129 switch_ty.hash_stable(hcx, hasher);
130 values.hash_stable(hcx, hasher);
131 targets.hash_stable(hcx, hasher);
133 mir::TerminatorKind::Resume |
134 mir::TerminatorKind::Abort |
135 mir::TerminatorKind::Return |
136 mir::TerminatorKind::GeneratorDrop |
137 mir::TerminatorKind::Unreachable => {}
138 mir::TerminatorKind::Drop { ref location, target, unwind } => {
139 location.hash_stable(hcx, hasher);
140 target.hash_stable(hcx, hasher);
141 unwind.hash_stable(hcx, hasher);
143 mir::TerminatorKind::DropAndReplace { ref location,
147 location.hash_stable(hcx, hasher);
148 value.hash_stable(hcx, hasher);
149 target.hash_stable(hcx, hasher);
150 unwind.hash_stable(hcx, hasher);
152 mir::TerminatorKind::Yield { ref value,
155 value.hash_stable(hcx, hasher);
156 resume.hash_stable(hcx, hasher);
157 drop.hash_stable(hcx, hasher);
159 mir::TerminatorKind::Call { ref func,
163 from_hir_call, } => {
164 func.hash_stable(hcx, hasher);
165 args.hash_stable(hcx, hasher);
166 destination.hash_stable(hcx, hasher);
167 cleanup.hash_stable(hcx, hasher);
168 from_hir_call.hash_stable(hcx, hasher);
170 mir::TerminatorKind::Assert { ref cond,
175 cond.hash_stable(hcx, hasher);
176 expected.hash_stable(hcx, hasher);
177 msg.hash_stable(hcx, hasher);
178 target.hash_stable(hcx, hasher);
179 cleanup.hash_stable(hcx, hasher);
181 mir::TerminatorKind::FalseEdges { ref real_target, ref imaginary_targets } => {
182 real_target.hash_stable(hcx, hasher);
183 for target in imaginary_targets {
184 target.hash_stable(hcx, hasher);
187 mir::TerminatorKind::FalseUnwind { ref real_target, ref unwind } => {
188 real_target.hash_stable(hcx, hasher);
189 unwind.hash_stable(hcx, hasher);
195 impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
197 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
198 for mir::StatementKind<'gcx> {
199 fn hash_stable<W: StableHasherResult>(&self,
200 hcx: &mut StableHashingContext<'a>,
201 hasher: &mut StableHasher<W>) {
202 mem::discriminant(self).hash_stable(hcx, hasher);
205 mir::StatementKind::Assign(ref place, ref rvalue) => {
206 place.hash_stable(hcx, hasher);
207 rvalue.hash_stable(hcx, hasher);
209 mir::StatementKind::FakeRead(ref cause, ref place) => {
210 cause.hash_stable(hcx, hasher);
211 place.hash_stable(hcx, hasher);
213 mir::StatementKind::SetDiscriminant { ref place, variant_index } => {
214 place.hash_stable(hcx, hasher);
215 variant_index.hash_stable(hcx, hasher);
217 mir::StatementKind::StorageLive(ref place) |
218 mir::StatementKind::StorageDead(ref place) => {
219 place.hash_stable(hcx, hasher);
221 mir::StatementKind::EscapeToRaw(ref place) => {
222 place.hash_stable(hcx, hasher);
224 mir::StatementKind::Retag { fn_entry, ref place } => {
225 fn_entry.hash_stable(hcx, hasher);
226 place.hash_stable(hcx, hasher);
228 mir::StatementKind::AscribeUserType(ref place, ref variance, ref c_ty) => {
229 place.hash_stable(hcx, hasher);
230 variance.hash_stable(hcx, hasher);
231 c_ty.hash_stable(hcx, hasher);
233 mir::StatementKind::Nop => {}
234 mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
235 asm.hash_stable(hcx, hasher);
236 outputs.hash_stable(hcx, hasher);
237 inputs.hash_stable(hcx, hasher);
243 impl_stable_hash_for!(enum mir::FakeReadCause { ForMatchGuard, ForMatchedPlace, ForLet });
245 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Place<'gcx> {
246 fn hash_stable<W: StableHasherResult>(&self,
247 hcx: &mut StableHashingContext<'a>,
248 hasher: &mut StableHasher<W>) {
249 mem::discriminant(self).hash_stable(hcx, hasher);
251 mir::Place::Local(ref local) => {
252 local.hash_stable(hcx, hasher);
254 mir::Place::Static(ref statik) => {
255 statik.hash_stable(hcx, hasher);
257 mir::Place::Promoted(ref promoted) => {
258 promoted.hash_stable(hcx, hasher);
260 mir::Place::Projection(ref place_projection) => {
261 place_projection.hash_stable(hcx, hasher);
267 impl<'a, 'gcx, B, V, T> HashStable<StableHashingContext<'a>>
268 for mir::Projection<'gcx, B, V, T>
269 where B: HashStable<StableHashingContext<'a>>,
270 V: HashStable<StableHashingContext<'a>>,
271 T: HashStable<StableHashingContext<'a>>
273 fn hash_stable<W: StableHasherResult>(&self,
274 hcx: &mut StableHashingContext<'a>,
275 hasher: &mut StableHasher<W>) {
276 let mir::Projection {
281 base.hash_stable(hcx, hasher);
282 elem.hash_stable(hcx, hasher);
286 impl<'a, 'gcx, V, T> HashStable<StableHashingContext<'a>>
287 for mir::ProjectionElem<'gcx, V, T>
288 where V: HashStable<StableHashingContext<'a>>,
289 T: HashStable<StableHashingContext<'a>>
291 fn hash_stable<W: StableHasherResult>(&self,
292 hcx: &mut StableHashingContext<'a>,
293 hasher: &mut StableHasher<W>) {
294 mem::discriminant(self).hash_stable(hcx, hasher);
296 mir::ProjectionElem::Deref => {}
297 mir::ProjectionElem::Field(field, ref ty) => {
298 field.hash_stable(hcx, hasher);
299 ty.hash_stable(hcx, hasher);
301 mir::ProjectionElem::Index(ref value) => {
302 value.hash_stable(hcx, hasher);
304 mir::ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
305 offset.hash_stable(hcx, hasher);
306 min_length.hash_stable(hcx, hasher);
307 from_end.hash_stable(hcx, hasher);
309 mir::ProjectionElem::Subslice { from, to } => {
310 from.hash_stable(hcx, hasher);
311 to.hash_stable(hcx, hasher);
313 mir::ProjectionElem::Downcast(adt_def, variant) => {
314 adt_def.hash_stable(hcx, hasher);
315 variant.hash_stable(hcx, hasher);
321 impl_stable_hash_for!(struct mir::SourceScopeData { span, parent_scope });
322 impl_stable_hash_for!(struct mir::SourceScopeLocalData {
326 impl<'a> HashStable<StableHashingContext<'a>> for mir::Safety {
327 fn hash_stable<W: StableHasherResult>(&self,
328 hcx: &mut StableHashingContext<'a>,
329 hasher: &mut StableHasher<W>) {
330 mem::discriminant(self).hash_stable(hcx, hasher);
334 mir::Safety::BuiltinUnsafe |
335 mir::Safety::FnUnsafe => {}
336 mir::Safety::ExplicitUnsafe(node_id) => {
337 node_id.hash_stable(hcx, hasher);
343 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Operand<'gcx> {
344 fn hash_stable<W: StableHasherResult>(&self,
345 hcx: &mut StableHashingContext<'a>,
346 hasher: &mut StableHasher<W>) {
347 mem::discriminant(self).hash_stable(hcx, hasher);
350 mir::Operand::Copy(ref place) => {
351 place.hash_stable(hcx, hasher);
353 mir::Operand::Move(ref place) => {
354 place.hash_stable(hcx, hasher);
356 mir::Operand::Constant(ref constant) => {
357 constant.hash_stable(hcx, hasher);
363 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Rvalue<'gcx> {
364 fn hash_stable<W: StableHasherResult>(&self,
365 hcx: &mut StableHashingContext<'a>,
366 hasher: &mut StableHasher<W>) {
367 mem::discriminant(self).hash_stable(hcx, hasher);
370 mir::Rvalue::Use(ref operand) => {
371 operand.hash_stable(hcx, hasher);
373 mir::Rvalue::Repeat(ref operand, ref val) => {
374 operand.hash_stable(hcx, hasher);
375 val.hash_stable(hcx, hasher);
377 mir::Rvalue::Ref(region, borrow_kind, ref place) => {
378 region.hash_stable(hcx, hasher);
379 borrow_kind.hash_stable(hcx, hasher);
380 place.hash_stable(hcx, hasher);
382 mir::Rvalue::Len(ref place) => {
383 place.hash_stable(hcx, hasher);
385 mir::Rvalue::Cast(cast_kind, ref operand, ty) => {
386 cast_kind.hash_stable(hcx, hasher);
387 operand.hash_stable(hcx, hasher);
388 ty.hash_stable(hcx, hasher);
390 mir::Rvalue::BinaryOp(op, ref operand1, ref operand2) |
391 mir::Rvalue::CheckedBinaryOp(op, ref operand1, ref operand2) => {
392 op.hash_stable(hcx, hasher);
393 operand1.hash_stable(hcx, hasher);
394 operand2.hash_stable(hcx, hasher);
396 mir::Rvalue::UnaryOp(op, ref operand) => {
397 op.hash_stable(hcx, hasher);
398 operand.hash_stable(hcx, hasher);
400 mir::Rvalue::Discriminant(ref place) => {
401 place.hash_stable(hcx, hasher);
403 mir::Rvalue::NullaryOp(op, ty) => {
404 op.hash_stable(hcx, hasher);
405 ty.hash_stable(hcx, hasher);
407 mir::Rvalue::Aggregate(ref kind, ref operands) => {
408 kind.hash_stable(hcx, hasher);
409 operands.hash_stable(hcx, hasher);
415 impl_stable_hash_for!(enum mir::CastKind {
423 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
424 for mir::AggregateKind<'gcx> {
425 fn hash_stable<W: StableHasherResult>(&self,
426 hcx: &mut StableHashingContext<'a>,
427 hasher: &mut StableHasher<W>) {
428 mem::discriminant(self).hash_stable(hcx, hasher);
430 mir::AggregateKind::Tuple => {}
431 mir::AggregateKind::Array(t) => {
432 t.hash_stable(hcx, hasher);
434 mir::AggregateKind::Adt(adt_def, idx, substs, user_substs, active_field) => {
435 adt_def.hash_stable(hcx, hasher);
436 idx.hash_stable(hcx, hasher);
437 substs.hash_stable(hcx, hasher);
438 user_substs.hash_stable(hcx, hasher);
439 active_field.hash_stable(hcx, hasher);
441 mir::AggregateKind::Closure(def_id, ref substs) => {
442 def_id.hash_stable(hcx, hasher);
443 substs.hash_stable(hcx, hasher);
445 mir::AggregateKind::Generator(def_id, ref substs, movability) => {
446 def_id.hash_stable(hcx, hasher);
447 substs.hash_stable(hcx, hasher);
448 movability.hash_stable(hcx, hasher);
454 impl_stable_hash_for!(enum mir::BinOp {
474 impl_stable_hash_for!(enum mir::UnOp {
479 impl_stable_hash_for!(enum mir::NullOp {
484 impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, user_ty, literal });
486 impl_stable_hash_for!(struct mir::Location { block, statement_index });
488 impl_stable_hash_for!(struct mir::BorrowCheckResult<'tcx> {
489 closure_requirements,
493 impl_stable_hash_for!(struct mir::ClosureRegionRequirements<'tcx> {
495 outlives_requirements
498 impl_stable_hash_for!(struct mir::ClosureOutlivesRequirement<'tcx> {
500 outlived_free_region,
505 impl_stable_hash_for!(enum mir::ConstraintCategory {
522 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::ClosureOutlivesSubject<'gcx> {
523 fn hash_stable<W: StableHasherResult>(&self,
524 hcx: &mut StableHashingContext<'a>,
525 hasher: &mut StableHasher<W>) {
526 mem::discriminant(self).hash_stable(hcx, hasher);
528 mir::ClosureOutlivesSubject::Ty(ref ty) => {
529 ty.hash_stable(hcx, hasher);
531 mir::ClosureOutlivesSubject::Region(ref region) => {
532 region.hash_stable(hcx, hasher);
538 impl_stable_hash_for!(struct mir::interpret::GlobalId<'tcx> { instance, promoted });
540 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::UserTypeAnnotation<'gcx> {
541 fn hash_stable<W: StableHasherResult>(&self,
542 hcx: &mut StableHashingContext<'a>,
543 hasher: &mut StableHasher<W>) {
544 mem::discriminant(self).hash_stable(hcx, hasher);
546 mir::UserTypeAnnotation::Ty(ref ty) => {
547 ty.hash_stable(hcx, hasher);
549 mir::UserTypeAnnotation::TypeOf(ref def_id, ref substs) => {
550 def_id.hash_stable(hcx, hasher);
551 substs.hash_stable(hcx, hasher);
557 impl_stable_hash_for!(struct mir::UserTypeProjection<'tcx> { base, projs });
558 impl_stable_hash_for!(struct mir::UserTypeProjections<'tcx> { contents });