]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_mir.rs
Auto merge of #42304 - Mark-Simulacrum:issue-37157, r=nikomatsakis
[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> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
262 for mir::Projection<'tcx, B, V>
263     where B: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
264           V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
265 {
266     fn hash_stable<W: StableHasherResult>(&self,
267                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
268                                           hasher: &mut StableHasher<W>) {
269         let mir::Projection {
270             ref base,
271             ref elem,
272         } = *self;
273
274         base.hash_stable(hcx, hasher);
275         elem.hash_stable(hcx, hasher);
276     }
277 }
278
279 impl<'a, 'gcx, 'tcx, V> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
280 for mir::ProjectionElem<'tcx, V>
281     where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
282 {
283     fn hash_stable<W: StableHasherResult>(&self,
284                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
285                                           hasher: &mut StableHasher<W>) {
286         mem::discriminant(self).hash_stable(hcx, hasher);
287         match *self {
288             mir::ProjectionElem::Deref => {}
289             mir::ProjectionElem::Field(field, ty) => {
290                 field.hash_stable(hcx, hasher);
291                 ty.hash_stable(hcx, hasher);
292             }
293             mir::ProjectionElem::Index(ref value) => {
294                 value.hash_stable(hcx, hasher);
295             }
296             mir::ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
297                 offset.hash_stable(hcx, hasher);
298                 min_length.hash_stable(hcx, hasher);
299                 from_end.hash_stable(hcx, hasher);
300             }
301             mir::ProjectionElem::Subslice { from, to } => {
302                 from.hash_stable(hcx, hasher);
303                 to.hash_stable(hcx, hasher);
304             }
305             mir::ProjectionElem::Downcast(adt_def, variant) => {
306                 adt_def.hash_stable(hcx, hasher);
307                 variant.hash_stable(hcx, hasher);
308             }
309         }
310     }
311 }
312
313 impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope });
314
315 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Operand<'tcx> {
316     fn hash_stable<W: StableHasherResult>(&self,
317                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
318                                           hasher: &mut StableHasher<W>) {
319         mem::discriminant(self).hash_stable(hcx, hasher);
320
321         match *self {
322             mir::Operand::Consume(ref lvalue) => {
323                 lvalue.hash_stable(hcx, hasher);
324             }
325             mir::Operand::Constant(ref constant) => {
326                 constant.hash_stable(hcx, hasher);
327             }
328         }
329     }
330 }
331
332 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Rvalue<'tcx> {
333     fn hash_stable<W: StableHasherResult>(&self,
334                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
335                                           hasher: &mut StableHasher<W>) {
336         mem::discriminant(self).hash_stable(hcx, hasher);
337
338         match *self {
339             mir::Rvalue::Use(ref operand) => {
340                 operand.hash_stable(hcx, hasher);
341             }
342             mir::Rvalue::Repeat(ref operand, ref val) => {
343                 operand.hash_stable(hcx, hasher);
344                 val.hash_stable(hcx, hasher);
345             }
346             mir::Rvalue::Ref(region, borrow_kind, ref lvalue) => {
347                 region.hash_stable(hcx, hasher);
348                 borrow_kind.hash_stable(hcx, hasher);
349                 lvalue.hash_stable(hcx, hasher);
350             }
351             mir::Rvalue::Len(ref lvalue) => {
352                 lvalue.hash_stable(hcx, hasher);
353             }
354             mir::Rvalue::Cast(cast_kind, ref operand, ty) => {
355                 cast_kind.hash_stable(hcx, hasher);
356                 operand.hash_stable(hcx, hasher);
357                 ty.hash_stable(hcx, hasher);
358             }
359             mir::Rvalue::BinaryOp(op, ref operand1, ref operand2) |
360             mir::Rvalue::CheckedBinaryOp(op, ref operand1, ref operand2) => {
361                 op.hash_stable(hcx, hasher);
362                 operand1.hash_stable(hcx, hasher);
363                 operand2.hash_stable(hcx, hasher);
364             }
365             mir::Rvalue::UnaryOp(op, ref operand) => {
366                 op.hash_stable(hcx, hasher);
367                 operand.hash_stable(hcx, hasher);
368             }
369             mir::Rvalue::Discriminant(ref lvalue) => {
370                 lvalue.hash_stable(hcx, hasher);
371             }
372             mir::Rvalue::NullaryOp(op, ty) => {
373                 op.hash_stable(hcx, hasher);
374                 ty.hash_stable(hcx, hasher);
375             }
376             mir::Rvalue::Aggregate(ref kind, ref operands) => {
377                 kind.hash_stable(hcx, hasher);
378                 operands.hash_stable(hcx, hasher);
379             }
380         }
381     }
382 }
383
384 impl_stable_hash_for!(enum mir::CastKind {
385     Misc,
386     ReifyFnPointer,
387     ClosureFnPointer,
388     UnsafeFnPointer,
389     Unsize
390 });
391
392 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
393 for mir::AggregateKind<'tcx> {
394     fn hash_stable<W: StableHasherResult>(&self,
395                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
396                                           hasher: &mut StableHasher<W>) {
397         mem::discriminant(self).hash_stable(hcx, hasher);
398         match *self {
399             mir::AggregateKind::Tuple => {}
400             mir::AggregateKind::Array(t) => {
401                 t.hash_stable(hcx, hasher);
402             }
403             mir::AggregateKind::Adt(adt_def, idx, substs, active_field) => {
404                 adt_def.hash_stable(hcx, hasher);
405                 idx.hash_stable(hcx, hasher);
406                 substs.hash_stable(hcx, hasher);
407                 active_field.hash_stable(hcx, hasher);
408             }
409             mir::AggregateKind::Closure(def_id, ref substs) => {
410                 def_id.hash_stable(hcx, hasher);
411                 substs.hash_stable(hcx, hasher);
412             }
413         }
414     }
415 }
416
417 impl_stable_hash_for!(enum mir::BinOp {
418     Add,
419     Sub,
420     Mul,
421     Div,
422     Rem,
423     BitXor,
424     BitAnd,
425     BitOr,
426     Shl,
427     Shr,
428     Eq,
429     Lt,
430     Le,
431     Ne,
432     Ge,
433     Gt,
434     Offset
435 });
436
437 impl_stable_hash_for!(enum mir::UnOp {
438     Not,
439     Neg
440 });
441
442 impl_stable_hash_for!(enum mir::NullOp {
443     Box,
444     SizeOf
445 });
446
447 impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
448
449 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Literal<'tcx> {
450     fn hash_stable<W: StableHasherResult>(&self,
451                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
452                                           hasher: &mut StableHasher<W>) {
453         mem::discriminant(self).hash_stable(hcx, hasher);
454         match *self {
455             mir::Literal::Item { def_id, substs } => {
456                 def_id.hash_stable(hcx, hasher);
457                 substs.hash_stable(hcx, hasher);
458             }
459             mir::Literal::Value { ref value } => {
460                 value.hash_stable(hcx, hasher);
461             }
462             mir::Literal::Promoted { index } => {
463                 index.hash_stable(hcx, hasher);
464             }
465         }
466     }
467 }
468
469 impl_stable_hash_for!(struct mir::Location { block, statement_index });