impls_mir.rs 20.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! This module contains `HashStable` implementations for various MIR data
//! types in no particular order.

use ich::StableHashingContext;
use mir;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
                                           StableHasherResult};
use std::mem;

J
John Kåre Alsaker 已提交
20
impl_stable_hash_for!(struct mir::GeneratorLayout<'tcx> { fields });
21 22 23 24
impl_stable_hash_for!(struct mir::SourceInfo { span, scope });
impl_stable_hash_for!(enum mir::Mutability { Mut, Not });
impl_stable_hash_for!(enum mir::BorrowKind { Shared, Unique, Mut });
impl_stable_hash_for!(enum mir::LocalKind { Var, Temp, Arg, ReturnPointer });
25 26 27 28 29
impl_stable_hash_for!(struct mir::LocalDecl<'tcx> {
    mutability,
    ty,
    name,
    source_info,
30
    internal,
31
    syntactic_scope,
32 33
    is_user_variable
});
34
impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref, mutability });
35
impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
36
impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, kind });
A
Ariel Ben-Yehuda 已提交
37
impl_stable_hash_for!(struct mir::UnsafetyCheckResult { violations, unsafe_blocks });
38

39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
impl<'gcx> HashStable<StableHashingContext<'gcx>>
for mir::UnsafetyViolationKind {
    #[inline]
    fn hash_stable<W: StableHasherResult>(&self,
                                          hcx: &mut StableHashingContext<'gcx>,
                                          hasher: &mut StableHasher<W>) {

        mem::discriminant(self).hash_stable(hcx, hasher);

        match *self {
            mir::UnsafetyViolationKind::General => {}
            mir::UnsafetyViolationKind::ExternStatic(lint_node_id) |
            mir::UnsafetyViolationKind::BorrowPacked(lint_node_id) => {
                lint_node_id.hash_stable(hcx, hasher);
            }

        }
    }
}
58

59 60 61 62
impl_stable_hash_for!(struct mir::Terminator<'tcx> {
    kind,
    source_info
});
63

64
impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for mir::ClearCrossCrate<T>
65 66 67 68 69 70 71 72
    where T: HashStable<StableHashingContext<'gcx>>
{
    #[inline]
    fn hash_stable<W: StableHasherResult>(&self,
                                          hcx: &mut StableHashingContext<'gcx>,
                                          hasher: &mut StableHasher<W>) {
        mem::discriminant(self).hash_stable(hcx, hasher);
        match *self {
73 74
            mir::ClearCrossCrate::Clear => {}
            mir::ClearCrossCrate::Set(ref value) => {
75 76 77 78 79
                value.hash_stable(hcx, hasher);
            }
        }
    }
}
80

81
impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Local {
82 83
    #[inline]
    fn hash_stable<W: StableHasherResult>(&self,
84
                                          hcx: &mut StableHashingContext<'gcx>,
85 86 87 88 89 90
                                          hasher: &mut StableHasher<W>) {
        use rustc_data_structures::indexed_vec::Idx;
        self.index().hash_stable(hcx, hasher);
    }
}

91
impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::BasicBlock {
92 93
    #[inline]
    fn hash_stable<W: StableHasherResult>(&self,
94
                                          hcx: &mut StableHashingContext<'gcx>,
95 96 97 98 99 100
                                          hasher: &mut StableHasher<W>) {
        use rustc_data_structures::indexed_vec::Idx;
        self.index().hash_stable(hcx, hasher);
    }
}

101
impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Field {
102 103
    #[inline]
    fn hash_stable<W: StableHasherResult>(&self,
104
                                          hcx: &mut StableHashingContext<'gcx>,
105 106 107 108 109 110
                                          hasher: &mut StableHasher<W>) {
        use rustc_data_structures::indexed_vec::Idx;
        self.index().hash_stable(hcx, hasher);
    }
}

111
impl<'gcx> HashStable<StableHashingContext<'gcx>>
112
for mir::VisibilityScope {
113 114
    #[inline]
    fn hash_stable<W: StableHasherResult>(&self,
115
                                          hcx: &mut StableHashingContext<'gcx>,
116 117 118 119 120 121
                                          hasher: &mut StableHasher<W>) {
        use rustc_data_structures::indexed_vec::Idx;
        self.index().hash_stable(hcx, hasher);
    }
}

