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
::NullaryOp(op
, ty
) => {
363 op
.hash_stable(hcx
, hasher
);
364 ty
.hash_stable(hcx
, hasher
);
366 mir
::Rvalue
::Aggregate(ref kind
, ref operands
) => {
367 kind
.hash_stable(hcx
, hasher
);
368 operands
.hash_stable(hcx
, hasher
);
374 impl_stable_hash_for
!(enum mir
::CastKind
{
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
);
388 mir
::AggregateKind
::Tuple
=> {}
389 mir
::AggregateKind
::Array(t
) => {
390 t
.hash_stable(hcx
, hasher
);
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
);
398 mir
::AggregateKind
::Closure(def_id
, ref substs
) => {
399 def_id
.hash_stable(hcx
, hasher
);
400 substs
.hash_stable(hcx
, hasher
);
406 impl_stable_hash_for
!(enum mir
::BinOp
{
426 impl_stable_hash_for
!(enum mir
::UnOp
{
431 impl_stable_hash_for
!(enum mir
::NullOp
{
436 impl_stable_hash_for
!(struct mir
::Constant
<'tcx
> { span, ty, literal }
);
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
);
444 mir
::Literal
::Item { def_id, substs }
=> {
445 def_id
.hash_stable(hcx
, hasher
);
446 substs
.hash_stable(hcx
, hasher
);
448 mir
::Literal
::Value { ref value }
=> {
449 value
.hash_stable(hcx
, hasher
);
451 mir
::Literal
::Promoted { index }
=> {
452 index
.hash_stable(hcx
, hasher
);
458 impl_stable_hash_for
!(struct mir
::Location { block, statement_index }
);