]> git.proxmox.com Git - rustc.git/blob - src/librustc/ich/impls_mir.rs
New upstream version 1.20.0+dfsg1
[rustc.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 });