122
impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Promoted {
123 124
    #[inline]
    fn hash_stable<W: StableHasherResult>(&self,
125
                                          hcx: &mut StableHashingContext<'gcx>,
126 127 128 129 130 131
                                          hasher: &mut StableHasher<W>) {
        use rustc_data_structures::indexed_vec::Idx;
        self.index().hash_stable(hcx, hasher);
    }
}

132
impl<'gcx> HashStable<StableHashingContext<'gcx>>
133
for mir::TerminatorKind<'gcx> {
134
    fn hash_stable<W: StableHasherResult>(&self,
135
                                          hcx: &mut StableHashingContext<'gcx>,
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
                                          hasher: &mut StableHasher<W>) {
        mem::discriminant(self).hash_stable(hcx, hasher);

        match *self {
            mir::TerminatorKind::Goto { ref target } => {
                target.hash_stable(hcx, hasher);
            }
            mir::TerminatorKind::SwitchInt { ref discr,
                                             switch_ty,
                                             ref values,
                                             ref targets } => {
                discr.hash_stable(hcx, hasher);
                switch_ty.hash_stable(hcx, hasher);
                values.hash_stable(hcx, hasher);
                targets.hash_stable(hcx, hasher);
            }
            mir::TerminatorKind::Resume |
D
David Henningsson 已提交
153
            mir::TerminatorKind::Abort |
154
            mir::TerminatorKind::Return |
J
John Kåre Alsaker 已提交
155
            mir::TerminatorKind::GeneratorDrop |
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
            mir::TerminatorKind::Unreachable => {}
            mir::TerminatorKind::Drop { ref location, target, unwind } => {
                location.hash_stable(hcx, hasher);
                target.hash_stable(hcx, hasher);
                unwind.hash_stable(hcx, hasher);
            }
            mir::TerminatorKind::DropAndReplace { ref location,
                                                  ref value,
                                                  target,
                                                  unwind, } => {
                location.hash_stable(hcx, hasher);
                value.hash_stable(hcx, hasher);
                target.hash_stable(hcx, hasher);
                unwind.hash_stable(hcx, hasher);
            }
J
John Kåre Alsaker 已提交
171
            mir::TerminatorKind::Yield { ref value,
J
John Kåre Alsaker 已提交
172 173 174 175 176 177
                                        resume,
                                        drop } => {
                value.hash_stable(hcx, hasher);
                resume.hash_stable(hcx, hasher);
                drop.hash_stable(hcx, hasher);
            }
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
            mir::TerminatorKind::Call { ref func,
                                        ref args,
                                        ref destination,
                                        cleanup } => {
                func.hash_stable(hcx, hasher);
                args.hash_stable(hcx, hasher);
                destination.hash_stable(hcx, hasher);
                cleanup.hash_stable(hcx, hasher);
            }
            mir::TerminatorKind::Assert { ref cond,
                                          expected,
                                          ref msg,
                                          target,
                                          cleanup } => {
                cond.hash_stable(hcx, hasher);
                expected.hash_stable(hcx, hasher);
                msg.hash_stable(hcx, hasher);
                target.hash_stable(hcx, hasher);
                cleanup.hash_stable(hcx, hasher);
            }
198 199 200 201 202 203
            mir::TerminatorKind::FalseEdges { ref real_target, ref imaginary_targets } => {
                real_target.hash_stable(hcx, hasher);
                for target in imaginary_targets {
                    target.hash_stable(hcx, hasher);
                }
            }
204 205 206 207
            mir::TerminatorKind::FalseUnwind { ref real_target, ref unwind } => {
                real_target.hash_stable(hcx, hasher);
                unwind.hash_stable(hcx, hasher);
            }
208 209 210 211
        }
    }
}

212
impl<'gcx> HashStable<StableHashingContext<'gcx>>
213
for mir::AssertMessage<'gcx> {
214
    fn hash_stable<W: StableHasherResult>(&self,
215
                                          hcx: &mut StableHashingContext<'gcx>,
216 217 218 219 220 221 222 223 224 225 226
                                          hasher: &mut StableHasher<W>) {
        mem::discriminant(self).hash_stable(hcx, hasher);

        match *self {
            mir::AssertMessage::BoundsCheck { ref len, ref index } => {
                len.hash_stable(hcx, hasher);
                index.hash_stable(hcx, hasher);
            }
            mir::AssertMessage::Math(ref const_math_err) => {
                const_math_err.hash_stable(hcx, hasher);
            }
J
John Kåre Alsaker 已提交
227 228
            mir::AssertMessage::GeneratorResumedAfterReturn => (),
            mir::AssertMessage::GeneratorResumedAfterPanic => (),
229 230 231 232 233 234
        }
    }
}

impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });

235
impl<'gcx> HashStable<StableHashingContext<'gcx>>
236
for mir::StatementKind<'gcx> {
237
    fn hash_stable<W: StableHasherResult>(&self,
238
                                          hcx: &mut StableHashingContext<'gcx>,
239 240 241 242
                                          hasher: &mut StableHasher<W>) {
        mem::discriminant(self).hash_stable(hcx, hasher);

        match *self {
243 244
            mir::StatementKind::Assign(ref place, ref rvalue) => {
                place.hash_stable(hcx, hasher);
245 246
                rvalue.hash_stable(hcx, hasher);
            }
247 248
            mir::StatementKind::SetDiscriminant { ref place, variant_index } => {
                place.hash_stable(hcx, hasher);
249 250
                variant_index.hash_stable(hcx, hasher);
            }
251 252 253
            mir::StatementKind::StorageLive(ref place) |
            mir::StatementKind::StorageDead(ref place) => {
                place.hash_stable(hcx, hasher);
254
            }
255 256
            mir::StatementKind::EndRegion(ref region_scope) => {
                region_scope.hash_stable(hcx, hasher);
257
            }
258
            mir::StatementKind::Validate(ref op, ref places) => {
259
                op.hash_stable(hcx, hasher);
260
                places.hash_stable(hcx, hasher);
261
            }
262 263 264 265 266 267 268 269 270 271
            mir::StatementKind::Nop => {}
            mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
                asm.hash_stable(hcx, hasher);
                outputs.hash_stable(hcx, hasher);
                inputs.hash_stable(hcx, hasher);
            }
        }
    }
}

272
impl<'gcx, T> HashStable<StableHashingContext<'gcx>>
273
    for mir::ValidationOperand<'gcx, T>
274
    where T: HashStable<StableHashingContext<'gcx>>
275 276
{
    fn hash_stable<W: StableHasherResult>(&self,
277
                                          hcx: &mut StableHashingContext<'gcx>,
278 279
                                          hasher: &mut StableHasher<W>)
    {
280
        self.place.hash_stable(hcx, hasher);
281 282 283 284 285
        self.ty.hash_stable(hcx, hasher);
        self.re.hash_stable(hcx, hasher);
        self.mutbl.hash_stable(hcx, hasher);
    }
}
286

287
impl_stable_hash_for!(enum mir::ValidationOp { Acquire, Release, Suspend(region_scope) });
288

289
impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Place<'gcx> {
290
    fn hash_stable<W: StableHasherResult>(&self,
291
                                          hcx: &mut StableHashingContext<'gcx>,
292 293 294
                                          hasher: &mut StableHasher<W>) {
        mem::discriminant(self).hash_stable(hcx, hasher);
        match *self {
295
            mir::Place::Local(ref local) => {
296 297
                local.hash_stable(hcx, hasher);
            }
298
            mir::Place::Static(ref statik) => {
299 300
                statik.hash_stable(hcx, hasher);
            }
301 302
            mir::Place::Projection(ref place_projection) => {
                place_projection.hash_stable(hcx, hasher);
303 304 305 306 307
            }
        }
    }
}

308
impl<'gcx, B, V, T> HashStable<StableHashingContext<'gcx>>
309
for mir::Projection<'gcx, B, V, T>
310 311 312
    where B: HashStable<StableHashingContext<'gcx>>,
          V: HashStable<StableHashingContext<'gcx>>,
          T: HashStable<StableHashingContext<'gcx>>
313 314
{
    fn hash_stable<W: StableHasherResult>(&self,
315
                                          hcx: &mut StableHashingContext<'gcx>,
316 317 318 319 320 321 322 323 324 325 326
                                          hasher: &mut StableHasher<W>) {
        let mir::Projection {
            ref base,
            ref elem,
        } = *self;

        base.hash_stable(hcx, hasher);
        elem.hash_stable(hcx, hasher);
    }
}

327
impl<'gcx, V, T> HashStable<StableHashingContext<'gcx>>
328
for mir::ProjectionElem<'gcx, V, T>
329 330
    where V: HashStable<StableHashingContext<'gcx>>,
          T: HashStable<StableHashingContext<'gcx>>
