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