]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_mir.rs
df67c3abbe86c79fe293f9a425ffb8d706e50951
[rust.git] / src / librustc / ich / impls_mir.rs
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.
4 //
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.
10
11 //! This module contains `HashStable` implementations for various MIR data
12 //! types in no particular order.
13
14 use ich::StableHashingContext;
15 use mir;
16 use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
17                                            StableHasherResult};
18 use std::mem;
19
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> {
26     mutability,
27     ty,
28     name,
29     source_info,
30     internal,
31     lexical_scope,
32     is_user_variable
33 });
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 });
38
39 impl<'gcx> HashStable<StableHashingContext<'gcx>>
40 for mir::UnsafetyViolationKind {
41     #[inline]
42     fn hash_stable<W: StableHasherResult>(&self,
43                                           hcx: &mut StableHashingContext<'gcx>,
44                                           hasher: &mut StableHasher<W>) {
45
46         mem::discriminant(self).hash_stable(hcx, hasher);
47
48         match *self {
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);
53             }
54
55         }
56     }
57 }
58
59 impl_stable_hash_for!(struct mir::Terminator<'tcx> {
60     kind,
61     source_info
62 });
63
64 impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for mir::ClearCrossCrate<T>
65     where T: HashStable<StableHashingContext<'gcx>>
66 {
67     #[inline]
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);
72         match *self {
73             mir::ClearCrossCrate::Clear => {}
74             mir::ClearCrossCrate::Set(ref value) => {
75                 value.hash_stable(hcx, hasher);
76             }
77         }
78     }
79 }
80
81 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Local {
82     #[inline]
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);
88     }
89 }
90
91 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::BasicBlock {
92     #[inline]
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);
98     }
99 }
100
101 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Field {
102     #[inline]
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);
108     }
109 }
110
111 impl<'gcx> HashStable<StableHashingContext<'gcx>>
112 for mir::VisibilityScope {
113     #[inline]
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);
119     }
120 }
121
122 impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Promoted {
123     #[inline]
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);
129     }
130 }
131
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);
138
139         match *self {
140             mir::TerminatorKind::Goto { ref target } => {
141                 target.hash_stable(hcx, hasher);
142             }
143             mir::TerminatorKind::SwitchInt { ref discr,
144                                              switch_ty,
145                                              ref values,
146                                              ref targets } => {
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);
151             }
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);
160             }
161             mir::TerminatorKind::DropAndReplace { ref location,
162                                                   ref value,
163                                                   target,
164                                                   unwind, } => {
165                 location.hash_stable(hcx, hasher);
166                 value.hash_stable(hcx, hasher);
167                 target.hash_stable(hcx, hasher);
168                 unwind.hash_stable(hcx, hasher);
169             }
170             mir::TerminatorKind::Yield { ref value,
171                                         resume,
172                                         drop } => {
173                 value.hash_stable(hcx, hasher);
174                 resume.hash_stable(hcx, hasher);
175                 drop.hash_stable(hcx, hasher);
176             }
177             mir::TerminatorKind::Call { ref func,
178                                         ref args,
179                                         ref destination,
180                                         cleanup } => {
181                 func.hash_stable(hcx, hasher);
182                 args.hash_stable(hcx, hasher);
183                 destination.hash_stable(hcx, hasher);
184                 cleanup.hash_stable(hcx, hasher);
185             }
186             mir::TerminatorKind::Assert { ref cond,
187                                           expected,
188                                           ref msg,
189                                           target,
190                                           cleanup } => {
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);
196             }
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);
201                 }
202             }
203         }
204     }
205 }
206
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);
213
214         match *self {
215             mir::AssertMessage::BoundsCheck { ref len, ref index } => {
216                 len.hash_stable(hcx, hasher);
217                 index.hash_stable(hcx, hasher);
218             }
219             mir::AssertMessage::Math(ref const_math_err) => {
220                 const_math_err.hash_stable(hcx, hasher);
221             }
222             mir::AssertMessage::GeneratorResumedAfterReturn => (),
223             mir::AssertMessage::GeneratorResumedAfterPanic => (),
224         }
225     }
226 }
227
228 impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
229
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);
236
237         match *self {
238             mir::StatementKind::Assign(ref place, ref rvalue) => {
239                 place.hash_stable(hcx, hasher);
240                 rvalue.hash_stable(hcx, hasher);
241             }
242             mir::StatementKind::SetDiscriminant { ref place, variant_index } => {
243                 place.hash_stable(hcx, hasher);
244                 variant_index.hash_stable(hcx, hasher);
245             }
246             mir::StatementKind::StorageLive(ref place) |
247             mir::StatementKind::StorageDead(ref place) => {
248                 place.hash_stable(hcx, hasher);
249             }
250             mir::StatementKind::EndRegion(ref region_scope) => {
251                 region_scope.hash_stable(hcx, hasher);
252             }
253             mir::StatementKind::Validate(ref op, ref places) => {
254                 op.hash_stable(hcx, hasher);
255                 places.hash_stable(hcx, hasher);
256             }
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);
262             }
263         }
264     }
265 }
266
267 impl<'gcx, T> HashStable<StableHashingContext<'gcx>>
268     for mir::ValidationOperand<'gcx, T>
269     where T: HashStable<StableHashingContext<'gcx>>
270 {
271     fn hash_stable<W: StableHasherResult>(&self,
272                                           hcx: &mut StableHashingContext<'gcx>,
273                                           hasher: &mut StableHasher<W>)
274     {
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);
279     }
280 }
281
282 impl_stable_hash_for!(enum mir::ValidationOp { Acquire, Release, Suspend(region_scope) });
283
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);
289         match *self {
290             mir::Place::Local(ref local) => {
291                 local.hash_stable(hcx, hasher);
292             }
293             mir::Place::Static(ref statik) => {
294                 statik.hash_stable(hcx, hasher);
295             }
296             mir::Place::Projection(ref place_projection) => {
297                 place_projection.hash_stable(hcx, hasher);
298             }
299         }
300     }
301 }
302
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>>
308 {
309     fn hash_stable<W: StableHasherResult>(&self,
310                                           hcx: &mut StableHashingContext<'gcx>,
311                                           hasher: &mut StableHasher<W>) {
312         let mir::Projection {
313             ref base,
314             ref elem,
315         } = *self;
316
317         base.hash_stable(hcx, hasher);
318         elem.hash_stable(hcx, hasher);
319     }
320 }
321
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>>
326 {
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);
331         match *self {
332             mir::ProjectionElem::Deref => {}
333             mir::ProjectionElem::Field(field, ref ty) => {
334                 field.hash_stable(hcx, hasher);
335                 ty.hash_stable(hcx, hasher);
336             }
337             mir::ProjectionElem::Index(ref value) => {
338                 value.hash_stable(hcx, hasher);
339             }
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);
344             }
345             mir::ProjectionElem::Subslice { from, to } => {
346                 from.hash_stable(hcx, hasher);
347                 to.hash_stable(hcx, hasher);
348             }
349             mir::ProjectionElem::Downcast(adt_def, variant) => {
350                 adt_def.hash_stable(hcx, hasher);
351                 variant.hash_stable(hcx, hasher);
352             }
353         }
354     }
355 }
356
357 impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope });
358 impl_stable_hash_for!(struct mir::VisibilityScopeInfo {
359     lint_root, safety
360 });
361
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);
367
368         match *self {
369             mir::Safety::Safe |
370             mir::Safety::BuiltinUnsafe |
371             mir::Safety::FnUnsafe => {}
372             mir::Safety::ExplicitUnsafe(node_id) => {
373                 node_id.hash_stable(hcx, hasher);
374             }
375         }
376     }
377 }
378
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);
384
385         match *self {
386             mir::Operand::Copy(ref place) => {
387                 place.hash_stable(hcx, hasher);
388             }
389             mir::Operand::Move(ref place) => {
390                 place.hash_stable(hcx, hasher);
391             }
392             mir::Operand::Constant(ref constant) => {
393                 constant.hash_stable(hcx, hasher);
394             }
395         }
396     }
397 }
398
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);
404
405         match *self {
406             mir::Rvalue::Use(ref operand) => {
407                 operand.hash_stable(hcx, hasher);
408             }
409             mir::Rvalue::Repeat(ref operand, ref val) => {
410                 operand.hash_stable(hcx, hasher);
411                 val.hash_stable(hcx, hasher);
412             }
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);
417             }
418             mir::Rvalue::Len(ref place) => {
419                 place.hash_stable(hcx, hasher);
420             }
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);
425             }
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);
431             }
432             mir::Rvalue::UnaryOp(op, ref operand) => {
433                 op.hash_stable(hcx, hasher);
434                 operand.hash_stable(hcx, hasher);
435             }
436             mir::Rvalue::Discriminant(ref place) => {
437                 place.hash_stable(hcx, hasher);
438             }
439             mir::Rvalue::NullaryOp(op, ty) => {
440                 op.hash_stable(hcx, hasher);
441                 ty.hash_stable(hcx, hasher);
442             }
443             mir::Rvalue::Aggregate(ref kind, ref operands) => {
444                 kind.hash_stable(hcx, hasher);
445                 operands.hash_stable(hcx, hasher);
446             }
447         }
448     }
449 }
450
451 impl_stable_hash_for!(enum mir::CastKind {
452     Misc,
453     ReifyFnPointer,
454     ClosureFnPointer,
455     UnsafeFnPointer,
456     Unsize
457 });
458
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);
465         match *self {
466             mir::AggregateKind::Tuple => {}
467             mir::AggregateKind::Array(t) => {
468                 t.hash_stable(hcx, hasher);
469             }
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);
475             }
476             mir::AggregateKind::Closure(def_id, ref substs) => {
477                 def_id.hash_stable(hcx, hasher);
478                 substs.hash_stable(hcx, hasher);
479             }
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);
484             }
485         }
486     }
487 }
488
489 impl_stable_hash_for!(enum mir::BinOp {
490     Add,
491     Sub,
492     Mul,
493     Div,
494     Rem,
495     BitXor,
496     BitAnd,
497     BitOr,
498     Shl,
499     Shr,
500     Eq,
501     Lt,
502     Le,
503     Ne,
504     Ge,
505     Gt,
506     Offset
507 });
508
509 impl_stable_hash_for!(enum mir::UnOp {
510     Not,
511     Neg
512 });
513
514 impl_stable_hash_for!(enum mir::NullOp {
515     Box,
516     SizeOf
517 });
518
519 impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
520
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);
526         match *self {
527             mir::Literal::Value { ref value } => {
528                 value.hash_stable(hcx, hasher);
529             }
530             mir::Literal::Promoted { index } => {
531                 index.hash_stable(hcx, hasher);
532             }
533         }
534     }
535 }
536
537 impl_stable_hash_for!(struct mir::Location { block, statement_index });
538
539 impl_stable_hash_for!(struct mir::ClosureRegionRequirements<'tcx> {
540     num_external_vids,
541     outlives_requirements
542 });
543
544 impl_stable_hash_for!(struct mir::ClosureOutlivesRequirement<'tcx> {
545     subject,
546     outlived_free_region,
547     blame_span
548 });
549
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);
555         match *self {
556             mir::ClosureOutlivesSubject::Ty(ref ty) => {
557                 ty.hash_stable(hcx, hasher);
558             }
559             mir::ClosureOutlivesSubject::Region(ref region) => {
560                 region.hash_stable(hcx, hasher);
561             }
562         }
563     }
564 }