331 332
{
    fn hash_stable<W: StableHasherResult>(&self,
333
                                          hcx: &mut StableHashingContext<'gcx>,
334 335 336 337
                                          hasher: &mut StableHasher<W>) {
        mem::discriminant(self).hash_stable(hcx, hasher);
        match *self {
            mir::ProjectionElem::Deref => {}
338
            mir::ProjectionElem::Field(field, ref ty) => {
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
                field.hash_stable(hcx, hasher);
                ty.hash_stable(hcx, hasher);
            }
            mir::ProjectionElem::Index(ref value) => {
                value.hash_stable(hcx, hasher);
            }
            mir::ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
                offset.hash_stable(hcx, hasher);
                min_length.hash_stable(hcx, hasher);
                from_end.hash_stable(hcx, hasher);
            }
            mir::ProjectionElem::Subslice { from, to } => {
                from.hash_stable(hcx, hasher);
                to.hash_stable(hcx, hasher);
            }
            mir::ProjectionElem::Downcast(adt_def, variant) => {
                adt_def.hash_stable(hcx, hasher);
                variant.hash_stable(hcx, hasher);
            }
        }
    }
}

impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope });
A
Ariel Ben-Yehuda 已提交
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
impl_stable_hash_for!(struct mir::VisibilityScopeInfo {
    lint_root, safety
});

impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Safety {
    fn hash_stable<W: StableHasherResult>(&self,
                                          hcx: &mut StableHashingContext<'gcx>,
                                          hasher: &mut StableHasher<W>) {
        mem::discriminant(self).hash_stable(hcx, hasher);

        match *self {
            mir::Safety::Safe |
            mir::Safety::BuiltinUnsafe |
            mir::Safety::FnUnsafe => {}
            mir::Safety::ExplicitUnsafe(node_id) => {
                node_id.hash_stable(hcx, hasher);
            }
        }
    }
}
383

384
impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Operand<'gcx> {
385
    fn hash_stable<W: StableHasherResult>(&self,
386
                                          hcx: &mut StableHashingContext<'gcx>,
387 388 389 390
                                          hasher: &mut StableHasher<W>) {
        mem::discriminant(self).hash_stable(hcx, hasher);

        match *self {
391 392
            mir::Operand::Copy(ref place) => {
                place.hash_stable(hcx, hasher);
393
            }
394 395
            mir::Operand::Move(ref place) => {
                place.hash_stable(hcx, hasher);
396 397 398 399 400 401 402 403
            }
            mir::Operand::Constant(ref constant) => {
                constant.hash_stable(hcx, hasher);
            }
        }
    }
}

404
impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Rvalue<'gcx> {
405
    fn hash_stable<W: StableHasherResult>(&self,
406
                                          hcx: &mut StableHashingContext<'gcx>,
407 408 409 410 411 412 413 414 415 416 417
                                          hasher: &mut StableHasher<W>) {
        mem::discriminant(self).hash_stable(hcx, hasher);

        match *self {
            mir::Rvalue::Use(ref operand) => {
                operand.hash_stable(hcx, hasher);
            }
            mir::Rvalue::Repeat(ref operand, ref val) => {
                operand.hash_stable(hcx, hasher);
                val.hash_stable(hcx, hasher);
            }
418
            mir::Rvalue::Ref(region, borrow_kind, ref place) => {
419 420
                region.hash_stable(hcx, hasher);
                borrow_kind.hash_stable(hcx, hasher);
421
                place.hash_stable(hcx, hasher);
422
            }
423 424
            mir::Rvalue::Len(ref place) => {
                place.hash_stable(hcx, hasher);
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
            }
            mir::Rvalue::Cast(cast_kind, ref operand, ty) => {
                cast_kind.hash_stable(hcx, hasher);
                operand.hash_stable(hcx, hasher);
                ty.hash_stable(hcx, hasher);
            }
            mir::Rvalue::BinaryOp(op, ref operand1, ref operand2) |
            mir::Rvalue::CheckedBinaryOp(op, ref operand1, ref operand2) => {
                op.hash_stable(hcx, hasher);
                operand1.hash_stable(hcx, hasher);
                operand2.hash_stable(hcx, hasher);
            }
            mir::Rvalue::UnaryOp(op, ref operand) => {
                op.hash_stable(hcx, hasher);
                operand.hash_stable(hcx, hasher);
            }
441 442
            mir::Rvalue::Discriminant(ref place) => {
                place.hash_stable(hcx, hasher);
443
            }
444 445
            mir::Rvalue::NullaryOp(op, ty) => {
                op.hash_stable(hcx, hasher);
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
                ty.hash_stable(hcx, hasher);
            }
            mir::Rvalue::Aggregate(ref kind, ref operands) => {
                kind.hash_stable(hcx, hasher);
                operands.hash_stable(hcx, hasher);
            }
        }
    }
}

