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