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