impl_stable_hash_for!(enum mir::CastKind {
    Misc,
    ReifyFnPointer,
    ClosureFnPointer,
    UnsafeFnPointer,
    Unsize
});

464
impl<'gcx> HashStable<StableHashingContext<'gcx>>
465
for mir::AggregateKind<'gcx> {
466
    fn hash_stable<W: StableHasherResult>(&self,
467
                                          hcx: &mut StableHashingContext<'gcx>,
468 469 470 471 472 473 474 475 476 477 478 479 480
                                          hasher: &mut StableHasher<W>) {
        mem::discriminant(self).hash_stable(hcx, hasher);
        match *self {
            mir::AggregateKind::Tuple => {}
            mir::AggregateKind::Array(t) => {
                t.hash_stable(hcx, hasher);
            }
            mir::AggregateKind::Adt(adt_def, idx, substs, active_field) => {
                adt_def.hash_stable(hcx, hasher);
                idx.hash_stable(hcx, hasher);
                substs.hash_stable(hcx, hasher);
                active_field.hash_stable(hcx, hasher);
            }
481
            mir::AggregateKind::Closure(def_id, ref substs) => {
482 483 484
                def_id.hash_stable(hcx, hasher);
                substs.hash_stable(hcx, hasher);
            }
485 486 487 488 489
            mir::AggregateKind::Generator(def_id, ref substs, ref interior) => {
                def_id.hash_stable(hcx, hasher);
                substs.hash_stable(hcx, hasher);
                interior.hash_stable(hcx, hasher);
            }
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
        }
    }
}

impl_stable_hash_for!(enum mir::BinOp {
    Add,
    Sub,
    Mul,
    Div,
    Rem,
    BitXor,
    BitAnd,
    BitOr,
    Shl,
    Shr,
    Eq,
    Lt,
    Le,
    Ne,
    Ge,
510 511
    Gt,
    Offset
512 513 514 515 516 517 518
});

impl_stable_hash_for!(enum mir::UnOp {
    Not,
    Neg
});

519 520 521 522
impl_stable_hash_for!(enum mir::NullOp {
    Box,
    SizeOf
});
523 524 525

impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });

526
impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Literal<'gcx> {
527
    fn hash_stable<W: StableHasherResult>(&self,
528
                                          hcx: &mut StableHashingContext<'gcx>,
529 530 531 532 533 534 535 536 537 538 539 540 541 542
                                          hasher: &mut StableHasher<W>) {
        mem::discriminant(self).hash_stable(hcx, hasher);
        match *self {
            mir::Literal::Value { ref value } => {
                value.hash_stable(hcx, hasher);
            }
            mir::Literal::Promoted { index } => {
                index.hash_stable(hcx, hasher);
            }
        }
    }
}

impl_stable_hash_for!(struct mir::Location { block, statement_index });
543

544
impl_stable_hash_for!(struct mir::ClosureRegionRequirements<'tcx> {
545 546 547 548
    num_external_vids,
    outlives_requirements
});

549 550
impl_stable_hash_for!(struct mir::ClosureOutlivesRequirement<'tcx> {
    subject,
551 552 553 554
    outlived_free_region,
    blame_span
});

555 556 557 558 559 560 561 562 563 564 565 566 567 568 569
impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::ClosureOutlivesSubject<'gcx> {
    fn hash_stable<W: StableHasherResult>(&self,
                                          hcx: &mut StableHashingContext<'gcx>,
                                          hasher: &mut StableHasher<W>) {
        mem::discriminant(self).hash_stable(hcx, hasher);
        match *self {
            mir::ClosureOutlivesSubject::Ty(ref ty) => {
                ty.hash_stable(hcx, hasher);
            }
            mir::ClosureOutlivesSubject::Region(ref region) => {
                region.hash_stable(hcx, hasher);
            }
        }
    }
}