]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_mir.rs
Merge remote-tracking branch 'origin/master' into gen
[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     is_user_variable
32 });
33 impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref });
34 impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
35
36 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
37 for mir::Terminator<'gcx> {
38     #[inline]
39     fn hash_stable<W: StableHasherResult>(&self,
40                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
41                                           hasher: &mut StableHasher<W>) {
42         let mir::Terminator {
43             ref kind,
44             ref source_info,
45         } = *self;
46
47         let hash_spans_unconditionally = match *kind {
48             mir::TerminatorKind::Assert { .. } => {
49                 // Assert terminators generate a panic message that contains the
50                 // source location, so we always have to feed its span into the
51                 // ICH.
52                 true
53             }
54             mir::TerminatorKind::Goto { .. } |
55             mir::TerminatorKind::SwitchInt { .. } |
56             mir::TerminatorKind::Resume |
57             mir::TerminatorKind::Return |
58             mir::TerminatorKind::GeneratorDrop |
59             mir::TerminatorKind::Unreachable |
60             mir::TerminatorKind::Drop { .. } |
61             mir::TerminatorKind::DropAndReplace { .. } |
62             mir::TerminatorKind::Yield { .. } |
63             mir::TerminatorKind::Call { .. } => false,
64         };
65
66         if hash_spans_unconditionally {
67             hcx.while_hashing_spans(true, |hcx| {
68                 source_info.hash_stable(hcx, hasher);
69             })
70         } else {
71             source_info.hash_stable(hcx, hasher);
72         }
73
74         kind.hash_stable(hcx, hasher);
75     }
76 }
77
78
79 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Local {
80     #[inline]
81     fn hash_stable<W: StableHasherResult>(&self,
82                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
83                                           hasher: &mut StableHasher<W>) {
84         use rustc_data_structures::indexed_vec::Idx;
85         self.index().hash_stable(hcx, hasher);
86     }
87 }
88
89 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::BasicBlock {
90     #[inline]
91     fn hash_stable<W: StableHasherResult>(&self,
92                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
93                                           hasher: &mut StableHasher<W>) {
94         use rustc_data_structures::indexed_vec::Idx;
95         self.index().hash_stable(hcx, hasher);
96     }
97 }
98
99 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Field {
100     #[inline]
101     fn hash_stable<W: StableHasherResult>(&self,
102                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
103                                           hasher: &mut StableHasher<W>) {
104         use rustc_data_structures::indexed_vec::Idx;
105         self.index().hash_stable(hcx, hasher);
106     }
107 }
108
109 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
110 for mir::VisibilityScope {
111     #[inline]
112     fn hash_stable<W: StableHasherResult>(&self,
113                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
114                                           hasher: &mut StableHasher<W>) {
115         use rustc_data_structures::indexed_vec::Idx;
116         self.index().hash_stable(hcx, hasher);
117     }
118 }
119
120 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Promoted {
121     #[inline]
122     fn hash_stable<W: StableHasherResult>(&self,
123                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
124                                           hasher: &mut StableHasher<W>) {
125         use rustc_data_structures::indexed_vec::Idx;
126         self.index().hash_stable(hcx, hasher);
127     }
128 }
129
130 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
131 for mir::TerminatorKind<'gcx> {
132     fn hash_stable<W: StableHasherResult>(&self,
133                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
134                                           hasher: &mut StableHasher<W>) {
135         mem::discriminant(self).hash_stable(hcx, hasher);
136
137         match *self {
138             mir::TerminatorKind::Goto { ref target } => {
139                 target.hash_stable(hcx, hasher);
140             }
141             mir::TerminatorKind::SwitchInt { ref discr,
142                                              switch_ty,
143                                              ref values,
144                                              ref targets } => {
145                 discr.hash_stable(hcx, hasher);
146                 switch_ty.hash_stable(hcx, hasher);
147                 values.hash_stable(hcx, hasher);
148                 targets.hash_stable(hcx, hasher);
149             }
150             mir::TerminatorKind::Resume |
151             mir::TerminatorKind::Return |
152             mir::TerminatorKind::GeneratorDrop |
153             mir::TerminatorKind::Unreachable => {}
154             mir::TerminatorKind::Drop { ref location, target, unwind } => {
155                 location.hash_stable(hcx, hasher);
156                 target.hash_stable(hcx, hasher);
157                 unwind.hash_stable(hcx, hasher);
158             }
159             mir::TerminatorKind::DropAndReplace { ref location,
160                                                   ref value,
161                                                   target,
162                                                   unwind, } => {
163                 location.hash_stable(hcx, hasher);
164                 value.hash_stable(hcx, hasher);
165                 target.hash_stable(hcx, hasher);
166                 unwind.hash_stable(hcx, hasher);
167             }
168             mir::TerminatorKind::Yield { ref value,
169                                         resume,
170                                         drop } => {
171                 value.hash_stable(hcx, hasher);
172                 resume.hash_stable(hcx, hasher);
173                 drop.hash_stable(hcx, hasher);
174             }
175             mir::TerminatorKind::Call { ref func,
176                                         ref args,
177                                         ref destination,
178                                         cleanup } => {
179                 func.hash_stable(hcx, hasher);
180                 args.hash_stable(hcx, hasher);
181                 destination.hash_stable(hcx, hasher);
182                 cleanup.hash_stable(hcx, hasher);
183             }
184             mir::TerminatorKind::Assert { ref cond,
185                                           expected,
186                                           ref msg,
187                                           target,
188                                           cleanup } => {
189                 cond.hash_stable(hcx, hasher);
190                 expected.hash_stable(hcx, hasher);
191                 msg.hash_stable(hcx, hasher);
192                 target.hash_stable(hcx, hasher);
193                 cleanup.hash_stable(hcx, hasher);
194             }
195         }
196     }
197 }
198
199 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
200 for mir::AssertMessage<'gcx> {
201     fn hash_stable<W: StableHasherResult>(&self,
202                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
203                                           hasher: &mut StableHasher<W>) {
204         mem::discriminant(self).hash_stable(hcx, hasher);
205
206         match *self {
207             mir::AssertMessage::BoundsCheck { ref len, ref index } => {
208                 len.hash_stable(hcx, hasher);
209                 index.hash_stable(hcx, hasher);
210             }
211             mir::AssertMessage::Math(ref const_math_err) => {
212                 const_math_err.hash_stable(hcx, hasher);
213             }
214             mir::AssertMessage::GeneratorResumedAfterReturn => (),
215             mir::AssertMessage::GeneratorResumedAfterPanic => (),
216         }
217     }
218 }
219
220 impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
221
222 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
223 for mir::StatementKind<'gcx> {
224     fn hash_stable<W: StableHasherResult>(&self,
225                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
226                                           hasher: &mut StableHasher<W>) {
227         mem::discriminant(self).hash_stable(hcx, hasher);
228
229         match *self {
230             mir::StatementKind::Assign(ref lvalue, ref rvalue) => {
231                 lvalue.hash_stable(hcx, hasher);
232                 rvalue.hash_stable(hcx, hasher);
233             }
234             mir::StatementKind::SetDiscriminant { ref lvalue, variant_index } => {
235                 lvalue.hash_stable(hcx, hasher);
236                 variant_index.hash_stable(hcx, hasher);
237             }
238             mir::StatementKind::StorageLive(ref lvalue) |
239             mir::StatementKind::StorageDead(ref lvalue) => {
240                 lvalue.hash_stable(hcx, hasher);
241             }
242             mir::StatementKind::EndRegion(ref extent) => {
243                 extent.hash_stable(hcx, hasher);
244             }
245             mir::StatementKind::Validate(ref op, ref lvalues) => {
246                 op.hash_stable(hcx, hasher);
247                 lvalues.hash_stable(hcx, hasher);
248             }
249             mir::StatementKind::Nop => {}
250             mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
251                 asm.hash_stable(hcx, hasher);
252                 outputs.hash_stable(hcx, hasher);
253                 inputs.hash_stable(hcx, hasher);
254             }
255         }
256     }
257 }
258
259 impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
260     for mir::ValidationOperand<'gcx, T>
261     where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
262 {
263     fn hash_stable<W: StableHasherResult>(&self,
264                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
265                                           hasher: &mut StableHasher<W>)
266     {
267         self.lval.hash_stable(hcx, hasher);
268         self.ty.hash_stable(hcx, hasher);
269         self.re.hash_stable(hcx, hasher);
270         self.mutbl.hash_stable(hcx, hasher);
271     }
272 }
273
274 impl_stable_hash_for!(enum mir::ValidationOp { Acquire, Release, Suspend(extent) });
275
276 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Lvalue<'gcx> {
277     fn hash_stable<W: StableHasherResult>(&self,
278                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
279                                           hasher: &mut StableHasher<W>) {
280         mem::discriminant(self).hash_stable(hcx, hasher);
281         match *self {
282             mir::Lvalue::Local(ref local) => {
283                 local.hash_stable(hcx, hasher);
284             }
285             mir::Lvalue::Static(ref statik) => {
286                 statik.hash_stable(hcx, hasher);
287             }
288             mir::Lvalue::Projection(ref lvalue_projection) => {
289                 lvalue_projection.hash_stable(hcx, hasher);
290             }
291         }
292     }
293 }
294
295 impl<'a, 'gcx, 'tcx, B, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
296 for mir::Projection<'gcx, B, V, T>
297     where B: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
298           V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
299           T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
300 {
301     fn hash_stable<W: StableHasherResult>(&self,
302                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
303                                           hasher: &mut StableHasher<W>) {
304         let mir::Projection {
305             ref base,
306             ref elem,
307         } = *self;
308
309         base.hash_stable(hcx, hasher);
310         elem.hash_stable(hcx, hasher);
311     }
312 }
313
314 impl<'a, 'gcx, 'tcx, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
315 for mir::ProjectionElem<'gcx, V, T>
316     where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
317           T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
318 {
319     fn hash_stable<W: StableHasherResult>(&self,
320                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
321                                           hasher: &mut StableHasher<W>) {
322         mem::discriminant(self).hash_stable(hcx, hasher);
323         match *self {
324             mir::ProjectionElem::Deref => {}
325             mir::ProjectionElem::Field(field, ref ty) => {
326                 field.hash_stable(hcx, hasher);
327                 ty.hash_stable(hcx, hasher);
328             }
329             mir::ProjectionElem::Index(ref value) => {
330                 value.hash_stable(hcx, hasher);
331             }
332             mir::ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
333                 offset.hash_stable(hcx, hasher);
334                 min_length.hash_stable(hcx, hasher);
335                 from_end.hash_stable(hcx, hasher);
336             }
337             mir::ProjectionElem::Subslice { from, to } => {
338                 from.hash_stable(hcx, hasher);
339                 to.hash_stable(hcx, hasher);
340             }
341             mir::ProjectionElem::Downcast(adt_def, variant) => {
342                 adt_def.hash_stable(hcx, hasher);
343                 variant.hash_stable(hcx, hasher);
344             }
345         }
346     }
347 }
348
349 impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope });
350
351 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Operand<'gcx> {
352     fn hash_stable<W: StableHasherResult>(&self,
353                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
354                                           hasher: &mut StableHasher<W>) {
355         mem::discriminant(self).hash_stable(hcx, hasher);
356
357         match *self {
358             mir::Operand::Consume(ref lvalue) => {
359                 lvalue.hash_stable(hcx, hasher);
360             }
361             mir::Operand::Constant(ref constant) => {
362                 constant.hash_stable(hcx, hasher);
363             }
364         }
365     }
366 }
367
368 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Rvalue<'gcx> {
369     fn hash_stable<W: StableHasherResult>(&self,
370                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
371                                           hasher: &mut StableHasher<W>) {
372         mem::discriminant(self).hash_stable(hcx, hasher);
373
374         match *self {
375             mir::Rvalue::Use(ref operand) => {
376                 operand.hash_stable(hcx, hasher);
377             }
378             mir::Rvalue::Repeat(ref operand, ref val) => {
379                 operand.hash_stable(hcx, hasher);
380                 val.hash_stable(hcx, hasher);
381             }
382             mir::Rvalue::Ref(region, borrow_kind, ref lvalue) => {
383                 region.hash_stable(hcx, hasher);
384                 borrow_kind.hash_stable(hcx, hasher);
385                 lvalue.hash_stable(hcx, hasher);
386             }
387             mir::Rvalue::Len(ref lvalue) => {
388                 lvalue.hash_stable(hcx, hasher);
389             }
390             mir::Rvalue::Cast(cast_kind, ref operand, ty) => {
391                 cast_kind.hash_stable(hcx, hasher);
392                 operand.hash_stable(hcx, hasher);
393                 ty.hash_stable(hcx, hasher);
394             }
395             mir::Rvalue::BinaryOp(op, ref operand1, ref operand2) |
396             mir::Rvalue::CheckedBinaryOp(op, ref operand1, ref operand2) => {
397                 op.hash_stable(hcx, hasher);
398                 operand1.hash_stable(hcx, hasher);
399                 operand2.hash_stable(hcx, hasher);
400             }
401             mir::Rvalue::UnaryOp(op, ref operand) => {
402                 op.hash_stable(hcx, hasher);
403                 operand.hash_stable(hcx, hasher);
404             }
405             mir::Rvalue::Discriminant(ref lvalue) => {
406                 lvalue.hash_stable(hcx, hasher);
407             }
408             mir::Rvalue::NullaryOp(op, ty) => {
409                 op.hash_stable(hcx, hasher);
410                 ty.hash_stable(hcx, hasher);
411             }
412             mir::Rvalue::Aggregate(ref kind, ref operands) => {
413                 kind.hash_stable(hcx, hasher);
414                 operands.hash_stable(hcx, hasher);
415             }
416         }
417     }
418 }
419
420 impl_stable_hash_for!(enum mir::CastKind {
421     Misc,
422     ReifyFnPointer,
423     ClosureFnPointer,
424     UnsafeFnPointer,
425     Unsize
426 });
427
428 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
429 for mir::AggregateKind<'gcx> {
430     fn hash_stable<W: StableHasherResult>(&self,
431                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
432                                           hasher: &mut StableHasher<W>) {
433         mem::discriminant(self).hash_stable(hcx, hasher);
434         match *self {
435             mir::AggregateKind::Tuple => {}
436             mir::AggregateKind::Array(t) => {
437                 t.hash_stable(hcx, hasher);
438             }
439             mir::AggregateKind::Adt(adt_def, idx, substs, active_field) => {
440                 adt_def.hash_stable(hcx, hasher);
441                 idx.hash_stable(hcx, hasher);
442                 substs.hash_stable(hcx, hasher);
443                 active_field.hash_stable(hcx, hasher);
444             }
445             mir::AggregateKind::Closure(def_id, ref substs) => {
446                 def_id.hash_stable(hcx, hasher);
447                 substs.hash_stable(hcx, hasher);
448             }
449             mir::AggregateKind::Generator(def_id, ref substs, ref interior) => {
450                 def_id.hash_stable(hcx, hasher);
451                 substs.hash_stable(hcx, hasher);
452                 interior.hash_stable(hcx, hasher);
453             }
454         }
455     }
456 }
457
458 impl_stable_hash_for!(enum mir::BinOp {
459     Add,
460     Sub,
461     Mul,
462     Div,
463     Rem,
464     BitXor,
465     BitAnd,
466     BitOr,
467     Shl,
468     Shr,
469     Eq,
470     Lt,
471     Le,
472     Ne,
473     Ge,
474     Gt,
475     Offset
476 });
477
478 impl_stable_hash_for!(enum mir::UnOp {
479     Not,
480     Neg
481 });
482
483 impl_stable_hash_for!(enum mir::NullOp {
484     Box,
485     SizeOf
486 });
487
488 impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
489
490 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Literal<'gcx> {
491     fn hash_stable<W: StableHasherResult>(&self,
492                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
493                                           hasher: &mut StableHasher<W>) {
494         mem::discriminant(self).hash_stable(hcx, hasher);
495         match *self {
496             mir::Literal::Item { def_id, substs } => {
497                 def_id.hash_stable(hcx, hasher);
498                 substs.hash_stable(hcx, hasher);
499             }
500             mir::Literal::Value { ref value } => {
501                 value.hash_stable(hcx, hasher);
502             }
503             mir::Literal::Promoted { index } => {
504                 index.hash_stable(hcx, hasher);
505             }
506         }
507     }
508 }
509
510 impl_stable_hash_for!(struct mir::Location { block, statement_index });