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.
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.
11 //! This module contains `HashStable` implementations for various MIR data
12 //! types in no particular order.
14 use ich::StableHashingContext;
16 use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
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> {
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 });
35 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Terminator<'tcx> {
37 fn hash_stable<W: StableHasherResult>(&self,
38 hcx: &mut StableHashingContext<'a, 'tcx>,
39 hasher: &mut StableHasher<W>) {
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
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,
62 if hash_spans_unconditionally {
63 hcx.while_hashing_spans(true, |hcx| {
64 source_info.hash_stable(hcx, hasher);
67 source_info.hash_stable(hcx, hasher);
70 kind.hash_stable(hcx, hasher);
75 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Local {
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);
85 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::BasicBlock {
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);
95 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Field {
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);
105 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::VisibilityScope {
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);
115 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Promoted {
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);
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);
132 mir::TerminatorKind::Goto { ref target } => {
133 target.hash_stable(hcx, hasher);
135 mir::TerminatorKind::SwitchInt { ref discr,
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);
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);
152 mir::TerminatorKind::DropAndReplace { ref location,
156 location.hash_stable(hcx, hasher);
157 value.hash_stable(hcx, hasher);
158 target.hash_stable(hcx, hasher);
159 unwind.hash_stable(hcx, hasher);
161 mir::TerminatorKind::Call { ref func,
165 func.hash_stable(hcx, hasher);
166 args.hash_stable(hcx, hasher);
167 destination.hash_stable(hcx, hasher);
168 cleanup.hash_stable(hcx, hasher);
170 mir::TerminatorKind::Assert { ref cond,
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);
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);
192 mir::AssertMessage::BoundsCheck { ref len, ref index } => {
193 len.hash_stable(hcx, hasher);
194 index.hash_stable(hcx, hasher);
196 mir::AssertMessage::Math(ref const_math_err) => {
197 const_math_err.hash_stable(hcx, hasher);
203 impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
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);
212 mir::StatementKind::Assign(ref lvalue, ref rvalue) => {
213 lvalue.hash_stable(hcx, hasher);
214 rvalue.hash_stable(hcx, hasher);
216 mir::StatementKind::SetDiscriminant { ref lvalue, variant_index } => {
217 lvalue.hash_stable(hcx, hasher);
218 variant_index.hash_stable(hcx, hasher);
220 mir::StatementKind::StorageLive(ref lvalue) |
221 mir::StatementKind::StorageDead(ref lvalue) => {
222 lvalue.hash_stable(hcx, hasher);
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);
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);
240 mir::Lvalue::Local(ref local) => {
241 local.hash_stable(hcx, hasher);
243 mir::Lvalue::Static(ref statik) => {
244 statik.hash_stable(hcx, hasher);
246 mir::Lvalue::Projection(ref lvalue_projection) => {
247 lvalue_projection.hash_stable(hcx, hasher);
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>>
257 fn hash_stable<W: StableHasherResult>(&self,
258 hcx: &mut StableHashingContext<'a, 'tcx>,
259 hasher: &mut StableHasher<W>) {
260 let mir::Projection {
265 base.hash_stable(hcx, hasher);
266 elem.hash_stable(hcx, hasher);
270 impl<'a, 'tcx, V> HashStable<StableHashingContext<'a, 'tcx>> for mir::ProjectionElem<'tcx, V>
271 where V: HashStable<StableHashingContext<'a, 'tcx>>
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);
278 mir::ProjectionElem::Deref => {}
279 mir::ProjectionElem::Field(field, ty) => {
280 field.hash_stable(hcx, hasher);
281 ty.hash_stable(hcx, hasher);
283 mir::ProjectionElem::Index(ref value) => {
284 value.hash_stable(hcx, hasher);
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);
291 mir::ProjectionElem::Subslice { from, to } => {
292 from.hash_stable(hcx, hasher);
293 to.hash_stable(hcx, hasher);
295 mir::ProjectionElem::Downcast(adt_def, variant) => {
296 adt_def.hash_stable(hcx, hasher);
297 variant.hash_stable(hcx, hasher);
303 impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope });
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);
312 mir::Operand::Consume(ref lvalue) => {
313 lvalue.hash_stable(hcx, hasher);
315 mir::Operand::Constant(ref constant) => {
316 constant.hash_stable(hcx, hasher);
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);
329 mir::Rvalue::Use(ref operand) => {
330 operand.hash_stable(hcx, hasher);
332 mir::Rvalue::Repeat(ref operand, ref val) => {
333 operand.hash_stable(hcx, hasher);
334 val.hash_stable(hcx, hasher);
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);
341 mir::Rvalue::Len(ref lvalue) => {
342 lvalue.hash_stable(hcx, hasher);
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);
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);
355 mir::Rvalue::UnaryOp(op, ref operand) => {
356 op.hash_stable(hcx, hasher);
357 operand.hash_stable(hcx, hasher);
359 mir::Rvalue::Discriminant(ref lvalue) => {
360 lvalue.hash_stable(hcx, hasher);
362 mir::Rvalue::Box(ty) => {
363 ty.hash_stable(hcx, hasher);
365 mir::Rvalue::Aggregate(ref kind, ref operands) => {
366 kind.hash_stable(hcx, hasher);
367 operands.hash_stable(hcx, hasher);
373 impl_stable_hash_for!(enum mir::CastKind {
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);
387 mir::AggregateKind::Tuple => {}
388 mir::AggregateKind::Array(t) => {
389 t.hash_stable(hcx, hasher);
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);
397 mir::AggregateKind::Closure(def_id, ref substs) => {
398 def_id.hash_stable(hcx, hasher);
399 substs.hash_stable(hcx, hasher);
405 impl_stable_hash_for!(enum mir::BinOp {
424 impl_stable_hash_for!(enum mir::UnOp {
430 impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
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);
438 mir::Literal::Item { def_id, substs } => {
439 def_id.hash_stable(hcx, hasher);
440 substs.hash_stable(hcx, hasher);
442 mir::Literal::Value { ref value } => {
443 value.hash_stable(hcx, hasher);
445 mir::Literal::Promoted { index } => {
446 index.hash_stable(hcx, hasher);
452 impl_stable_hash_for!(struct mir::Location { block, statement_index });