]> git.proxmox.com Git - rustc.git/blob - src/librustc/ich/impls_mir.rs
New upstream version 1.19.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, '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::NullaryOp(op, ty) => {
363 op.hash_stable(hcx, hasher);
364 ty.hash_stable(hcx, hasher);
365 }
366 mir::Rvalue::Aggregate(ref kind, ref operands) => {
367 kind.hash_stable(hcx, hasher);
368 operands.hash_stable(hcx, hasher);
369 }
370 }
371 }
372 }
373
374 impl_stable_hash_for!(enum mir::CastKind {
375 Misc,
376 ReifyFnPointer,
377 ClosureFnPointer,
378 UnsafeFnPointer,
379 Unsize
380 });
381
382 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::AggregateKind<'tcx> {
383 fn hash_stable<W: StableHasherResult>(&self,
384 hcx: &mut StableHashingContext<'a, 'tcx>,
385 hasher: &mut StableHasher<W>) {
386 mem::discriminant(self).hash_stable(hcx, hasher);
387 match *self {
388 mir::AggregateKind::Tuple => {}
389 mir::AggregateKind::Array(t) => {
390 t.hash_stable(hcx, hasher);
391 }
392 mir::AggregateKind::Adt(adt_def, idx, substs, active_field) => {
393 adt_def.hash_stable(hcx, hasher);
394 idx.hash_stable(hcx, hasher);
395 substs.hash_stable(hcx, hasher);
396 active_field.hash_stable(hcx, hasher);
397 }
398 mir::AggregateKind::Closure(def_id, ref substs) => {
399 def_id.hash_stable(hcx, hasher);
400 substs.hash_stable(hcx, hasher);
401 }
402 }
403 }
404 }
405
406 impl_stable_hash_for!(enum mir::BinOp {
407 Add,
408 Sub,
409 Mul,
410 Div,
411 Rem,
412 BitXor,
413 BitAnd,
414 BitOr,
415 Shl,
416 Shr,
417 Eq,
418 Lt,
419 Le,
420 Ne,
421 Ge,
422 Gt,
423 Offset
424 });
425
426 impl_stable_hash_for!(enum mir::UnOp {
427 Not,
428 Neg
429 });
430
431 impl_stable_hash_for!(enum mir::NullOp {
432 Box,
433 SizeOf
434 });
435
436 impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
437
438 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Literal<'tcx> {
439 fn hash_stable<W: StableHasherResult>(&self,
440 hcx: &mut StableHashingContext<'a, 'tcx>,
441 hasher: &mut StableHasher<W>) {
442 mem::discriminant(self).hash_stable(hcx, hasher);
443 match *self {
444 mir::Literal::Item { def_id, substs } => {
445 def_id.hash_stable(hcx, hasher);
446 substs.hash_stable(hcx, hasher);
447 }
448 mir::Literal::Value { ref value } => {
449 value.hash_stable(hcx, hasher);
450 }
451 mir::Literal::Promoted { index } => {
452 index.hash_stable(hcx, hasher);
453 }
454 }
455 }
456 }
457
458 impl_stable_hash_for!(struct mir::Location { block, statement_index });