]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_mir.rs
c72887124aa0b4ab7b11619d032fa9b5507841a9
[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::LocalKind { Var, Temp, Arg, ReturnPointer });
24 impl_stable_hash_for!(struct mir::LocalDecl<'tcx> {
25     mutability,
26     ty,
27     user_ty,
28     name,
29     source_info,
30     visibility_scope,
31     internal,
32     is_block_tail,
33     is_user_variable
34 });
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 });
39
40 impl_stable_hash_for!(enum mir::BorrowKind {
41     Shared,
42     Shallow,
43     Unique,
44     Mut { allow_two_phase_borrow },
45 });
46
47 impl_stable_hash_for!(enum mir::UnsafetyViolationKind {
48     General,
49     GeneralAndConstFn,
50     GatedConstFnCall,
51     ExternStatic(lint_node_id),
52     BorrowPacked(lint_node_id),
53 });
54
55 impl_stable_hash_for!(struct mir::Terminator<'tcx> {
56     kind,
57     source_info
58 });
59
60 impl_stable_hash_for!(
61     impl<T> for enum mir::ClearCrossCrate<T> [ mir::ClearCrossCrate ] {
62         Clear,
63         Set(value),
64     }
65 );
66
67 impl<'a> HashStable<StableHashingContext<'a>> for mir::Local {
68     #[inline]
69     fn hash_stable<W: StableHasherResult>(&self,
70                                           hcx: &mut StableHashingContext<'a>,
71                                           hasher: &mut StableHasher<W>) {
72         self.index().hash_stable(hcx, hasher);
73     }
74 }
75
76 impl<'a> HashStable<StableHashingContext<'a>> for mir::BasicBlock {
77     #[inline]
78     fn hash_stable<W: StableHasherResult>(&self,
79                                           hcx: &mut StableHashingContext<'a>,
80                                           hasher: &mut StableHasher<W>) {
81         self.index().hash_stable(hcx, hasher);
82     }
83 }
84
85 impl<'a> HashStable<StableHashingContext<'a>> for mir::Field {
86     #[inline]
87     fn hash_stable<W: StableHasherResult>(&self,
88                                           hcx: &mut StableHashingContext<'a>,
89                                           hasher: &mut StableHasher<W>) {
90         self.index().hash_stable(hcx, hasher);
91     }
92 }
93
94 impl<'a> HashStable<StableHashingContext<'a>>
95 for mir::SourceScope {
96     #[inline]
97     fn hash_stable<W: StableHasherResult>(&self,
98                                           hcx: &mut StableHashingContext<'a>,
99                                           hasher: &mut StableHasher<W>) {
100         self.index().hash_stable(hcx, hasher);
101     }
102 }
103
104 impl<'a> HashStable<StableHashingContext<'a>> for mir::Promoted {
105     #[inline]
106     fn hash_stable<W: StableHasherResult>(&self,
107                                           hcx: &mut StableHashingContext<'a>,
108                                           hasher: &mut StableHasher<W>) {
109         self.index().hash_stable(hcx, hasher);
110     }
111 }
112
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);
119
120         match *self {
121             mir::TerminatorKind::Goto { ref target } => {
122                 target.hash_stable(hcx, hasher);
123             }
124             mir::TerminatorKind::SwitchInt { ref discr,
125                                              switch_ty,
126                                              ref values,
127                                              ref targets } => {
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);
132             }
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);
142             }
143             mir::TerminatorKind::DropAndReplace { ref location,
144                                                   ref value,
145                                                   target,
146                                                   unwind, } => {
147                 location.hash_stable(hcx, hasher);
148                 value.hash_stable(hcx, hasher);
149                 target.hash_stable(hcx, hasher);
150                 unwind.hash_stable(hcx, hasher);
151             }
152             mir::TerminatorKind::Yield { ref value,
153                                         resume,
154                                         drop } => {
155                 value.hash_stable(hcx, hasher);
156                 resume.hash_stable(hcx, hasher);
157                 drop.hash_stable(hcx, hasher);
158             }
159             mir::TerminatorKind::Call { ref func,
160                                         ref args,
161                                         ref destination,
162                                         cleanup,
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);
169             }
170             mir::TerminatorKind::Assert { ref cond,
171                                           expected,
172                                           ref msg,
173                                           target,
174                                           cleanup } => {
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);
180             }
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);
185                 }
186             }
187             mir::TerminatorKind::FalseUnwind { ref real_target, ref unwind } => {
188                 real_target.hash_stable(hcx, hasher);
189                 unwind.hash_stable(hcx, hasher);
190             }
191         }
192     }
193 }
194
195 impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
196
197 impl_stable_hash_for!(impl<'gcx> for enum mir::StatementKind<'gcx> [ mir::StatementKind ] {
198     Assign(place, rvalue),
199     FakeRead(cause, place),
200     SetDiscriminant { place, variant_index },
201     StorageLive(place),
202     StorageDead(place),
203     EscapeToRaw(place),
204     Retag { fn_entry, two_phase, place },
205     AscribeUserType(place, variance, c_ty),
206     Nop,
207     InlineAsm { asm, outputs, inputs },
208 });
209
210 impl_stable_hash_for!(enum mir::FakeReadCause { ForMatchGuard, ForMatchedPlace, ForLet });
211
212 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Place<'gcx> {
213     fn hash_stable<W: StableHasherResult>(&self,
214                                           hcx: &mut StableHashingContext<'a>,
215                                           hasher: &mut StableHasher<W>) {
216         mem::discriminant(self).hash_stable(hcx, hasher);
217         match *self {
218             mir::Place::Local(ref local) => {
219                 local.hash_stable(hcx, hasher);
220             }
221             mir::Place::Static(ref statik) => {
222                 statik.hash_stable(hcx, hasher);
223             }
224             mir::Place::Promoted(ref promoted) => {
225                 promoted.hash_stable(hcx, hasher);
226             }
227             mir::Place::Projection(ref place_projection) => {
228                 place_projection.hash_stable(hcx, hasher);
229             }
230         }
231     }
232 }
233
234 impl<'a, 'gcx, B, V, T> HashStable<StableHashingContext<'a>>
235 for mir::Projection<'gcx, B, V, T>
236     where B: HashStable<StableHashingContext<'a>>,
237           V: HashStable<StableHashingContext<'a>>,
238           T: HashStable<StableHashingContext<'a>>
239 {
240     fn hash_stable<W: StableHasherResult>(&self,
241                                           hcx: &mut StableHashingContext<'a>,
242                                           hasher: &mut StableHasher<W>) {
243         let mir::Projection {
244             ref base,
245             ref elem,
246         } = *self;
247
248         base.hash_stable(hcx, hasher);
249         elem.hash_stable(hcx, hasher);
250     }
251 }
252
253 impl<'a, 'gcx, V, T> HashStable<StableHashingContext<'a>>
254 for mir::ProjectionElem<'gcx, V, T>
255     where V: HashStable<StableHashingContext<'a>>,
256           T: HashStable<StableHashingContext<'a>>
257 {
258     fn hash_stable<W: StableHasherResult>(&self,
259                                           hcx: &mut StableHashingContext<'a>,
260                                           hasher: &mut StableHasher<W>) {
261         mem::discriminant(self).hash_stable(hcx, hasher);
262         match *self {
263             mir::ProjectionElem::Deref => {}
264             mir::ProjectionElem::Field(field, ref ty) => {
265                 field.hash_stable(hcx, hasher);
266                 ty.hash_stable(hcx, hasher);
267             }
268             mir::ProjectionElem::Index(ref value) => {
269                 value.hash_stable(hcx, hasher);
270             }
271             mir::ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
272                 offset.hash_stable(hcx, hasher);
273                 min_length.hash_stable(hcx, hasher);
274                 from_end.hash_stable(hcx, hasher);
275             }
276             mir::ProjectionElem::Subslice { from, to } => {
277                 from.hash_stable(hcx, hasher);
278                 to.hash_stable(hcx, hasher);
279             }
280             mir::ProjectionElem::Downcast(adt_def, variant) => {
281                 adt_def.hash_stable(hcx, hasher);
282                 variant.hash_stable(hcx, hasher);
283             }
284         }
285     }
286 }
287
288 impl_stable_hash_for!(struct mir::SourceScopeData { span, parent_scope });
289 impl_stable_hash_for!(struct mir::SourceScopeLocalData {
290     lint_root, safety
291 });
292
293 impl<'a> HashStable<StableHashingContext<'a>> for mir::Safety {
294     fn hash_stable<W: StableHasherResult>(&self,
295                                           hcx: &mut StableHashingContext<'a>,
296                                           hasher: &mut StableHasher<W>) {
297         mem::discriminant(self).hash_stable(hcx, hasher);
298
299         match *self {
300             mir::Safety::Safe |
301             mir::Safety::BuiltinUnsafe |
302             mir::Safety::FnUnsafe => {}
303             mir::Safety::ExplicitUnsafe(node_id) => {
304                 node_id.hash_stable(hcx, hasher);
305             }
306         }
307     }
308 }
309
310 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Operand<'gcx> {
311     fn hash_stable<W: StableHasherResult>(&self,
312                                           hcx: &mut StableHashingContext<'a>,
313                                           hasher: &mut StableHasher<W>) {
314         mem::discriminant(self).hash_stable(hcx, hasher);
315
316         match *self {
317             mir::Operand::Copy(ref place) => {
318                 place.hash_stable(hcx, hasher);
319             }
320             mir::Operand::Move(ref place) => {
321                 place.hash_stable(hcx, hasher);
322             }
323             mir::Operand::Constant(ref constant) => {
324                 constant.hash_stable(hcx, hasher);
325             }
326         }
327     }
328 }
329
330 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Rvalue<'gcx> {
331     fn hash_stable<W: StableHasherResult>(&self,
332                                           hcx: &mut StableHashingContext<'a>,
333                                           hasher: &mut StableHasher<W>) {
334         mem::discriminant(self).hash_stable(hcx, hasher);
335
336         match *self {
337             mir::Rvalue::Use(ref operand) => {
338                 operand.hash_stable(hcx, hasher);
339             }
340             mir::Rvalue::Repeat(ref operand, ref val) => {
341                 operand.hash_stable(hcx, hasher);
342                 val.hash_stable(hcx, hasher);
343             }
344             mir::Rvalue::Ref(region, borrow_kind, ref place) => {
345                 region.hash_stable(hcx, hasher);
346                 borrow_kind.hash_stable(hcx, hasher);
347                 place.hash_stable(hcx, hasher);
348             }
349             mir::Rvalue::Len(ref place) => {
350                 place.hash_stable(hcx, hasher);
351             }
352             mir::Rvalue::Cast(cast_kind, ref operand, ty) => {
353                 cast_kind.hash_stable(hcx, hasher);
354                 operand.hash_stable(hcx, hasher);
355                 ty.hash_stable(hcx, hasher);
356             }
357             mir::Rvalue::BinaryOp(op, ref operand1, ref operand2) |
358             mir::Rvalue::CheckedBinaryOp(op, ref operand1, ref operand2) => {
359                 op.hash_stable(hcx, hasher);
360                 operand1.hash_stable(hcx, hasher);
361                 operand2.hash_stable(hcx, hasher);
362             }
363             mir::Rvalue::UnaryOp(op, ref operand) => {
364                 op.hash_stable(hcx, hasher);
365                 operand.hash_stable(hcx, hasher);
366             }
367             mir::Rvalue::Discriminant(ref place) => {
368                 place.hash_stable(hcx, hasher);
369             }
370             mir::Rvalue::NullaryOp(op, ty) => {
371                 op.hash_stable(hcx, hasher);
372                 ty.hash_stable(hcx, hasher);
373             }
374             mir::Rvalue::Aggregate(ref kind, ref operands) => {
375                 kind.hash_stable(hcx, hasher);
376                 operands.hash_stable(hcx, hasher);
377             }
378         }
379     }
380 }
381
382 impl_stable_hash_for!(enum mir::CastKind {
383     Misc,
384     ReifyFnPointer,
385     ClosureFnPointer,
386     UnsafeFnPointer,
387     Unsize
388 });
389
390 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
391 for mir::AggregateKind<'gcx> {
392     fn hash_stable<W: StableHasherResult>(&self,
393                                           hcx: &mut StableHashingContext<'a>,
394                                           hasher: &mut StableHasher<W>) {
395         mem::discriminant(self).hash_stable(hcx, hasher);
396         match *self {
397             mir::AggregateKind::Tuple => {}
398             mir::AggregateKind::Array(t) => {
399                 t.hash_stable(hcx, hasher);
400             }
401             mir::AggregateKind::Adt(adt_def, idx, substs, user_substs, active_field) => {
402                 adt_def.hash_stable(hcx, hasher);
403                 idx.hash_stable(hcx, hasher);
404                 substs.hash_stable(hcx, hasher);
405                 user_substs.hash_stable(hcx, hasher);
406                 active_field.hash_stable(hcx, hasher);
407             }
408             mir::AggregateKind::Closure(def_id, ref substs) => {
409                 def_id.hash_stable(hcx, hasher);
410                 substs.hash_stable(hcx, hasher);
411             }
412             mir::AggregateKind::Generator(def_id, ref substs, movability) => {
413                 def_id.hash_stable(hcx, hasher);
414                 substs.hash_stable(hcx, hasher);
415                 movability.hash_stable(hcx, hasher);
416             }
417         }
418     }
419 }
420
421 impl_stable_hash_for!(enum mir::BinOp {
422     Add,
423     Sub,
424     Mul,
425     Div,
426     Rem,
427     BitXor,
428     BitAnd,
429     BitOr,
430     Shl,
431     Shr,
432     Eq,
433     Lt,
434     Le,
435     Ne,
436     Ge,
437     Gt,
438     Offset
439 });
440
441 impl_stable_hash_for!(enum mir::UnOp {
442     Not,
443     Neg
444 });
445
446 impl_stable_hash_for!(enum mir::NullOp {
447     Box,
448     SizeOf
449 });
450
451 impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, user_ty, literal });
452
453 impl_stable_hash_for!(struct mir::Location { block, statement_index });
454
455 impl_stable_hash_for!(struct mir::BorrowCheckResult<'tcx> {
456     closure_requirements,
457     used_mut_upvars
458 });
459
460 impl_stable_hash_for!(struct mir::ClosureRegionRequirements<'tcx> {
461     num_external_vids,
462     outlives_requirements
463 });
464
465 impl_stable_hash_for!(struct mir::ClosureOutlivesRequirement<'tcx> {
466     subject,
467     outlived_free_region,
468     blame_span,
469     category
470 });
471
472 impl_stable_hash_for!(enum mir::ConstraintCategory {
473     Return,
474     UseAsConst,
475     UseAsStatic,
476     TypeAnnotation,
477     Cast,
478     ClosureBounds,
479     CallArgument,
480     CopyBound,
481     SizedBound,
482     Assignment,
483     OpaqueType,
484     Boring,
485     BoringNoLocation,
486     Internal,
487 });
488
489 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::ClosureOutlivesSubject<'gcx> {
490     fn hash_stable<W: StableHasherResult>(&self,
491                                           hcx: &mut StableHashingContext<'a>,
492                                           hasher: &mut StableHasher<W>) {
493         mem::discriminant(self).hash_stable(hcx, hasher);
494         match *self {
495             mir::ClosureOutlivesSubject::Ty(ref ty) => {
496                 ty.hash_stable(hcx, hasher);
497             }
498             mir::ClosureOutlivesSubject::Region(ref region) => {
499                 region.hash_stable(hcx, hasher);
500             }
501         }
502     }
503 }
504
505 impl_stable_hash_for!(struct mir::interpret::GlobalId<'tcx> { instance, promoted });
506
507 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::UserTypeAnnotation<'gcx> {
508     fn hash_stable<W: StableHasherResult>(&self,
509                                           hcx: &mut StableHashingContext<'a>,
510                                           hasher: &mut StableHasher<W>) {
511         mem::discriminant(self).hash_stable(hcx, hasher);
512         match *self {
513             mir::UserTypeAnnotation::Ty(ref ty) => {
514                 ty.hash_stable(hcx, hasher);
515             }
516             mir::UserTypeAnnotation::TypeOf(ref def_id, ref substs) => {
517                 def_id.hash_stable(hcx, hasher);
518                 substs.hash_stable(hcx, hasher);
519             }
520         }
521     }
522 }
523
524 impl_stable_hash_for!(struct mir::UserTypeProjection<'tcx> { base, projs });
525 impl_stable_hash_for!(struct mir::UserTypeProjections<'tcx> { contents });