//! 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::LocalKind { Var, Temp, Arg, ReturnPointer }); impl_stable_hash_for!(struct mir::LocalDecl<'tcx> { mutability, ty, user_ty, name, source_info, visibility_scope, internal, is_block_tail, is_user_variable }); impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, var_hir_id, 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, details, kind }); impl_stable_hash_for!(struct mir::UnsafetyCheckResult { violations, unsafe_blocks }); impl_stable_hash_for!(enum mir::BorrowKind { Shared, Shallow, Unique, Mut { allow_two_phase_borrow }, }); impl_stable_hash_for!(enum mir::UnsafetyViolationKind { General, GeneralAndConstFn, ExternStatic(lint_node_id), BorrowPacked(lint_node_id), }); impl_stable_hash_for!(struct mir::Terminator<'tcx> { kind, source_info }); impl_stable_hash_for!( impl for enum mir::ClearCrossCrate [ mir::ClearCrossCrate ] { Clear, Set(value), } ); impl<'a> HashStable> for mir::Local { #[inline] fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { self.index().hash_stable(hcx, hasher); } } impl<'a> HashStable> for mir::BasicBlock { #[inline] fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { self.index().hash_stable(hcx, hasher); } } impl<'a> HashStable> for mir::Field { #[inline] fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { self.index().hash_stable(hcx, hasher); } } impl<'a> HashStable> for mir::SourceScope { #[inline] fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { self.index().hash_stable(hcx, hasher); } } impl<'a> HashStable> for mir::Promoted { #[inline] fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { self.index().hash_stable(hcx, hasher); } } impl<'a, 'gcx> HashStable> for mir::TerminatorKind<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { 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, from_hir_call, } => { func.hash_stable(hcx, hasher); args.hash_stable(hcx, hasher); destination.hash_stable(hcx, hasher); cleanup.hash_stable(hcx, hasher); from_hir_call.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); } } mir::TerminatorKind::FalseUnwind { ref real_target, ref unwind } => { real_target.hash_stable(hcx, hasher); unwind.hash_stable(hcx, hasher); } } } } impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind }); impl_stable_hash_for!(impl<'gcx> for enum mir::StatementKind<'gcx> [ mir::StatementKind ] { Assign(place, rvalue), FakeRead(cause, place), SetDiscriminant { place, variant_index }, StorageLive(place), StorageDead(place), Retag(retag_kind, place), AscribeUserType(place, variance, c_ty), Nop, InlineAsm { asm, outputs, inputs }, }); impl_stable_hash_for!(enum mir::RetagKind { FnEntry, TwoPhase, Raw, Default }); impl_stable_hash_for!(enum mir::FakeReadCause { ForMatchGuard, ForMatchedPlace, ForLet }); impl<'a, 'gcx> HashStable> for mir::Place<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { 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::Promoted(ref promoted) => { promoted.hash_stable(hcx, hasher); } mir::Place::Projection(ref place_projection) => { place_projection.hash_stable(hcx, hasher); } } } } impl<'a, 'gcx, B, V, T> HashStable> for mir::Projection<'gcx, B, V, T> where B: HashStable>, V: HashStable>, T: HashStable> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { let mir::Projection { ref base, ref elem, } = *self; base.hash_stable(hcx, hasher); elem.hash_stable(hcx, hasher); } } impl<'a, 'gcx, V, T> HashStable> for mir::ProjectionElem<'gcx, V, T> where V: HashStable>, T: HashStable> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { 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::SourceScopeData { span, parent_scope }); impl_stable_hash_for!(struct mir::SourceScopeLocalData { lint_root, safety }); impl<'a> HashStable> for mir::Safety { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { 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<'a, 'gcx> HashStable> for mir::Operand<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { 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<'a, 'gcx> HashStable> for mir::Rvalue<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { 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<'a, 'gcx> HashStable> for mir::AggregateKind<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { 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, user_substs, active_field) => { adt_def.hash_stable(hcx, hasher); idx.hash_stable(hcx, hasher); substs.hash_stable(hcx, hasher); user_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, movability) => { def_id.hash_stable(hcx, hasher); substs.hash_stable(hcx, hasher); movability.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, user_ty, literal }); impl_stable_hash_for!(struct mir::Location { block, statement_index }); impl_stable_hash_for!(struct mir::BorrowCheckResult<'tcx> { closure_requirements, used_mut_upvars }); 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, category }); impl_stable_hash_for!(enum mir::ConstraintCategory { Return, Yield, UseAsConst, UseAsStatic, TypeAnnotation, Cast, ClosureBounds, CallArgument, CopyBound, SizedBound, Assignment, OpaqueType, Boring, BoringNoLocation, Internal, }); impl<'a, 'gcx> HashStable> for mir::ClosureOutlivesSubject<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { 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); } } } } impl_stable_hash_for!(struct mir::interpret::GlobalId<'tcx> { instance, promoted }); impl_stable_hash_for!(struct mir::UserTypeProjection<'tcx> { base, projs }); impl_stable_hash_for!(struct mir::UserTypeProjections<'tcx> { contents });