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