| // 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; |
| |
| impl_stable_hash_for!(struct mir::GeneratorLayout<'tcx> { fields }); |
| 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 }); |
| impl_stable_hash_for!(struct mir::LocalDecl<'tcx> { |
| mutability, |
| ty, |
| name, |
| source_info, |
| internal, |
| syntactic_scope, |
| is_user_variable |
| }); |
| impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref, mutability }); |
| impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup }); |
| impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, kind }); |
| impl_stable_hash_for!(struct mir::UnsafetyCheckResult { violations, unsafe_blocks }); |
| |
| 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); |
| } |
| |
| } |
| } |
| } |
| |
| impl_stable_hash_for!(struct mir::Terminator<'tcx> { |
| kind, |
| source_info |
| }); |
| |
| impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for mir::ClearCrossCrate<T> |
| 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 { |
| mir::ClearCrossCrate::Clear => {} |
| mir::ClearCrossCrate::Set(ref value) => { |
| value.hash_stable(hcx, hasher); |
| } |
| } |
| } |
| } |
| |
| impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Local { |
| #[inline] |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'gcx>, |
| hasher: &mut StableHasher<W>) { |
| use rustc_data_structures::indexed_vec::Idx; |
| self.index().hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::BasicBlock { |
| #[inline] |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'gcx>, |
| hasher: &mut StableHasher<W>) { |
| use rustc_data_structures::indexed_vec::Idx; |
| self.index().hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Field { |
| #[inline] |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'gcx>, |
| hasher: &mut StableHasher<W>) { |
| use rustc_data_structures::indexed_vec::Idx; |
| self.index().hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'gcx> HashStable<StableHashingContext<'gcx>> |
| for mir::VisibilityScope { |
| #[inline] |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'gcx>, |
| hasher: &mut StableHasher<W>) { |
| use rustc_data_structures::indexed_vec::Idx; |
| self.index().hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Promoted { |
| #[inline] |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'gcx>, |
| hasher: &mut StableHasher<W>) { |
| use rustc_data_structures::indexed_vec::Idx; |
| self.index().hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'gcx> HashStable<StableHashingContext<'gcx>> |
| for mir::TerminatorKind<'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::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 | |
| mir::TerminatorKind::Abort | |
| mir::TerminatorKind::Return | |
| mir::TerminatorKind::GeneratorDrop | |
| 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); |
| } |
| mir::TerminatorKind::Yield { ref value, |
| resume, |
| drop } => { |
| value.hash_stable(hcx, hasher); |
| resume.hash_stable(hcx, hasher); |
| drop.hash_stable(hcx, hasher); |
| } |
| 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); |
| } |
| 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); |
| } |
| } |
| } |
| } |
| } |
| |
| impl<'gcx> HashStable<StableHashingContext<'gcx>> |
| for mir::AssertMessage<'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::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); |
| } |
| mir::AssertMessage::GeneratorResumedAfterReturn => (), |
| mir::AssertMessage::GeneratorResumedAfterPanic => (), |
| } |
| } |
| } |
| |
| impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind }); |
| |
| impl<'gcx> HashStable<StableHashingContext<'gcx>> |
| for mir::StatementKind<'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::StatementKind::Assign(ref place, ref rvalue) => { |
| place.hash_stable(hcx, hasher); |
| rvalue.hash_stable(hcx, hasher); |
| } |
| mir::StatementKind::SetDiscriminant { ref place, variant_index } => { |
| place.hash_stable(hcx, hasher); |
| variant_index.hash_stable(hcx, hasher); |
| } |
| mir::StatementKind::StorageLive(ref place) | |
| mir::StatementKind::StorageDead(ref place) => { |
| place.hash_stable(hcx, hasher); |
| } |
| mir::StatementKind::EndRegion(ref region_scope) => { |
| region_scope.hash_stable(hcx, hasher); |
| } |
| mir::StatementKind::Validate(ref op, ref places) => { |
| op.hash_stable(hcx, hasher); |
| places.hash_stable(hcx, hasher); |
| } |
| 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); |
| } |
| } |
| } |
| } |
| |
| impl<'gcx, T> HashStable<StableHashingContext<'gcx>> |
| for mir::ValidationOperand<'gcx, T> |
| where T: HashStable<StableHashingContext<'gcx>> |
| { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'gcx>, |
| hasher: &mut StableHasher<W>) |
| { |
| self.place.hash_stable(hcx, hasher); |
| self.ty.hash_stable(hcx, hasher); |
| self.re.hash_stable(hcx, hasher); |
| self.mutbl.hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl_stable_hash_for!(enum mir::ValidationOp { Acquire, Release, Suspend(region_scope) }); |
| |
| impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Place<'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::Place::Local(ref local) => { |
| local.hash_stable(hcx, hasher); |
| } |
| mir::Place::Static(ref statik) => { |
| statik.hash_stable(hcx, hasher); |
| } |
| mir::Place::Projection(ref place_projection) => { |
| place_projection.hash_stable(hcx, hasher); |
| } |
| } |
| } |
| } |
| |
| impl<'gcx, B, V, T> HashStable<StableHashingContext<'gcx>> |
| for mir::Projection<'gcx, B, V, T> |
| where B: HashStable<StableHashingContext<'gcx>>, |
| V: HashStable<StableHashingContext<'gcx>>, |
| T: HashStable<StableHashingContext<'gcx>> |
| { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'gcx>, |
| hasher: &mut StableHasher<W>) { |
| let mir::Projection { |
| ref base, |
| ref elem, |
| } = *self; |
| |
| base.hash_stable(hcx, hasher); |
| elem.hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'gcx, V, T> HashStable<StableHashingContext<'gcx>> |
| for mir::ProjectionElem<'gcx, V, T> |
| where V: HashStable<StableHashingContext<'gcx>>, |
| T: HashStable<StableHashingContext<'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::ProjectionElem::Deref => {} |
| mir::ProjectionElem::Field(field, ref ty) => { |
| 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 }); |
| 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); |
| } |
| } |
| } |
| } |
| |
| impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Operand<'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::Operand::Copy(ref place) => { |
| place.hash_stable(hcx, hasher); |
| } |
| mir::Operand::Move(ref place) => { |
| place.hash_stable(hcx, hasher); |
| } |
| mir::Operand::Constant(ref constant) => { |
| constant.hash_stable(hcx, hasher); |
| } |
| } |
| } |
| } |
| |
| impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Rvalue<'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::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); |
| } |
| mir::Rvalue::Ref(region, borrow_kind, ref place) => { |
| region.hash_stable(hcx, hasher); |
| borrow_kind.hash_stable(hcx, hasher); |
| place.hash_stable(hcx, hasher); |
| } |
| mir::Rvalue::Len(ref place) => { |
| place.hash_stable(hcx, hasher); |
| } |
| 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); |
| } |
| mir::Rvalue::Discriminant(ref place) => { |
| place.hash_stable(hcx, hasher); |
| } |
| mir::Rvalue::NullaryOp(op, ty) => { |
| op.hash_stable(hcx, hasher); |
| 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 |
| }); |
| |
| impl<'gcx> HashStable<StableHashingContext<'gcx>> |
| for mir::AggregateKind<'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::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); |
| } |
| mir::AggregateKind::Closure(def_id, ref substs) => { |
| def_id.hash_stable(hcx, hasher); |
| substs.hash_stable(hcx, hasher); |
| } |
| 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); |
| } |
| } |
| } |
| } |
| |
| impl_stable_hash_for!(enum mir::BinOp { |
| Add, |
| Sub, |
| Mul, |
| Div, |
| Rem, |
| BitXor, |
| BitAnd, |
| BitOr, |
| Shl, |
| Shr, |
| Eq, |
| Lt, |
| Le, |
| Ne, |
| Ge, |
| Gt, |
| Offset |
| }); |
| |
| impl_stable_hash_for!(enum mir::UnOp { |
| Not, |
| Neg |
| }); |
| |
| impl_stable_hash_for!(enum mir::NullOp { |
| Box, |
| SizeOf |
| }); |
| |
| impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal }); |
| |
| impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Literal<'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::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 }); |
| |
| impl_stable_hash_for!(struct mir::ClosureRegionRequirements<'tcx> { |
| num_external_vids, |
| outlives_requirements |
| }); |
| |
| impl_stable_hash_for!(struct mir::ClosureOutlivesRequirement<'tcx> { |
| subject, |
| outlived_free_region, |
| blame_span |
| }); |
| |
| 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); |
| } |
| } |
| } |
| } |