| //! This module contains `HashStable` implementations for various MIR data |
| //! types in no particular order. |
| |
| use crate::ich::StableHashingContext; |
| use crate::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<T> for enum mir::ClearCrossCrate<T> [ mir::ClearCrossCrate ] { |
| Clear, |
| Set(value), |
| } |
| ); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for mir::Local { |
| #[inline] |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| self.index().hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for mir::BasicBlock { |
| #[inline] |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| self.index().hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for mir::Field { |
| #[inline] |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| self.index().hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'a> HashStable<StableHashingContext<'a>> |
| for mir::SourceScope { |
| #[inline] |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| self.index().hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for mir::Promoted { |
| #[inline] |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| self.index().hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'a, 'gcx> HashStable<StableHashingContext<'a>> |
| for mir::TerminatorKind<'gcx> { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| 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, |
| 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<StableHashingContext<'a>> for mir::Place<'gcx> { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| 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::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<StableHashingContext<'a>> |
| for mir::Projection<'gcx, B, V, T> |
| where B: HashStable<StableHashingContext<'a>>, |
| V: HashStable<StableHashingContext<'a>>, |
| T: HashStable<StableHashingContext<'a>> |
| { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| let mir::Projection { |
| ref base, |
| ref elem, |
| } = *self; |
| |
| base.hash_stable(hcx, hasher); |
| elem.hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'a, 'gcx, V, T> HashStable<StableHashingContext<'a>> |
| for mir::ProjectionElem<'gcx, V, T> |
| where V: HashStable<StableHashingContext<'a>>, |
| T: HashStable<StableHashingContext<'a>> |
| { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| 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::SourceScopeData { span, parent_scope }); |
| impl_stable_hash_for!(struct mir::SourceScopeLocalData { |
| lint_root, safety |
| }); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for mir::Safety { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| 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<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Operand<'gcx> { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| 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<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Rvalue<'gcx> { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| 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<'a, 'gcx> HashStable<StableHashingContext<'a>> |
| for mir::AggregateKind<'gcx> { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| 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, 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<StableHashingContext<'a>> for mir::ClosureOutlivesSubject<'gcx> { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| 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); |
| } |
| } |
| } |
| } |
| |
| 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 }); |