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> { mutability, ty, name, source_info,
27 impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref });
28 impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
29 impl_stable_hash_for!(struct mir::Terminator<'tcx> { source_info, kind });
31 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Local {
33 fn hash_stable<W: StableHasherResult>(&self,
34 hcx: &mut StableHashingContext<'a, 'tcx>,
35 hasher: &mut StableHasher<W>) {
36 use rustc_data_structures::indexed_vec::Idx;
37 self.index().hash_stable(hcx, hasher);
41 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::BasicBlock {
43 fn hash_stable<W: StableHasherResult>(&self,
44 hcx: &mut StableHashingContext<'a, 'tcx>,
45 hasher: &mut StableHasher<W>) {
46 use rustc_data_structures::indexed_vec::Idx;
47 self.index().hash_stable(hcx, hasher);
51 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Field {
53 fn hash_stable<W: StableHasherResult>(&self,
54 hcx: &mut StableHashingContext<'a, 'tcx>,
55 hasher: &mut StableHasher<W>) {
56 use rustc_data_structures::indexed_vec::Idx;
57 self.index().hash_stable(hcx, hasher);
61 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::VisibilityScope {
63 fn hash_stable<W: StableHasherResult>(&self,
64 hcx: &mut StableHashingContext<'a, 'tcx>,
65 hasher: &mut StableHasher<W>) {
66 use rustc_data_structures::indexed_vec::Idx;
67 self.index().hash_stable(hcx, hasher);
71 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Promoted {
73 fn hash_stable<W: StableHasherResult>(&self,
74 hcx: &mut StableHashingContext<'a, 'tcx>,
75 hasher: &mut StableHasher<W>) {
76 use rustc_data_structures::indexed_vec::Idx;
77 self.index().hash_stable(hcx, hasher);
81 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::TerminatorKind<'tcx> {
82 fn hash_stable<W: StableHasherResult>(&self,
83 hcx: &mut StableHashingContext<'a, 'tcx>,
84 hasher: &mut StableHasher<W>) {
85 mem::discriminant(self).hash_stable(hcx, hasher);
88 mir::TerminatorKind::Goto { ref target } => {
89 target.hash_stable(hcx, hasher);
91 mir::TerminatorKind::SwitchInt { ref discr,
95 discr.hash_stable(hcx, hasher);
96 switch_ty.hash_stable(hcx, hasher);
97 values.hash_stable(hcx, hasher);
98 targets.hash_stable(hcx, hasher);
100 mir::TerminatorKind::Resume |
101 mir::TerminatorKind::Return |
102 mir::TerminatorKind::Unreachable => {}
103 mir::TerminatorKind::Drop { ref location, target, unwind } => {
104 location.hash_stable(hcx, hasher);
105 target.hash_stable(hcx, hasher);
106 unwind.hash_stable(hcx, hasher);
108 mir::TerminatorKind::DropAndReplace { ref location,
112 location.hash_stable(hcx, hasher);
113 value.hash_stable(hcx, hasher);
114 target.hash_stable(hcx, hasher);
115 unwind.hash_stable(hcx, hasher);
117 mir::TerminatorKind::Call { ref func,
121 func.hash_stable(hcx, hasher);
122 args.hash_stable(hcx, hasher);
123 destination.hash_stable(hcx, hasher);
124 cleanup.hash_stable(hcx, hasher);
126 mir::TerminatorKind::Assert { ref cond,
131 cond.hash_stable(hcx, hasher);
132 expected.hash_stable(hcx, hasher);
133 msg.hash_stable(hcx, hasher);
134 target.hash_stable(hcx, hasher);
135 cleanup.hash_stable(hcx, hasher);
141 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::AssertMessage<'tcx> {
142 fn hash_stable<W: StableHasherResult>(&self,
143 hcx: &mut StableHashingContext<'a, 'tcx>,
144 hasher: &mut StableHasher<W>) {
145 mem::discriminant(self).hash_stable(hcx, hasher);
148 mir::AssertMessage::BoundsCheck { ref len, ref index } => {
149 len.hash_stable(hcx, hasher);
150 index.hash_stable(hcx, hasher);
152 mir::AssertMessage::Math(ref const_math_err) => {
153 const_math_err.hash_stable(hcx, hasher);
159 impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
161 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::StatementKind<'tcx> {
162 fn hash_stable<W: StableHasherResult>(&self,
163 hcx: &mut StableHashingContext<'a, 'tcx>,
164 hasher: &mut StableHasher<W>) {
165 mem::discriminant(self).hash_stable(hcx, hasher);
168 mir::StatementKind::Assign(ref lvalue, ref rvalue) => {
169 lvalue.hash_stable(hcx, hasher);
170 rvalue.hash_stable(hcx, hasher);
172 mir::StatementKind::SetDiscriminant { ref lvalue, variant_index } => {
173 lvalue.hash_stable(hcx, hasher);
174 variant_index.hash_stable(hcx, hasher);
176 mir::StatementKind::StorageLive(ref lvalue) |
177 mir::StatementKind::StorageDead(ref lvalue) => {
178 lvalue.hash_stable(hcx, hasher);
180 mir::StatementKind::Nop => {}
181 mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
182 asm.hash_stable(hcx, hasher);
183 outputs.hash_stable(hcx, hasher);
184 inputs.hash_stable(hcx, hasher);
190 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Lvalue<'tcx> {
191 fn hash_stable<W: StableHasherResult>(&self,
192 hcx: &mut StableHashingContext<'a, 'tcx>,
193 hasher: &mut StableHasher<W>) {
194 mem::discriminant(self).hash_stable(hcx, hasher);
196 mir::Lvalue::Local(ref local) => {
197 local.hash_stable(hcx, hasher);
199 mir::Lvalue::Static(ref statik) => {
200 statik.hash_stable(hcx, hasher);
202 mir::Lvalue::Projection(ref lvalue_projection) => {
203 lvalue_projection.hash_stable(hcx, hasher);
209 impl<'a, 'tcx, B, V> HashStable<StableHashingContext<'a, 'tcx>> for mir::Projection<'tcx, B, V>
210 where B: HashStable<StableHashingContext<'a, 'tcx>>,
211 V: HashStable<StableHashingContext<'a, 'tcx>>
213 fn hash_stable<W: StableHasherResult>(&self,
214 hcx: &mut StableHashingContext<'a, 'tcx>,
215 hasher: &mut StableHasher<W>) {
216 let mir::Projection {
221 base.hash_stable(hcx, hasher);
222 elem.hash_stable(hcx, hasher);
226 impl<'a, 'tcx, V> HashStable<StableHashingContext<'a, 'tcx>> for mir::ProjectionElem<'tcx, V>
227 where V: HashStable<StableHashingContext<'a, 'tcx>>
229 fn hash_stable<W: StableHasherResult>(&self,
230 hcx: &mut StableHashingContext<'a, 'tcx>,
231 hasher: &mut StableHasher<W>) {
232 mem::discriminant(self).hash_stable(hcx, hasher);
234 mir::ProjectionElem::Deref => {}
235 mir::ProjectionElem::Field(field, ty) => {
236 field.hash_stable(hcx, hasher);
237 ty.hash_stable(hcx, hasher);
239 mir::ProjectionElem::Index(ref value) => {
240 value.hash_stable(hcx, hasher);
242 mir::ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
243 offset.hash_stable(hcx, hasher);
244 min_length.hash_stable(hcx, hasher);
245 from_end.hash_stable(hcx, hasher);
247 mir::ProjectionElem::Subslice { from, to } => {
248 from.hash_stable(hcx, hasher);
249 to.hash_stable(hcx, hasher);
251 mir::ProjectionElem::Downcast(adt_def, variant) => {
252 adt_def.hash_stable(hcx, hasher);
253 variant.hash_stable(hcx, hasher);
259 impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope });
261 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Operand<'tcx> {
262 fn hash_stable<W: StableHasherResult>(&self,
263 hcx: &mut StableHashingContext<'a, 'tcx>,
264 hasher: &mut StableHasher<W>) {
265 mem::discriminant(self).hash_stable(hcx, hasher);
268 mir::Operand::Consume(ref lvalue) => {
269 lvalue.hash_stable(hcx, hasher);
271 mir::Operand::Constant(ref constant) => {
272 constant.hash_stable(hcx, hasher);
278 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Rvalue<'tcx> {
279 fn hash_stable<W: StableHasherResult>(&self,
280 hcx: &mut StableHashingContext<'a, 'tcx>,
281 hasher: &mut StableHasher<W>) {
282 mem::discriminant(self).hash_stable(hcx, hasher);
285 mir::Rvalue::Use(ref operand) => {
286 operand.hash_stable(hcx, hasher);
288 mir::Rvalue::Repeat(ref operand, ref val) => {
289 operand.hash_stable(hcx, hasher);
290 val.hash_stable(hcx, hasher);
292 mir::Rvalue::Ref(region, borrow_kind, ref lvalue) => {
293 region.hash_stable(hcx, hasher);
294 borrow_kind.hash_stable(hcx, hasher);
295 lvalue.hash_stable(hcx, hasher);
297 mir::Rvalue::Len(ref lvalue) => {
298 lvalue.hash_stable(hcx, hasher);
300 mir::Rvalue::Cast(cast_kind, ref operand, ty) => {
301 cast_kind.hash_stable(hcx, hasher);
302 operand.hash_stable(hcx, hasher);
303 ty.hash_stable(hcx, hasher);
305 mir::Rvalue::BinaryOp(op, ref operand1, ref operand2) |
306 mir::Rvalue::CheckedBinaryOp(op, ref operand1, ref operand2) => {
307 op.hash_stable(hcx, hasher);
308 operand1.hash_stable(hcx, hasher);
309 operand2.hash_stable(hcx, hasher);
311 mir::Rvalue::UnaryOp(op, ref operand) => {
312 op.hash_stable(hcx, hasher);
313 operand.hash_stable(hcx, hasher);
315 mir::Rvalue::Discriminant(ref lvalue) => {
316 lvalue.hash_stable(hcx, hasher);
318 mir::Rvalue::Box(ty) => {
319 ty.hash_stable(hcx, hasher);
321 mir::Rvalue::Aggregate(ref kind, ref operands) => {
322 kind.hash_stable(hcx, hasher);
323 operands.hash_stable(hcx, hasher);
329 impl_stable_hash_for!(enum mir::CastKind {
337 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::AggregateKind<'tcx> {
338 fn hash_stable<W: StableHasherResult>(&self,
339 hcx: &mut StableHashingContext<'a, 'tcx>,
340 hasher: &mut StableHasher<W>) {
341 mem::discriminant(self).hash_stable(hcx, hasher);
343 mir::AggregateKind::Tuple => {}
344 mir::AggregateKind::Array(t) => {
345 t.hash_stable(hcx, hasher);
347 mir::AggregateKind::Adt(adt_def, idx, substs, active_field) => {
348 adt_def.hash_stable(hcx, hasher);
349 idx.hash_stable(hcx, hasher);
350 substs.hash_stable(hcx, hasher);
351 active_field.hash_stable(hcx, hasher);
353 mir::AggregateKind::Closure(def_id, ref substs) => {
354 def_id.hash_stable(hcx, hasher);
355 substs.hash_stable(hcx, hasher);
361 impl_stable_hash_for!(enum mir::BinOp {
380 impl_stable_hash_for!(enum mir::UnOp {
386 impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
388 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Literal<'tcx> {
389 fn hash_stable<W: StableHasherResult>(&self,
390 hcx: &mut StableHashingContext<'a, 'tcx>,
391 hasher: &mut StableHasher<W>) {
392 mem::discriminant(self).hash_stable(hcx, hasher);
394 mir::Literal::Item { def_id, substs } => {
395 def_id.hash_stable(hcx, hasher);
396 substs.hash_stable(hcx, hasher);
398 mir::Literal::Value { ref value } => {
399 value.hash_stable(hcx, hasher);
401 mir::Literal::Promoted { index } => {
402 index.hash_stable(hcx, hasher);
408 impl_stable_hash_for!(struct mir::Location { block, statement_index });