//! 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_spanned!(hir::StmtKind);

impl_stable_hash_for!(struct hir::Local {
    pat,
    ty,
    init,
    id,
    hir_id,
    span,
    attrs,
    source
});

impl_stable_hash_for_spanned!(hir::DeclKind);
impl_stable_hash_for!(enum hir::DeclKind {
    Local(local),
    Item(item_id)
});

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 {
    Decl(decl, id),
    Expr(expr, id),
    Semi(expr, id)
});

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
});
