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
, 'gcx
, 'tcx
> HashStable
<StableHashingContext
<'a
, 'gcx
, 'tcx
>>
36 for mir
::Terminator
<'gcx
> {
38 fn hash_stable
<W
: StableHasherResult
>(&self,
39 hcx
: &mut StableHashingContext
<'a
, 'gcx
, 'tcx
>,
40 hasher
: &mut StableHasher
<W
>) {
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
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,
63 if hash_spans_unconditionally
{
64 hcx
.while_hashing_spans(true, |hcx
| {
65 source_info
.hash_stable(hcx
, hasher
);
68 source_info
.hash_stable(hcx
, hasher
);
71 kind
.hash_stable(hcx
, hasher
);
76 impl<'a
, 'gcx
, 'tcx
> HashStable
<StableHashingContext
<'a
, 'gcx
, 'tcx
>> for mir
::Local
{
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
);
86 impl<'a
, 'gcx
, 'tcx
> HashStable
<StableHashingContext
<'a
, 'gcx
, 'tcx
>> for mir
::BasicBlock
{
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
);
96 impl<'a
, 'gcx
, 'tcx
> HashStable
<StableHashingContext
<'a
, 'gcx
, 'tcx
>> for mir
::Field
{
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
);
106 impl<'a
, 'gcx
, 'tcx
> HashStable
<StableHashingContext
<'a
, 'gcx
, 'tcx
>>
107 for mir
::VisibilityScope
{
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
);
117 impl<'a
, 'gcx
, 'tcx
> HashStable
<StableHashingContext
<'a
, 'gcx
, 'tcx
>> for mir
::Promoted
{
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
);
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
);
135 mir
::TerminatorKind
::Goto { ref target }
=> {
136 target
.hash_stable(hcx
, hasher
);
138 mir
::TerminatorKind
::SwitchInt
{ ref discr
,
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
);
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
);
155 mir
::TerminatorKind
::DropAndReplace
{ ref location
,
159 location
.hash_stable(hcx
, hasher
);
160 value
.hash_stable(hcx
, hasher
);
161 target
.hash_stable(hcx
, hasher
);
162 unwind
.hash_stable(hcx
, hasher
);
164 mir
::TerminatorKind
::Call
{ ref func
,
168 func
.hash_stable(hcx
, hasher
);
169 args
.hash_stable(hcx
, hasher
);
170 destination
.hash_stable(hcx
, hasher
);
171 cleanup
.hash_stable(hcx
, hasher
);
173 mir
::TerminatorKind
::Assert
{ ref cond
,
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
);
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
);
196 mir
::AssertMessage
::BoundsCheck { ref len, ref index }
=> {
197 len
.hash_stable(hcx
, hasher
);
198 index
.hash_stable(hcx
, hasher
);
200 mir
::AssertMessage
::Math(ref const_math_err
) => {
201 const_math_err
.hash_stable(hcx
, hasher
);
207 impl_stable_hash_for
!(struct mir
::Statement
<'tcx
> { source_info, kind }
);
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
);
217 mir
::StatementKind
::Assign(ref lvalue
, ref rvalue
) => {
218 lvalue
.hash_stable(hcx
, hasher
);
219 rvalue
.hash_stable(hcx
, hasher
);
221 mir
::StatementKind
::SetDiscriminant { ref lvalue, variant_index }
=> {
222 lvalue
.hash_stable(hcx
, hasher
);
223 variant_index
.hash_stable(hcx
, hasher
);
225 mir
::StatementKind
::StorageLive(ref lvalue
) |
226 mir
::StatementKind
::StorageDead(ref lvalue
) => {
227 lvalue
.hash_stable(hcx
, hasher
);
229 mir
::StatementKind
::EndRegion(ref extent
) => {
230 extent
.hash_stable(hcx
, hasher
);
232 mir
::StatementKind
::Validate(ref op
, ref lvalues
) => {
233 op
.hash_stable(hcx
, hasher
);
234 lvalues
.hash_stable(hcx
, hasher
);
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
);
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
>>
250 fn hash_stable
<W
: StableHasherResult
>(&self,
251 hcx
: &mut StableHashingContext
<'a
, 'gcx
, 'tcx
>,
252 hasher
: &mut StableHasher
<W
>)
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
);
261 impl_stable_hash_for
!(enum mir
::ValidationOp { Acquire, Release, Suspend(extent) }
);
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
);
269 mir
::Lvalue
::Local(ref local
) => {
270 local
.hash_stable(hcx
, hasher
);
272 mir
::Lvalue
::Static(ref statik
) => {
273 statik
.hash_stable(hcx
, hasher
);
275 mir
::Lvalue
::Projection(ref lvalue_projection
) => {
276 lvalue_projection
.hash_stable(hcx
, hasher
);
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
>>
288 fn hash_stable
<W
: StableHasherResult
>(&self,
289 hcx
: &mut StableHashingContext
<'a
, 'gcx
, 'tcx
>,
290 hasher
: &mut StableHasher
<W
>) {
291 let mir
::Projection
{
296 base
.hash_stable(hcx
, hasher
);
297 elem
.hash_stable(hcx
, hasher
);
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
>>
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
);
311 mir
::ProjectionElem
::Deref
=> {}
312 mir
::ProjectionElem
::Field(field
, ref ty
) => {
313 field
.hash_stable(hcx
, hasher
);
314 ty
.hash_stable(hcx
, hasher
);
316 mir
::ProjectionElem
::Index(ref value
) => {
317 value
.hash_stable(hcx
, hasher
);
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
);
324 mir
::ProjectionElem
::Subslice { from, to }
=> {
325 from
.hash_stable(hcx
, hasher
);
326 to
.hash_stable(hcx
, hasher
);
328 mir
::ProjectionElem
::Downcast(adt_def
, variant
) => {
329 adt_def
.hash_stable(hcx
, hasher
);
330 variant
.hash_stable(hcx
, hasher
);
336 impl_stable_hash_for
!(struct mir
::VisibilityScopeData { span, parent_scope }
);
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
);
345 mir
::Operand
::Consume(ref lvalue
) => {
346 lvalue
.hash_stable(hcx
, hasher
);
348 mir
::Operand
::Constant(ref constant
) => {
349 constant
.hash_stable(hcx
, hasher
);
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
);
362 mir
::Rvalue
::Use(ref operand
) => {
363 operand
.hash_stable(hcx
, hasher
);
365 mir
::Rvalue
::Repeat(ref operand
, ref val
) => {
366 operand
.hash_stable(hcx
, hasher
);
367 val
.hash_stable(hcx
, hasher
);
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
);
374 mir
::Rvalue
::Len(ref lvalue
) => {
375 lvalue
.hash_stable(hcx
, hasher
);
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
);
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
);
388 mir
::Rvalue
::UnaryOp(op
, ref operand
) => {
389 op
.hash_stable(hcx
, hasher
);
390 operand
.hash_stable(hcx
, hasher
);
392 mir
::Rvalue
::Discriminant(ref lvalue
) => {
393 lvalue
.hash_stable(hcx
, hasher
);
395 mir
::Rvalue
::NullaryOp(op
, ty
) => {
396 op
.hash_stable(hcx
, hasher
);
397 ty
.hash_stable(hcx
, hasher
);
399 mir
::Rvalue
::Aggregate(ref kind
, ref operands
) => {
400 kind
.hash_stable(hcx
, hasher
);
401 operands
.hash_stable(hcx
, hasher
);
407 impl_stable_hash_for
!(enum mir
::CastKind
{
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
);
422 mir
::AggregateKind
::Tuple
=> {}
423 mir
::AggregateKind
::Array(t
) => {
424 t
.hash_stable(hcx
, hasher
);
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
);
432 mir
::AggregateKind
::Closure(def_id
, ref substs
) => {
433 def_id
.hash_stable(hcx
, hasher
);
434 substs
.hash_stable(hcx
, hasher
);
440 impl_stable_hash_for
!(enum mir
::BinOp
{
460 impl_stable_hash_for
!(enum mir
::UnOp
{
465 impl_stable_hash_for
!(enum mir
::NullOp
{
470 impl_stable_hash_for
!(struct mir
::Constant
<'tcx
> { span, ty, literal }
);
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
);
478 mir
::Literal
::Item { def_id, substs }
=> {
479 def_id
.hash_stable(hcx
, hasher
);
480 substs
.hash_stable(hcx
, hasher
);
482 mir
::Literal
::Value { ref value }
=> {
483 value
.hash_stable(hcx
, hasher
);
485 mir
::Literal
::Promoted { index }
=> {
486 index
.hash_stable(hcx
, hasher
);
492 impl_stable_hash_for
!(struct mir
::Location { block, statement_index }
);