| //! This module contains `HashStable` implementations for various HIR data |
| //! types in no particular order. |
| |
| use hir; |
| use hir::map::DefPathHash; |
| use hir::def_id::{DefId, LocalDefId, CrateNum, CRATE_DEF_INDEX}; |
| use ich::{StableHashingContext, NodeIdHashingMode, Fingerprint}; |
| use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, |
| StableHasher, StableHasherResult}; |
| use std::mem; |
| use syntax::ast; |
| use syntax::attr; |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for DefId { |
| #[inline] |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| hcx.def_path_hash(*self).hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'a> ToStableHashKey<StableHashingContext<'a>> for DefId { |
| type KeyType = DefPathHash; |
| |
| #[inline] |
| fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash { |
| hcx.def_path_hash(*self) |
| } |
| } |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for LocalDefId { |
| #[inline] |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| hcx.def_path_hash(self.to_def_id()).hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalDefId { |
| type KeyType = DefPathHash; |
| |
| #[inline] |
| fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash { |
| hcx.def_path_hash(self.to_def_id()) |
| } |
| } |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for CrateNum { |
| #[inline] |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| hcx.def_path_hash(DefId { |
| krate: *self, |
| index: CRATE_DEF_INDEX |
| }).hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum { |
| type KeyType = DefPathHash; |
| |
| #[inline] |
| fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash { |
| let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX }; |
| def_id.to_stable_hash_key(hcx) |
| } |
| } |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::ItemLocalId { |
| #[inline] |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| self.as_u32().hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'a> ToStableHashKey<StableHashingContext<'a>> |
| for hir::ItemLocalId { |
| type KeyType = hir::ItemLocalId; |
| |
| #[inline] |
| fn to_stable_hash_key(&self, |
| _: &StableHashingContext<'a>) |
| -> hir::ItemLocalId { |
| *self |
| } |
| } |
| |
| // The following implementations of HashStable for ItemId, TraitItemId, and |
| // ImplItemId deserve special attention. Normally we do not hash NodeIds within |
| // the HIR, since they just signify a HIR nodes own path. But ItemId et al |
| // are used when another item in the HIR is *referenced* and we certainly |
| // want to pick up on a reference changing its target, so we hash the NodeIds |
| // in "DefPath Mode". |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::ItemId { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| let hir::ItemId { |
| id |
| } = *self; |
| |
| hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { |
| id.hash_stable(hcx, hasher); |
| }) |
| } |
| } |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItemId { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| let hir::TraitItemId { |
| node_id |
| } = * self; |
| |
| hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { |
| node_id.hash_stable(hcx, hasher); |
| }) |
| } |
| } |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItemId { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| let hir::ImplItemId { |
| node_id |
| } = * self; |
| |
| hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { |
| node_id.hash_stable(hcx, hasher); |
| }) |
| } |
| } |
| |
| impl_stable_hash_for!(enum hir::ParamName { |
| Plain(name), |
| Fresh(index), |
| Error, |
| }); |
| |
| impl_stable_hash_for!(enum hir::LifetimeName { |
| Param(param_name), |
| Implicit, |
| Underscore, |
| Static, |
| Error, |
| }); |
| |
| impl_stable_hash_for!(struct ast::Label { |
| ident |
| }); |
| |
| impl_stable_hash_for!(struct hir::Lifetime { |
| id, |
| span, |
| name |
| }); |
| |
| impl_stable_hash_for!(struct hir::Path { |
| span, |
| def, |
| segments |
| }); |
| |
| impl_stable_hash_for!(struct hir::PathSegment { |
| ident -> (ident.name), |
| id, |
| def, |
| infer_types, |
| args |
| }); |
| |
| impl_stable_hash_for!(enum hir::GenericArg { |
| Lifetime(lt), |
| Type(ty) |
| }); |
| |
| impl_stable_hash_for!(struct hir::GenericArgs { |
| args, |
| bindings, |
| parenthesized |
| }); |
| |
| impl_stable_hash_for!(enum hir::GenericBound { |
| Trait(poly_trait_ref, trait_bound_modifier), |
| Outlives(lifetime) |
| }); |
| |
| impl_stable_hash_for!(enum hir::TraitBoundModifier { |
| None, |
| Maybe |
| }); |
| |
| impl_stable_hash_for!(struct hir::GenericParam { |
| id, |
| name, |
| pure_wrt_drop, |
| attrs, |
| bounds, |
| span, |
| kind |
| }); |
| |
| impl_stable_hash_for!(enum hir::LifetimeParamKind { |
| Explicit, |
| InBand, |
| Elided, |
| Error, |
| }); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::GenericParamKind { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| mem::discriminant(self).hash_stable(hcx, hasher); |
| match self { |
| hir::GenericParamKind::Lifetime { kind } => { |
| kind.hash_stable(hcx, hasher); |
| } |
| hir::GenericParamKind::Type { ref default, synthetic } => { |
| default.hash_stable(hcx, hasher); |
| synthetic.hash_stable(hcx, hasher); |
| } |
| } |
| } |
| } |
| |
| impl_stable_hash_for!(struct hir::Generics { |
| params, |
| where_clause, |
| span |
| }); |
| |
| impl_stable_hash_for!(enum hir::SyntheticTyParamKind { |
| ImplTrait |
| }); |
| |
| impl_stable_hash_for!(struct hir::WhereClause { |
| id, |
| predicates |
| }); |
| |
| impl_stable_hash_for!(enum hir::WherePredicate { |
| BoundPredicate(pred), |
| RegionPredicate(pred), |
| EqPredicate(pred) |
| }); |
| |
| impl_stable_hash_for!(struct hir::WhereBoundPredicate { |
| span, |
| bound_generic_params, |
| bounded_ty, |
| bounds |
| }); |
| |
| impl_stable_hash_for!(struct hir::WhereRegionPredicate { |
| span, |
| lifetime, |
| bounds |
| }); |
| |
| impl_stable_hash_for!(struct hir::WhereEqPredicate { |
| id, |
| span, |
| lhs_ty, |
| rhs_ty |
| }); |
| |
| impl_stable_hash_for!(struct hir::MutTy { |
| ty, |
| mutbl |
| }); |
| |
| impl_stable_hash_for!(struct hir::MethodSig { |
| header, |
| decl |
| }); |
| |
| impl_stable_hash_for!(struct hir::TypeBinding { |
| id, |
| ident -> (ident.name), |
| ty, |
| span |
| }); |
| |
| impl_stable_hash_for!(struct hir::FnHeader { |
| unsafety, |
| constness, |
| asyncness, |
| abi |
| }); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| hcx.while_hashing_hir_bodies(true, |hcx| { |
| let hir::Ty { |
| id: _, |
| hir_id: _, |
| ref node, |
| ref span, |
| } = *self; |
| |
| node.hash_stable(hcx, hasher); |
| span.hash_stable(hcx, hasher); |
| }) |
| } |
| } |
| |
| impl_stable_hash_for!(enum hir::PrimTy { |
| Int(int_ty), |
| Uint(uint_ty), |
| Float(float_ty), |
| Str, |
| Bool, |
| Char |
| }); |
| |
| impl_stable_hash_for!(struct hir::BareFnTy { |
| unsafety, |
| abi, |
| generic_params, |
| decl, |
| arg_names |
| }); |
| |
| impl_stable_hash_for!(struct hir::ExistTy { |
| generics, |
| impl_trait_fn, |
| bounds |
| }); |
| |
| impl_stable_hash_for!(enum hir::TyKind { |
| Slice(t), |
| Array(t, body_id), |
| Ptr(t), |
| Rptr(lifetime, t), |
| BareFn(t), |
| Never, |
| Tup(ts), |
| Path(qpath), |
| Def(it, lt), |
| TraitObject(trait_refs, lifetime), |
| Typeof(body_id), |
| Err, |
| Infer |
| }); |
| |
| impl_stable_hash_for!(struct hir::FnDecl { |
| inputs, |
| output, |
| variadic, |
| implicit_self |
| }); |
| |
| impl_stable_hash_for!(enum hir::FunctionRetTy { |
| DefaultReturn(span), |
| Return(t) |
| }); |
| |
| impl_stable_hash_for!(enum hir::ImplicitSelfKind { |
| Imm, |
| Mut, |
| ImmRef, |
| MutRef, |
| None |
| }); |
| |
| impl_stable_hash_for!(struct hir::TraitRef { |
| // Don't hash the ref_id. It is tracked via the thing it is used to access |
| ref_id -> _, |
| hir_ref_id -> _, |
| path, |
| }); |
| |
| impl_stable_hash_for!(struct hir::PolyTraitRef { |
| bound_generic_params, |
| trait_ref, |
| span |
| }); |
| |
| impl_stable_hash_for!(enum hir::QPath { |
| Resolved(t, path), |
| TypeRelative(t, path_segment) |
| }); |
| |
| impl_stable_hash_for!(struct hir::MacroDef { |
| name, |
| vis, |
| attrs, |
| id, |
| span, |
| legacy, |
| body |
| }); |
| |
| impl_stable_hash_for!(struct hir::Block { |
| stmts, |
| expr, |
| id -> _, |
| hir_id -> _, |
| rules, |
| span, |
| targeted_by_break, |
| }); |
| |
| impl_stable_hash_for!(struct hir::Pat { |
| id -> _, |
| hir_id -> _, |
| node, |
| span, |
| }); |
| |
| impl_stable_hash_for_spanned!(hir::FieldPat); |
| |
| impl_stable_hash_for!(struct hir::FieldPat { |
| id -> _, |
| ident -> (ident.name), |
| pat, |
| is_shorthand, |
| }); |
| |
| impl_stable_hash_for!(enum hir::BindingAnnotation { |
| Unannotated, |
| Mutable, |
| Ref, |
| RefMut |
| }); |
| |
| impl_stable_hash_for!(enum hir::RangeEnd { |
| Included, |
| Excluded |
| }); |
| |
| impl_stable_hash_for!(enum hir::PatKind { |
| Wild, |
| Binding(binding_mode, var, name, sub), |
| Struct(path, field_pats, dotdot), |
| TupleStruct(path, field_pats, dotdot), |
| Path(path), |
| Tuple(field_pats, dotdot), |
| Box(sub), |
| Ref(sub, mutability), |
| Lit(expr), |
| Range(start, end, end_kind), |
| Slice(one, two, three) |
| }); |
| |
| impl_stable_hash_for!(enum hir::BinOpKind { |
| Add, |
| Sub, |
| Mul, |
| Div, |
| Rem, |
| And, |
| Or, |
| BitXor, |
| BitAnd, |
| BitOr, |
| Shl, |
| Shr, |
| Eq, |
| Lt, |
| Le, |
| Ne, |
| Ge, |
| Gt |
| }); |
| |
| impl_stable_hash_for_spanned!(hir::BinOpKind); |
| |
| impl_stable_hash_for!(enum hir::UnOp { |
| UnDeref, |
| UnNot, |
| UnNeg |
| }); |
| |
| impl_stable_hash_for!(struct hir::Stmt { |
| id, |
| node, |
| span, |
| }); |
| |
| |
| impl_stable_hash_for!(struct hir::Local { |
| pat, |
| ty, |
| init, |
| id, |
| hir_id, |
| span, |
| attrs, |
| source |
| }); |
| |
| impl_stable_hash_for!(struct hir::Arm { |
| attrs, |
| pats, |
| guard, |
| body |
| }); |
| |
| impl_stable_hash_for!(enum hir::Guard { |
| If(expr), |
| }); |
| |
| impl_stable_hash_for!(struct hir::Field { |
| id -> _, |
| ident, |
| expr, |
| span, |
| is_shorthand, |
| }); |
| |
| impl_stable_hash_for_spanned!(ast::Name); |
| |
| |
| impl_stable_hash_for!(enum hir::BlockCheckMode { |
| DefaultBlock, |
| UnsafeBlock(src), |
| PushUnsafeBlock(src), |
| PopUnsafeBlock(src) |
| }); |
| |
| impl_stable_hash_for!(enum hir::UnsafeSource { |
| CompilerGenerated, |
| UserProvided |
| }); |
| |
| impl_stable_hash_for!(struct hir::AnonConst { |
| id, |
| hir_id, |
| body |
| }); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| hcx.while_hashing_hir_bodies(true, |hcx| { |
| let hir::Expr { |
| id: _, |
| hir_id: _, |
| ref span, |
| ref node, |
| ref attrs |
| } = *self; |
| |
| span.hash_stable(hcx, hasher); |
| node.hash_stable(hcx, hasher); |
| attrs.hash_stable(hcx, hasher); |
| }) |
| } |
| } |
| |
| impl_stable_hash_for!(enum hir::ExprKind { |
| Box(sub), |
| Array(subs), |
| Call(callee, args), |
| MethodCall(segment, span, args), |
| Tup(fields), |
| Binary(op, lhs, rhs), |
| Unary(op, operand), |
| Lit(value), |
| Cast(expr, t), |
| Type(expr, t), |
| If(cond, then, els), |
| While(cond, body, label), |
| Loop(body, label, loop_src), |
| Match(matchee, arms, match_src), |
| Closure(capture_clause, decl, body_id, span, gen), |
| Block(blk, label), |
| Assign(lhs, rhs), |
| AssignOp(op, lhs, rhs), |
| Field(owner, ident), |
| Index(lhs, rhs), |
| Path(path), |
| AddrOf(mutability, sub), |
| Break(destination, sub), |
| Continue(destination), |
| Ret(val), |
| InlineAsm(asm, inputs, outputs), |
| Struct(path, fields, base), |
| Repeat(val, times), |
| Yield(val), |
| Err |
| }); |
| |
| impl_stable_hash_for!(enum hir::LocalSource { |
| Normal, |
| ForLoopDesugar |
| }); |
| |
| impl_stable_hash_for!(enum hir::LoopSource { |
| Loop, |
| WhileLet, |
| ForLoop |
| }); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::MatchSource { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| use hir::MatchSource; |
| |
| mem::discriminant(self).hash_stable(hcx, hasher); |
| match *self { |
| MatchSource::Normal | |
| MatchSource::WhileLetDesugar | |
| MatchSource::ForLoopDesugar | |
| MatchSource::TryDesugar => { |
| // No fields to hash. |
| } |
| MatchSource::IfLetDesugar { contains_else_clause } => { |
| contains_else_clause.hash_stable(hcx, hasher); |
| } |
| } |
| } |
| } |
| |
| impl_stable_hash_for!(enum hir::GeneratorMovability { |
| Static, |
| Movable |
| }); |
| |
| impl_stable_hash_for!(enum hir::CaptureClause { |
| CaptureByValue, |
| CaptureByRef |
| }); |
| |
| impl_stable_hash_for_spanned!(usize); |
| |
| impl_stable_hash_for!(struct hir::Destination { |
| label, |
| target_id |
| }); |
| |
| impl_stable_hash_for_spanned!(ast::Ident); |
| |
| impl_stable_hash_for!(enum hir::LoopIdError { |
| OutsideLoopScope, |
| UnlabeledCfInWhileCondition, |
| UnresolvedLabel |
| }); |
| |
| impl_stable_hash_for!(struct ast::Ident { |
| name, |
| span, |
| }); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| let hir::TraitItem { |
| id: _, |
| hir_id: _, |
| ident, |
| ref attrs, |
| ref generics, |
| ref node, |
| span |
| } = *self; |
| |
| hcx.hash_hir_item_like(|hcx| { |
| ident.name.hash_stable(hcx, hasher); |
| attrs.hash_stable(hcx, hasher); |
| generics.hash_stable(hcx, hasher); |
| node.hash_stable(hcx, hasher); |
| span.hash_stable(hcx, hasher); |
| }); |
| } |
| } |
| |
| impl_stable_hash_for!(enum hir::TraitMethod { |
| Required(name), |
| Provided(body) |
| }); |
| |
| impl_stable_hash_for!(enum hir::TraitItemKind { |
| Const(t, body), |
| Method(sig, method), |
| Type(bounds, rhs) |
| }); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| let hir::ImplItem { |
| id: _, |
| hir_id: _, |
| ident, |
| ref vis, |
| defaultness, |
| ref attrs, |
| ref generics, |
| ref node, |
| span |
| } = *self; |
| |
| hcx.hash_hir_item_like(|hcx| { |
| ident.name.hash_stable(hcx, hasher); |
| vis.hash_stable(hcx, hasher); |
| defaultness.hash_stable(hcx, hasher); |
| attrs.hash_stable(hcx, hasher); |
| generics.hash_stable(hcx, hasher); |
| node.hash_stable(hcx, hasher); |
| span.hash_stable(hcx, hasher); |
| }); |
| } |
| } |
| |
| impl_stable_hash_for!(enum hir::ImplItemKind { |
| Const(t, body), |
| Method(sig, body), |
| Existential(bounds), |
| Type(t) |
| }); |
| |
| impl_stable_hash_for!(enum ::syntax::ast::CrateSugar { |
| JustCrate, |
| PubCrate, |
| }); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| mem::discriminant(self).hash_stable(hcx, hasher); |
| match *self { |
| hir::VisibilityKind::Public | |
| hir::VisibilityKind::Inherited => { |
| // No fields to hash. |
| } |
| hir::VisibilityKind::Crate(sugar) => { |
| sugar.hash_stable(hcx, hasher); |
| } |
| hir::VisibilityKind::Restricted { ref path, id, hir_id } => { |
| hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { |
| id.hash_stable(hcx, hasher); |
| hir_id.hash_stable(hcx, hasher); |
| }); |
| path.hash_stable(hcx, hasher); |
| } |
| } |
| } |
| } |
| |
| impl_stable_hash_for_spanned!(hir::VisibilityKind); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::Defaultness { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| mem::discriminant(self).hash_stable(hcx, hasher); |
| match *self { |
| hir::Defaultness::Final => { |
| // No fields to hash. |
| } |
| hir::Defaultness::Default { has_value } => { |
| has_value.hash_stable(hcx, hasher); |
| } |
| } |
| } |
| } |
| |
| impl_stable_hash_for!(enum hir::ImplPolarity { |
| Positive, |
| Negative |
| }); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| let hir::Mod { |
| inner: ref inner_span, |
| ref item_ids, |
| } = *self; |
| |
| inner_span.hash_stable(hcx, hasher); |
| |
| // Combining the DefPathHashes directly is faster than feeding them |
| // into the hasher. Because we use a commutative combine, we also don't |
| // have to sort the array. |
| let item_ids_hash = item_ids |
| .iter() |
| .map(|id| { |
| let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx); |
| debug_assert_eq!(local_id, hir::ItemLocalId::from_u32(0)); |
| def_path_hash.0 |
| }).fold(Fingerprint::ZERO, |a, b| { |
| a.combine_commutative(b) |
| }); |
| |
| item_ids.len().hash_stable(hcx, hasher); |
| item_ids_hash.hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl_stable_hash_for!(struct hir::ForeignMod { |
| abi, |
| items |
| }); |
| |
| impl_stable_hash_for!(struct hir::EnumDef { |
| variants |
| }); |
| |
| impl_stable_hash_for!(struct hir::VariantKind { |
| ident -> (ident.name), |
| attrs, |
| data, |
| disr_expr |
| }); |
| |
| impl_stable_hash_for_spanned!(hir::VariantKind); |
| |
| impl_stable_hash_for!(enum hir::UseKind { |
| Single, |
| Glob, |
| ListStem |
| }); |
| |
| impl_stable_hash_for!(struct hir::StructField { |
| span, |
| ident -> (ident.name), |
| vis, |
| id, |
| ty, |
| attrs |
| }); |
| |
| impl_stable_hash_for!(enum hir::VariantData { |
| Struct(fields, id), |
| Tuple(fields, id), |
| Unit(id) |
| }); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::Item { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| let hir::Item { |
| ident, |
| ref attrs, |
| id: _, |
| hir_id: _, |
| ref node, |
| ref vis, |
| span |
| } = *self; |
| |
| hcx.hash_hir_item_like(|hcx| { |
| ident.name.hash_stable(hcx, hasher); |
| attrs.hash_stable(hcx, hasher); |
| node.hash_stable(hcx, hasher); |
| vis.hash_stable(hcx, hasher); |
| span.hash_stable(hcx, hasher); |
| }); |
| } |
| } |
| |
| impl_stable_hash_for!(enum hir::ItemKind { |
| ExternCrate(orig_name), |
| Use(path, use_kind), |
| Static(ty, mutability, body_id), |
| Const(ty, body_id), |
| Fn(fn_decl, header, generics, body_id), |
| Mod(module), |
| ForeignMod(foreign_mod), |
| GlobalAsm(global_asm), |
| Ty(ty, generics), |
| Existential(exist), |
| Enum(enum_def, generics), |
| Struct(variant_data, generics), |
| Union(variant_data, generics), |
| Trait(is_auto, unsafety, generics, bounds, item_refs), |
| TraitAlias(generics, bounds), |
| Impl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs) |
| }); |
| |
| impl_stable_hash_for!(struct hir::TraitItemRef { |
| id, |
| ident -> (ident.name), |
| kind, |
| span, |
| defaultness |
| }); |
| |
| impl_stable_hash_for!(struct hir::ImplItemRef { |
| id, |
| ident -> (ident.name), |
| kind, |
| span, |
| vis, |
| defaultness |
| }); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::AssociatedItemKind { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| mem::discriminant(self).hash_stable(hcx, hasher); |
| match *self { |
| hir::AssociatedItemKind::Const | |
| hir::AssociatedItemKind::Existential | |
| hir::AssociatedItemKind::Type => { |
| // No fields to hash. |
| } |
| hir::AssociatedItemKind::Method { has_self } => { |
| has_self.hash_stable(hcx, hasher); |
| } |
| } |
| } |
| } |
| |
| impl_stable_hash_for!(struct hir::ForeignItem { |
| ident -> (ident.name), |
| attrs, |
| node, |
| id, |
| span, |
| vis |
| }); |
| |
| impl_stable_hash_for!(enum hir::ForeignItemKind { |
| Fn(fn_decl, arg_names, generics), |
| Static(ty, is_mutbl), |
| Type |
| }); |
| |
| impl_stable_hash_for!(enum hir::StmtKind { |
| Local(local), |
| Item(item_id), |
| Expr(expr), |
| Semi(expr) |
| }); |
| |
| impl_stable_hash_for!(struct hir::Arg { |
| pat, |
| id, |
| hir_id |
| }); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::Body { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| let hir::Body { |
| ref arguments, |
| ref value, |
| is_generator, |
| } = *self; |
| |
| hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| { |
| arguments.hash_stable(hcx, hasher); |
| value.hash_stable(hcx, hasher); |
| is_generator.hash_stable(hcx, hasher); |
| }); |
| } |
| } |
| |
| impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId { |
| type KeyType = (DefPathHash, hir::ItemLocalId); |
| |
| #[inline] |
| fn to_stable_hash_key(&self, |
| hcx: &StableHashingContext<'a>) |
| -> (DefPathHash, hir::ItemLocalId) { |
| let hir::BodyId { node_id } = *self; |
| node_id.to_stable_hash_key(hcx) |
| } |
| } |
| |
| impl_stable_hash_for!(struct hir::InlineAsmOutput { |
| constraint, |
| is_rw, |
| is_indirect, |
| span |
| }); |
| |
| impl_stable_hash_for!(struct hir::GlobalAsm { |
| asm, |
| ctxt -> _, // This is used for error reporting |
| }); |
| |
| impl_stable_hash_for!(struct hir::InlineAsm { |
| asm, |
| asm_str_style, |
| outputs, |
| inputs, |
| clobbers, |
| volatile, |
| alignstack, |
| dialect, |
| ctxt -> _, // This is used for error reporting |
| }); |
| |
| impl_stable_hash_for!(enum hir::def::CtorKind { |
| Fn, |
| Const, |
| Fictive |
| }); |
| |
| impl_stable_hash_for!(enum hir::def::NonMacroAttrKind { |
| Builtin, |
| Tool, |
| DeriveHelper, |
| LegacyPluginHelper, |
| Custom, |
| }); |
| |
| impl_stable_hash_for!(enum hir::def::Def { |
| Mod(def_id), |
| Struct(def_id), |
| Union(def_id), |
| Enum(def_id), |
| Existential(def_id), |
| Variant(def_id), |
| Trait(def_id), |
| TyAlias(def_id), |
| TraitAlias(def_id), |
| AssociatedTy(def_id), |
| AssociatedExistential(def_id), |
| PrimTy(prim_ty), |
| TyParam(def_id), |
| SelfTy(trait_def_id, impl_def_id), |
| ForeignTy(def_id), |
| Fn(def_id), |
| Const(def_id), |
| Static(def_id, is_mutbl), |
| StructCtor(def_id, ctor_kind), |
| SelfCtor(impl_def_id), |
| VariantCtor(def_id, ctor_kind), |
| Method(def_id), |
| AssociatedConst(def_id), |
| Local(def_id), |
| Upvar(def_id, index, expr_id), |
| Label(node_id), |
| Macro(def_id, macro_kind), |
| ToolMod, |
| NonMacroAttr(attr_kind), |
| Err |
| }); |
| |
| impl_stable_hash_for!(enum hir::Mutability { |
| MutMutable, |
| MutImmutable |
| }); |
| |
| impl_stable_hash_for!(enum hir::IsAuto { |
| Yes, |
| No |
| }); |
| |
| impl_stable_hash_for!(enum hir::Unsafety { |
| Unsafe, |
| Normal |
| }); |
| |
| impl_stable_hash_for!(enum hir::IsAsync { |
| Async, |
| NotAsync |
| }); |
| |
| impl_stable_hash_for!(enum hir::Constness { |
| Const, |
| NotConst |
| }); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex { |
| |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| hcx.local_def_path_hash(*self).hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'a> ToStableHashKey<StableHashingContext<'a>> |
| for hir::def_id::DefIndex { |
| type KeyType = DefPathHash; |
| |
| #[inline] |
| fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash { |
| hcx.local_def_path_hash(*self) |
| } |
| } |
| |
| impl_stable_hash_for!(struct hir::def::Export { |
| ident, |
| def, |
| vis, |
| span |
| }); |
| |
| impl_stable_hash_for!(struct ::middle::lib_features::LibFeatures { |
| stable, |
| unstable |
| }); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for ::middle::lang_items::LangItem { |
| fn hash_stable<W: StableHasherResult>(&self, |
| _: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| ::std::hash::Hash::hash(self, hasher); |
| } |
| } |
| |
| impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems { |
| items, |
| missing |
| }); |
| |
| impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'a>, |
| hasher: &mut StableHasher<W>) { |
| hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { |
| let hir::TraitCandidate { |
| def_id, |
| import_id, |
| } = *self; |
| |
| def_id.hash_stable(hcx, hasher); |
| import_id.hash_stable(hcx, hasher); |
| }); |
| } |
| } |
| |
| impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate { |
| type KeyType = (DefPathHash, Option<(DefPathHash, hir::ItemLocalId)>); |
| |
| fn to_stable_hash_key(&self, |
| hcx: &StableHashingContext<'a>) |
| -> Self::KeyType { |
| let hir::TraitCandidate { |
| def_id, |
| import_id, |
| } = *self; |
| |
| let import_id = import_id.map(|node_id| hcx.node_to_hir_id(node_id)) |
| .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner), |
| hir_id.local_id)); |
| (hcx.def_path_hash(def_id), import_id) |
| } |
| } |
| |
| impl_stable_hash_for!(struct hir::CodegenFnAttrs { |
| flags, |
| inline, |
| export_name, |
| link_name, |
| target_features, |
| linkage, |
| link_section, |
| }); |
| |
| impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags |
| { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'hir>, |
| hasher: &mut StableHasher<W>) { |
| self.bits().hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr { |
| fn hash_stable<W: StableHasherResult>(&self, |
| hcx: &mut StableHashingContext<'hir>, |
| hasher: &mut StableHasher<W>) { |
| mem::discriminant(self).hash_stable(hcx, hasher); |
| } |
| } |
| |
| impl_stable_hash_for!(struct hir::Freevar { |
| def, |
| span |
| }); |