about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-01-02 05:18:45 +0100
committerMazdak Farrokhzad <twingoow@gmail.com>2020-01-04 19:03:27 +0100
commitef08662613ae80983dff32efda0c6275d1f86dda (patch)
tree97ec199befa56a62a5a7da732cd22e2aea264193
parent1f7b4e9a59ccb3e5d819900f45de81882e959c72 (diff)
downloadrust-ef08662613ae80983dff32efda0c6275d1f86dda.tar.gz
rust-ef08662613ae80983dff32efda0c6275d1f86dda.zip
hir::{hir,def,itemlikevisit,pat_util,print} -> rustc_hir
Also fix fallout wrt. HashStable.
-rw-r--r--src/librustc/hir.rs21
-rw-r--r--src/librustc/hir/map/mod.rs39
-rw-r--r--src/librustc/ich/hcx.rs33
-rw-r--r--src/librustc/ich/impls_hir.rs231
-rw-r--r--src/librustc/ich/impls_syntax.rs18
-rw-r--r--src/librustc_hir/def.rs (renamed from src/librustc/hir/def.rs)24
-rw-r--r--src/librustc_hir/hir.rs (renamed from src/librustc/hir/hir.rs)204
-rw-r--r--src/librustc_hir/itemlikevisit.rs (renamed from src/librustc/hir/itemlikevisit.rs)0
-rw-r--r--src/librustc_hir/lib.rs15
-rw-r--r--src/librustc_hir/pat_util.rs (renamed from src/librustc/hir/pat_util.rs)4
-rw-r--r--src/librustc_hir/print.rs (renamed from src/librustc/hir/print.rs)49
-rw-r--r--src/librustc_hir/stable_hash_impls.rs81
-rw-r--r--src/libsyntax/lib.rs12
13 files changed, 420 insertions, 311 deletions
diff --git a/src/librustc/hir.rs b/src/librustc/hir.rs
index ae19d82387d..62160fed1bc 100644
--- a/src/librustc/hir.rs
+++ b/src/librustc/hir.rs
@@ -3,24 +3,23 @@
 //! [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html
 
 pub mod check_attr;
-pub mod def;
+pub use rustc_hir::def;
 pub mod exports;
 pub use rustc_hir::def_id;
 pub use rustc_hir::hir_id::*;
 pub mod intravisit;
-pub mod itemlikevisit;
+pub use rustc_hir::itemlikevisit;
 pub mod map;
-pub mod pat_util;
-pub mod print;
+pub use rustc_hir::pat_util;
+pub use rustc_hir::print;
 pub mod upvars;
 
-mod hir;
-pub use hir::BlockCheckMode::*;
-pub use hir::FunctionRetTy::*;
-pub use hir::PrimTy::*;
-pub use hir::UnOp::*;
-pub use hir::UnsafeSource::*;
-pub use hir::*;
+pub use rustc_hir::BlockCheckMode::*;
+pub use rustc_hir::FunctionRetTy::*;
+pub use rustc_hir::PrimTy::*;
+pub use rustc_hir::UnOp::*;
+pub use rustc_hir::UnsafeSource::*;
+pub use rustc_hir::*;
 
 use crate::ty::query::Providers;
 
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 92547bbe038..b499ba20b8c 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -1266,45 +1266,6 @@ impl<'hir> print::PpAnn for Map<'hir> {
     }
 }
 
-impl<'a> print::State<'a> {
-    pub fn print_node(&mut self, node: Node<'_>) {
-        match node {
-            Node::Param(a) => self.print_param(&a),
-            Node::Item(a) => self.print_item(&a),
-            Node::ForeignItem(a) => self.print_foreign_item(&a),
-            Node::TraitItem(a) => self.print_trait_item(a),
-            Node::ImplItem(a) => self.print_impl_item(a),
-            Node::Variant(a) => self.print_variant(&a),
-            Node::AnonConst(a) => self.print_anon_const(&a),
-            Node::Expr(a) => self.print_expr(&a),
-            Node::Stmt(a) => self.print_stmt(&a),
-            Node::PathSegment(a) => self.print_path_segment(&a),
-            Node::Ty(a) => self.print_type(&a),
-            Node::TraitRef(a) => self.print_trait_ref(&a),
-            Node::Binding(a) | Node::Pat(a) => self.print_pat(&a),
-            Node::Arm(a) => self.print_arm(&a),
-            Node::Block(a) => {
-                // Containing cbox, will be closed by print-block at `}`.
-                self.cbox(print::INDENT_UNIT);
-                // Head-ibox, will be closed by print-block after `{`.
-                self.ibox(0);
-                self.print_block(&a)
-            }
-            Node::Lifetime(a) => self.print_lifetime(&a),
-            Node::Visibility(a) => self.print_visibility(&a),
-            Node::GenericParam(_) => bug!("cannot print Node::GenericParam"),
-            Node::Field(_) => bug!("cannot print StructField"),
-            // These cases do not carry enough information in the
-            // `hir_map` to reconstruct their full structure for pretty
-            // printing.
-            Node::Ctor(..) => bug!("cannot print isolated Ctor"),
-            Node::Local(a) => self.print_local_decl(&a),
-            Node::MacroDef(_) => bug!("cannot print MacroDef"),
-            Node::Crate => bug!("cannot print Crate"),
-        }
-    }
-}
-
 fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String {
     let id_str = format!(" (hir_id={})", id);
     let id_str = if include_id { &id_str[..] } else { "" };
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
index 44230fa0a44..86cad00af17 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc/ich/hcx.rs
@@ -33,10 +33,10 @@ pub struct StableHashingContext<'a> {
     sess: &'a Session,
     definitions: &'a Definitions,
     cstore: &'a dyn CrateStore,
-    body_resolver: BodyResolver<'a>,
+    pub(super) body_resolver: BodyResolver<'a>,
     hash_spans: bool,
     hash_bodies: bool,
-    node_id_hashing_mode: NodeIdHashingMode,
+    pub(super) node_id_hashing_mode: NodeIdHashingMode,
 
     // Very often, we are hashing something that does not need the
     // `CachingSourceMapView`, so we initialize it lazily.
@@ -54,12 +54,12 @@ pub enum NodeIdHashingMode {
 /// We could also just store a plain reference to the `hir::Crate` but we want
 /// to avoid that the crate is used to get untracked access to all of the HIR.
 #[derive(Clone, Copy)]
-struct BodyResolver<'tcx>(&'tcx hir::Crate<'tcx>);
+pub(super) struct BodyResolver<'tcx>(&'tcx hir::Crate<'tcx>);
 
 impl<'tcx> BodyResolver<'tcx> {
     /// Returns a reference to the `hir::Body` with the given `BodyId`.
     /// **Does not do any tracking**; use carefully.
-    fn body(self, id: hir::BodyId) -> &'tcx hir::Body<'tcx> {
+    pub(super) fn body(self, id: hir::BodyId) -> &'tcx hir::Body<'tcx> {
         self.0.body(id)
     }
 }
@@ -207,31 +207,6 @@ impl<'a> StableHashingContextProvider<'a> for StableHashingContext<'a> {
 
 impl<'a> crate::dep_graph::DepGraphSafe for StableHashingContext<'a> {}
 
-impl<'a> HashStable<StableHashingContext<'a>> for hir::BodyId {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        if hcx.hash_bodies() {
-            hcx.body_resolver.body(*self).hash_stable(hcx, hasher);
-        }
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for hir::HirId {
-    #[inline]
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        match hcx.node_id_hashing_mode {
-            NodeIdHashingMode::Ignore => {
-                // Don't do anything.
-            }
-            NodeIdHashingMode::HashDefPath => {
-                let hir::HirId { owner, local_id } = *self;
-
-                hcx.local_def_path_hash(owner).hash_stable(hcx, hasher);
-                local_id.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::HirId {
     type KeyType = (DefPathHash, hir::ItemLocalId);
 
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index 214a50456d5..f69051fd85d 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -11,10 +11,132 @@ use smallvec::SmallVec;
 use std::mem;
 use syntax::attr;
 
-impl<'a> HashStable<StableHashingContext<'a>> for DefId {
+impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
     #[inline]
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        hcx.def_path_hash(*self).hash_stable(hcx, hasher);
+    fn hash_def_id(&mut self, def_id: DefId, hasher: &mut StableHasher) {
+        let hcx = self;
+        hcx.def_path_hash(def_id).hash_stable(hcx, hasher);
+    }
+
+    #[inline]
+    fn hash_hir_id(&mut self, hir_id: hir::HirId, hasher: &mut StableHasher) {
+        let hcx = self;
+        match hcx.node_id_hashing_mode {
+            NodeIdHashingMode::Ignore => {
+                // Don't do anything.
+            }
+            NodeIdHashingMode::HashDefPath => {
+                let hir::HirId { owner, local_id } = hir_id;
+
+                hcx.local_def_path_hash(owner).hash_stable(hcx, hasher);
+                local_id.hash_stable(hcx, hasher);
+            }
+        }
+    }
+
+    fn hash_body_id(&mut self, id: hir::BodyId, hasher: &mut StableHasher) {
+        let hcx = self;
+        if hcx.hash_bodies() {
+            hcx.body_resolver.body(id).hash_stable(hcx, hasher);
+        }
+    }
+
+    // The following implementations of HashStable for `ItemId`, `TraitItemId`, and
+    // `ImplItemId` deserve special attention. Normally we do not hash `NodeId`s 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".
+
+    fn hash_item_id(&mut self, id: hir::ItemId, hasher: &mut StableHasher) {
+        let hcx = self;
+        let hir::ItemId { id } = id;
+
+        hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
+            id.hash_stable(hcx, hasher);
+        })
+    }
+
+    fn hash_impl_item_id(&mut self, id: hir::ImplItemId, hasher: &mut StableHasher) {
+        let hcx = self;
+        let hir::ImplItemId { hir_id } = id;
+
+        hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
+            hir_id.hash_stable(hcx, hasher);
+        })
+    }
+
+    fn hash_trait_item_id(&mut self, id: hir::TraitItemId, hasher: &mut StableHasher) {
+        let hcx = self;
+        let hir::TraitItemId { hir_id } = id;
+
+        hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
+            hir_id.hash_stable(hcx, hasher);
+        })
+    }
+
+    fn hash_hir_mod(&mut self, module: &hir::Mod<'_>, hasher: &mut StableHasher) {
+        let hcx = self;
+        let hir::Mod { inner: ref inner_span, ref item_ids } = *module;
+
+        inner_span.hash_stable(hcx, hasher);
+
+        // Combining the `DefPathHash`s 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);
+    }
+
+    fn hash_hir_expr(&mut self, expr: &hir::Expr<'_>, hasher: &mut StableHasher) {
+        self.while_hashing_hir_bodies(true, |hcx| {
+            let hir::Expr { hir_id: _, ref span, ref kind, ref attrs } = *expr;
+
+            span.hash_stable(hcx, hasher);
+            kind.hash_stable(hcx, hasher);
+            attrs.hash_stable(hcx, hasher);
+        })
+    }
+
+    fn hash_hir_ty(&mut self, ty: &hir::Ty<'_>, hasher: &mut StableHasher) {
+        self.while_hashing_hir_bodies(true, |hcx| {
+            let hir::Ty { hir_id: _, ref kind, ref span } = *ty;
+
+            kind.hash_stable(hcx, hasher);
+            span.hash_stable(hcx, hasher);
+        })
+    }
+
+    fn hash_hir_visibility_kind(
+        &mut self,
+        vis: &hir::VisibilityKind<'_>,
+        hasher: &mut StableHasher,
+    ) {
+        let hcx = self;
+        mem::discriminant(vis).hash_stable(hcx, hasher);
+        match *vis {
+            hir::VisibilityKind::Public | hir::VisibilityKind::Inherited => {
+                // No fields to hash.
+            }
+            hir::VisibilityKind::Crate(sugar) => {
+                sugar.hash_stable(hcx, hasher);
+            }
+            hir::VisibilityKind::Restricted { ref path, hir_id } => {
+                hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
+                    hir_id.hash_stable(hcx, hasher);
+                });
+                path.hash_stable(hcx, hasher);
+            }
+        }
     }
 }
 
@@ -69,66 +191,6 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::ItemLocalId {
     }
 }
 
-// The following implementations of HashStable for `ItemId`, `TraitItemId`, and
-// `ImplItemId` deserve special attention. Normally we do not hash `NodeId`s 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(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        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(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let hir::TraitItemId { hir_id } = *self;
-
-        hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
-            hir_id.hash_stable(hcx, hasher);
-        })
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItemId {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let hir::ImplItemId { hir_id } = *self;
-
-        hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
-            hir_id.hash_stable(hcx, hasher);
-        })
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty<'_> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        hcx.while_hashing_hir_bodies(true, |hcx| {
-            let hir::Ty { hir_id: _, ref kind, ref span } = *self;
-
-            kind.hash_stable(hcx, hasher);
-            span.hash_stable(hcx, hasher);
-        })
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr<'_> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        hcx.while_hashing_hir_bodies(true, |hcx| {
-            let hir::Expr { hir_id: _, ref span, ref kind, ref attrs } = *self;
-
-            span.hash_stable(hcx, hasher);
-            kind.hash_stable(hcx, hasher);
-            attrs.hash_stable(hcx, hasher);
-        })
-    }
-}
-
 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem<'_> {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         let hir::TraitItem { hir_id: _, ident, ref attrs, ref generics, ref kind, span } = *self;
@@ -168,49 +230,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem<'_> {
     }
 }
 
-impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind<'_> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        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, hir_id } => {
-                hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
-                    hir_id.hash_stable(hcx, hasher);
-                });
-                path.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod<'_> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let hir::Mod { inner: ref inner_span, ref item_ids } = *self;
-
-        inner_span.hash_stable(hcx, hasher);
-
-        // Combining the `DefPathHash`s 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<'a> HashStable<StableHashingContext<'a>> for hir::Item<'_> {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         let hir::Item { ident, ref attrs, hir_id: _, ref kind, ref vis, span } = *self;
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 90e1cac211a..e72a5241fad 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -43,25 +43,23 @@ impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
     }
 }
 
-impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
+impl<'ctx> syntax::HashStableContext for StableHashingContext<'ctx> {
+    fn hash_attr(&mut self, attr: &ast::Attribute, hasher: &mut StableHasher) {
         // Make sure that these have been filtered out.
-        debug_assert!(!self.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name)));
-        debug_assert!(!self.is_doc_comment());
+        debug_assert!(!attr.ident().map_or(false, |ident| self.is_ignored_attr(ident.name)));
+        debug_assert!(!attr.is_doc_comment());
 
-        let ast::Attribute { kind, id: _, style, span } = self;
+        let ast::Attribute { kind, id: _, style, span } = attr;
         if let ast::AttrKind::Normal(item) = kind {
-            item.hash_stable(hcx, hasher);
-            style.hash_stable(hcx, hasher);
-            span.hash_stable(hcx, hasher);
+            item.hash_stable(self, hasher);
+            style.hash_stable(self, hasher);
+            span.hash_stable(self, hasher);
         } else {
             unreachable!();
         }
     }
 }
 
-impl<'ctx> syntax::HashStableContext for StableHashingContext<'ctx> {}
-
 impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         let SourceFile {
diff --git a/src/librustc/hir/def.rs b/src/librustc_hir/def.rs
index 71ece0aadd3..83e30d85c5a 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc_hir/def.rs
@@ -1,7 +1,7 @@
+use crate::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use crate::hir;
-use crate::hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 
-use rustc_macros::HashStable;
+use rustc_macros::HashStable_Generic;
 use rustc_span::hygiene::MacroKind;
 use syntax::ast;
 use syntax::ast::NodeId;
@@ -9,7 +9,8 @@ use syntax::ast::NodeId;
 use std::fmt::Debug;
 
 /// Encodes if a `DefKind::Ctor` is the constructor of an enum variant or a struct.
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
+#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(HashStable_Generic)]
 pub enum CtorOf {
     /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit struct.
     Struct,
@@ -17,7 +18,8 @@ pub enum CtorOf {
     Variant,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
+#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(HashStable_Generic)]
 pub enum CtorKind {
     /// Constructor function automatically created by a tuple struct/variant.
     Fn,
@@ -27,7 +29,8 @@ pub enum CtorKind {
     Fictive,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
+#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(HashStable_Generic)]
 pub enum NonMacroAttrKind {
     /// Single-segment attribute defined by the language (`#[inline]`)
     Builtin,
@@ -39,7 +42,8 @@ pub enum NonMacroAttrKind {
     Registered,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
+#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(HashStable_Generic)]
 pub enum DefKind {
     // Type namespace
     Mod,
@@ -93,7 +97,7 @@ impl DefKind {
             DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct",
             DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct",
             DefKind::Ctor(CtorOf::Struct, CtorKind::Fictive) => {
-                bug!("impossible struct constructor")
+                panic!("impossible struct constructor")
             }
             DefKind::OpaqueTy => "opaque type",
             DefKind::TyAlias => "type alias",
@@ -154,7 +158,8 @@ impl DefKind {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
+#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(HashStable_Generic)]
 pub enum Res<Id = hir::HirId> {
     Def(DefKind, DefId),
 
@@ -341,7 +346,8 @@ impl<Id> Res<Id> {
     where
         Id: Debug,
     {
-        self.opt_def_id().unwrap_or_else(|| bug!("attempted .def_id() on invalid res: {:?}", self))
+        self.opt_def_id()
+            .unwrap_or_else(|| panic!("attempted .def_id() on invalid res: {:?}", self))
     }
 
     /// Return `Some(..)` with the `DefId` of this `Res` if it has a ID, else `None`.
diff --git a/src/librustc/hir/hir.rs b/src/librustc_hir/hir.rs
index da67cf3ccba..1fea05306b6 100644
--- a/src/librustc/hir/hir.rs
+++ b/src/librustc_hir/hir.rs
@@ -1,17 +1,17 @@
-//! HIR datatypes. See the [rustc guide] for more info.
-//!
-//! [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html
+use crate::def::{DefKind, Res};
+use crate::def_id::DefId;
+crate use crate::hir_id::HirId;
+use crate::itemlikevisit;
+use crate::print;
 
-use crate::hir::def::{DefKind, Res};
-use crate::hir::def_id::DefId;
-use crate::hir::itemlikevisit;
-use crate::hir::print;
-use rustc_hir::hir_id::HirId;
+crate use BlockCheckMode::*;
+crate use FunctionRetTy::*;
+crate use UnsafeSource::*;
 
 use errors::FatalError;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
-use rustc_macros::HashStable;
+use rustc_macros::HashStable_Generic;
 use rustc_session::node_id::NodeMap;
 use rustc_span::source_map::{SourceMap, Spanned};
 use rustc_span::symbol::{kw, sym, Symbol};
@@ -27,7 +27,7 @@ pub use syntax::ast::{CaptureBy, Constness, Movability, Mutability, Unsafety};
 use syntax::tokenstream::TokenStream;
 use syntax::util::parser::ExprPrecedence;
 
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, HashStable_Generic)]
 pub struct Lifetime {
     pub hir_id: HirId,
     pub span: Span,
@@ -41,7 +41,8 @@ pub struct Lifetime {
     pub name: LifetimeName,
 }
 
-#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy, HashStable)]
+#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
+#[derive(HashStable_Generic)]
 pub enum ParamName {
     /// Some user-given name like `T` or `'x`.
     Plain(Ident),
@@ -86,7 +87,8 @@ impl ParamName {
     }
 }
 
-#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy, HashStable)]
+#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
+#[derive(HashStable_Generic)]
 pub enum LifetimeName {
     /// User-given names or fresh (synthetic) names.
     Param(ParamName),
@@ -187,7 +189,7 @@ impl Lifetime {
 /// A `Path` is essentially Rust's notion of a name; for instance,
 /// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
 /// along with a bunch of supporting information.
-#[derive(RustcEncodable, RustcDecodable, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, HashStable_Generic)]
 pub struct Path<'hir> {
     pub span: Span,
     /// The resolution for the path.
@@ -216,7 +218,7 @@ impl fmt::Display for Path<'_> {
 
 /// A segment of a path: an identifier, an optional lifetime, and a set of
 /// types.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct PathSegment<'hir> {
     /// The identifier portion of this path segment.
     #[stable_hasher(project(name))]
@@ -259,13 +261,13 @@ impl<'hir> PathSegment<'hir> {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct ConstArg {
     pub value: AnonConst,
     pub span: Span,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum GenericArg<'hir> {
     Lifetime(Lifetime),
     Type(Ty<'hir>),
@@ -297,7 +299,7 @@ impl GenericArg<'_> {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct GenericArgs<'hir> {
     /// The generic arguments for this path segment.
     pub args: &'hir [GenericArg<'hir>],
@@ -334,7 +336,7 @@ impl GenericArgs<'_> {
                 }
             }
         }
-        bug!("GenericArgs::inputs: not a `Fn(T) -> U`");
+        panic!("GenericArgs::inputs: not a `Fn(T) -> U`");
     }
 
     pub fn own_counts(&self) -> GenericParamCount {
@@ -357,7 +359,8 @@ impl GenericArgs<'_> {
 
 /// A modifier on a bound, currently this is only used for `?Sized`, where the
 /// modifier is `Maybe`. Negative bounds should also be handled here.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(HashStable_Generic)]
 pub enum TraitBoundModifier {
     None,
     Maybe,
@@ -367,7 +370,7 @@ pub enum TraitBoundModifier {
 /// `typeck::collect::compute_bounds` matches these against
 /// the "special" built-in traits (see `middle::lang_items`) and
 /// detects `Copy`, `Send` and `Sync`.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum GenericBound<'hir> {
     Trait(PolyTraitRef<'hir>, TraitBoundModifier),
     Outlives(Lifetime),
@@ -384,7 +387,7 @@ impl GenericBound<'_> {
 
 pub type GenericBounds<'hir> = &'hir [GenericBound<'hir>];
 
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum LifetimeParamKind {
     // Indicates that the lifetime definition was explicitly declared (e.g., in
     // `fn foo<'a>(x: &'a u8) -> &'a u8 { x }`).
@@ -403,7 +406,7 @@ pub enum LifetimeParamKind {
     Error,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum GenericParamKind<'hir> {
     /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
     Lifetime {
@@ -418,7 +421,7 @@ pub enum GenericParamKind<'hir> {
     },
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct GenericParam<'hir> {
     pub hir_id: HirId,
     pub name: ParamName,
@@ -438,7 +441,7 @@ pub struct GenericParamCount {
 
 /// Represents lifetimes and type parameters attached to a declaration
 /// of a function, enum, trait, etc.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct Generics<'hir> {
     pub params: &'hir [GenericParam<'hir>],
     pub where_clause: WhereClause<'hir>,
@@ -491,13 +494,14 @@ impl Generics<'hir> {
 
 /// Synthetic type parameters are converted to another form during lowering; this allows
 /// us to track the original form they had, and is useful for error messages.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(HashStable_Generic)]
 pub enum SyntheticTyParamKind {
     ImplTrait,
 }
 
 /// A where-clause in a definition.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct WhereClause<'hir> {
     pub predicates: &'hir [WherePredicate<'hir>],
     // Only valid if predicates isn't empty.
@@ -517,7 +521,7 @@ impl WhereClause<'_> {
 }
 
 /// A single predicate in a where-clause.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum WherePredicate<'hir> {
     /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
     BoundPredicate(WhereBoundPredicate<'hir>),
@@ -538,7 +542,7 @@ impl WherePredicate<'_> {
 }
 
 /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct WhereBoundPredicate<'hir> {
     pub span: Span,
     /// Any generics from a `for` binding.
@@ -550,7 +554,7 @@ pub struct WhereBoundPredicate<'hir> {
 }
 
 /// A lifetime predicate (e.g., `'a: 'b + 'c`).
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct WhereRegionPredicate<'hir> {
     pub span: Span,
     pub lifetime: Lifetime,
@@ -558,7 +562,7 @@ pub struct WhereRegionPredicate<'hir> {
 }
 
 /// An equality predicate (e.g., `T = int`); currently unsupported.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct WhereEqPredicate<'hir> {
     pub hir_id: HirId,
     pub span: Span,
@@ -663,7 +667,7 @@ impl Crate<'_> {
     where
         V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send,
     {
-        parallel!(
+        rustc_data_structures::parallel!(
             {
                 par_for_each_in(&self.items, |(_, item)| {
                     visitor.visit_item(item);
@@ -686,7 +690,7 @@ impl Crate<'_> {
 /// A macro definition, in this crate or imported from another.
 ///
 /// Not parsed directly, but created on macro import or `macro_rules!` expansion.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct MacroDef<'hir> {
     pub name: Name,
     pub vis: Visibility<'hir>,
@@ -700,7 +704,7 @@ pub struct MacroDef<'hir> {
 /// A block of statements `{ .. }`, which may have a label (in this case the
 /// `targeted_by_break` field will be `true`) and may be `unsafe` by means of
 /// the `rules` being anything but `DefaultBlock`.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct Block<'hir> {
     /// Statements in a block.
     pub stmts: &'hir [Stmt<'hir>],
@@ -718,7 +722,7 @@ pub struct Block<'hir> {
     pub targeted_by_break: bool,
 }
 
-#[derive(RustcEncodable, RustcDecodable, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, HashStable_Generic)]
 pub struct Pat<'hir> {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
@@ -807,7 +811,7 @@ impl Pat<'_> {
 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
 /// except `is_shorthand` is true.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct FieldPat<'hir> {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
@@ -823,7 +827,7 @@ pub struct FieldPat<'hir> {
 /// Explicit binding annotations given in the HIR for a binding. Note
 /// that this is not the final binding *mode* that we infer after type
 /// inference.
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum BindingAnnotation {
     /// No binding annotation given: this means that the final binding mode
     /// will depend on whether we have skipped through a `&` reference
@@ -844,7 +848,7 @@ pub enum BindingAnnotation {
     RefMut,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum RangeEnd {
     Included,
     Excluded,
@@ -859,7 +863,7 @@ impl fmt::Display for RangeEnd {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum PatKind<'hir> {
     /// Represents a wildcard pattern (i.e., `_`).
     Wild,
@@ -915,7 +919,7 @@ pub enum PatKind<'hir> {
     Slice(&'hir [&'hir Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [&'hir Pat<'hir>]),
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum BinOpKind {
     /// The `+` operator (addition).
     Add,
@@ -1049,7 +1053,7 @@ impl Into<ast::BinOpKind> for BinOpKind {
 
 pub type BinOp = Spanned<BinOpKind>;
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum UnOp {
     /// The `*` operator (deferencing).
     UnDeref,
@@ -1078,7 +1082,7 @@ impl UnOp {
 }
 
 /// A statement.
-#[derive(RustcEncodable, RustcDecodable, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, HashStable_Generic)]
 pub struct Stmt<'hir> {
     pub hir_id: HirId,
     pub kind: StmtKind<'hir>,
@@ -1097,7 +1101,7 @@ impl fmt::Debug for Stmt<'_> {
 }
 
 /// The contents of a statement.
-#[derive(RustcEncodable, RustcDecodable, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, HashStable_Generic)]
 pub enum StmtKind<'hir> {
     /// A local (`let`) binding.
     Local(&'hir Local<'hir>),
@@ -1123,7 +1127,7 @@ impl StmtKind<'hir> {
 }
 
 /// Represents a `let` statement (i.e., `let <pat>:<ty> = <expr>;`).
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct Local<'hir> {
     pub pat: &'hir Pat<'hir>,
     /// Type annotation, if any (otherwise the type will be inferred).
@@ -1140,7 +1144,7 @@ pub struct Local<'hir> {
 
 /// Represents a single arm of a `match` expression, e.g.
 /// `<pat> (if <guard>) => <body>`.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct Arm<'hir> {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
@@ -1154,12 +1158,12 @@ pub struct Arm<'hir> {
     pub body: &'hir Expr<'hir>,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum Guard<'hir> {
     If(&'hir Expr<'hir>),
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct Field<'hir> {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
@@ -1169,7 +1173,7 @@ pub struct Field<'hir> {
     pub is_shorthand: bool,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum BlockCheckMode {
     DefaultBlock,
     UnsafeBlock(UnsafeSource),
@@ -1177,7 +1181,7 @@ pub enum BlockCheckMode {
     PopUnsafeBlock(UnsafeSource),
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum UnsafeSource {
     CompilerGenerated,
     UserProvided,
@@ -1227,7 +1231,7 @@ impl Body<'hir> {
 }
 
 /// The type of source expression that caused this generator to be created.
-#[derive(Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, Eq, HashStable_Generic, RustcEncodable, RustcDecodable, Debug, Copy)]
 pub enum GeneratorKind {
     /// An explicit `async` block or the body of an async function.
     Async(AsyncGeneratorKind),
@@ -1250,7 +1254,7 @@ impl fmt::Display for GeneratorKind {
 ///
 /// This helps error messages but is also used to drive coercions in
 /// type-checking (see #60424).
-#[derive(Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, Eq, HashStable_Generic, RustcEncodable, RustcDecodable, Debug, Copy)]
 pub enum AsyncGeneratorKind {
     /// An explicit `async` block written by the user.
     Block,
@@ -1304,7 +1308,7 @@ pub type Lit = Spanned<LitKind>;
 /// These are usually found nested inside types (e.g., array lengths)
 /// or expressions (e.g., repeat counts), and also used to define
 /// explicit discriminant values for enum variants.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct AnonConst {
     pub hir_id: HirId,
     pub body: BodyId,
@@ -1321,7 +1325,7 @@ pub struct Expr<'hir> {
 
 // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(Expr<'static>, 64);
+rustc_data_structures::static_assert_size!(Expr<'static>, 64);
 
 impl Expr<'_> {
     pub fn precedence(&self) -> ExprPrecedence {
@@ -1505,7 +1509,7 @@ pub fn is_range_literal(sm: &SourceMap, expr: &Expr<'_>) -> bool {
     false
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum ExprKind<'hir> {
     /// A `box x` expression.
     Box(&'hir Expr<'hir>),
@@ -1618,7 +1622,7 @@ pub enum ExprKind<'hir> {
 /// To resolve the path to a `DefId`, call [`qpath_res`].
 ///
 /// [`qpath_res`]: ../ty/struct.TypeckTables.html#method.qpath_res
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum QPath<'hir> {
     /// Path to a definition, optionally "fully-qualified" with a `Self`
     /// type, if the path points to an associated item in a trait.
@@ -1638,7 +1642,7 @@ pub enum QPath<'hir> {
 }
 
 /// Hints at the original code for a let statement.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum LocalSource {
     /// A `match _ { .. }`.
     Normal,
@@ -1660,7 +1664,8 @@ pub enum LocalSource {
 }
 
 /// Hints at the original code for a `match _ { .. }`.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(HashStable_Generic)]
 pub enum MatchSource {
     /// A `match _ { .. }`.
     Normal,
@@ -1696,7 +1701,7 @@ impl MatchSource {
 }
 
 /// The loop type that yielded an `ExprKind::Loop`.
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum LoopSource {
     /// A `loop { .. }` loop.
     Loop,
@@ -1718,7 +1723,7 @@ impl LoopSource {
     }
 }
 
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum LoopIdError {
     OutsideLoopScope,
     UnlabeledCfInWhileCondition,
@@ -1737,7 +1742,7 @@ impl fmt::Display for LoopIdError {
     }
 }
 
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct Destination {
     // This is `Some(_)` iff there is an explicit user-specified `label
     pub label: Option<Label>,
@@ -1748,7 +1753,7 @@ pub struct Destination {
 }
 
 /// The yield kind that caused an `ExprKind::Yield`.
-#[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable, HashStable_Generic)]
 pub enum YieldSource {
     /// An `<expr>.await`.
     Await,
@@ -1777,7 +1782,7 @@ impl From<GeneratorKind> for YieldSource {
 
 // N.B., if you change this, you'll probably want to change the corresponding
 // type structure in middle/ty.rs as well.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct MutTy<'hir> {
     pub ty: &'hir Ty<'hir>,
     pub mutbl: Mutability,
@@ -1785,7 +1790,7 @@ pub struct MutTy<'hir> {
 
 /// Represents a function's signature in a trait declaration,
 /// trait implementation, or a free function.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct FnSig<'hir> {
     pub header: FnHeader,
     pub decl: &'hir FnDecl<'hir>,
@@ -1814,7 +1819,7 @@ pub struct TraitItem<'hir> {
 }
 
 /// Represents a trait method's body (or just argument names).
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum TraitMethod<'hir> {
     /// No default body in the trait, just a signature.
     Required(&'hir [Ident]),
@@ -1824,7 +1829,7 @@ pub enum TraitMethod<'hir> {
 }
 
 /// Represents a trait method or associated constant or type
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum TraitItemKind<'hir> {
     /// An associated constant with an optional value (otherwise `impl`s must contain a value).
     Const(&'hir Ty<'hir>, Option<BodyId>),
@@ -1857,7 +1862,7 @@ pub struct ImplItem<'hir> {
 }
 
 /// Represents various kinds of content within an `impl`.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum ImplItemKind<'hir> {
     /// An associated constant of the given type, set to the constant result
     /// of the expression.
@@ -1885,7 +1890,7 @@ pub enum ImplItemKind<'hir> {
 ///    Binding(...),
 /// }
 /// ```
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct TypeBinding<'hir> {
     pub hir_id: HirId,
     #[stable_hasher(project(name))]
@@ -1895,7 +1900,7 @@ pub struct TypeBinding<'hir> {
 }
 
 // Represents the two kinds of type bindings.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum TypeBindingKind<'hir> {
     /// E.g., `Foo<Bar: Send>`.
     Constraint { bounds: &'hir [GenericBound<'hir>] },
@@ -1907,7 +1912,7 @@ impl TypeBinding<'_> {
     pub fn ty(&self) -> &Ty<'_> {
         match self.kind {
             TypeBindingKind::Equality { ref ty } => ty,
-            _ => bug!("expected equality type binding for parenthesized generic args"),
+            _ => panic!("expected equality type binding for parenthesized generic args"),
         }
     }
 }
@@ -1926,7 +1931,8 @@ impl fmt::Debug for Ty<'_> {
 }
 
 /// Not represented directly in the AST; referred to by name through a `ty_path`.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(HashStable_Generic)]
 pub enum PrimTy {
     Int(IntTy),
     Uint(UintTy),
@@ -1936,7 +1942,7 @@ pub enum PrimTy {
     Char,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct BareFnTy<'hir> {
     pub unsafety: Unsafety,
     pub abi: Abi,
@@ -1945,7 +1951,7 @@ pub struct BareFnTy<'hir> {
     pub param_names: &'hir [Ident],
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct OpaqueTy<'hir> {
     pub generics: Generics<'hir>,
     pub bounds: GenericBounds<'hir>,
@@ -1954,7 +1960,7 @@ pub struct OpaqueTy<'hir> {
 }
 
 /// From whence the opaque type came.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum OpaqueTyOrigin {
     /// `type Foo = impl Trait;`
     TypeAlias,
@@ -1965,7 +1971,7 @@ pub enum OpaqueTyOrigin {
 }
 
 /// The various kinds of types recognized by the compiler.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum TyKind<'hir> {
     /// A variable length slice (i.e., `[T]`).
     Slice(&'hir Ty<'hir>),
@@ -2004,7 +2010,7 @@ pub enum TyKind<'hir> {
     Err,
 }
 
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable, PartialEq)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic, PartialEq)]
 pub struct InlineAsmOutput {
     pub constraint: Symbol,
     pub is_rw: bool,
@@ -2014,7 +2020,7 @@ pub struct InlineAsmOutput {
 
 // NOTE(eddyb) This is used within MIR as well, so unlike the rest of the HIR,
 // it needs to be `Clone` and use plain `Vec<T>` instead of arena-allocated slice.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable, PartialEq)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic, PartialEq)]
 pub struct InlineAsmInner {
     pub asm: Symbol,
     pub asm_str_style: StrStyle,
@@ -2026,7 +2032,7 @@ pub struct InlineAsmInner {
     pub dialect: AsmDialect,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct InlineAsm<'hir> {
     pub inner: InlineAsmInner,
     pub outputs_exprs: &'hir [Expr<'hir>],
@@ -2034,7 +2040,7 @@ pub struct InlineAsm<'hir> {
 }
 
 /// Represents a parameter in a function header.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct Param<'hir> {
     pub attrs: &'hir [Attribute],
     pub hir_id: HirId,
@@ -2043,7 +2049,7 @@ pub struct Param<'hir> {
 }
 
 /// Represents the header (not the body) of a function declaration.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct FnDecl<'hir> {
     /// The types of the function's parameters.
     ///
@@ -2056,7 +2062,7 @@ pub struct FnDecl<'hir> {
 }
 
 /// Represents what type of implicit self a function has, if any.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum ImplicitSelfKind {
     /// Represents a `fn x(self);`.
     Imm,
@@ -2087,7 +2093,7 @@ impl ImplicitSelfKind {
     PartialEq,
     Eq,
     PartialOrd,
-    HashStable,
+    HashStable_Generic,
     Ord,
     RustcEncodable,
     RustcDecodable,
@@ -2098,7 +2104,7 @@ pub enum IsAsync {
     NotAsync,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum Defaultness {
     Default { has_value: bool },
     Final,
@@ -2124,7 +2130,7 @@ impl Defaultness {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum FunctionRetTy<'hir> {
     /// Return type is not specified.
     ///
@@ -2163,23 +2169,23 @@ pub struct Mod<'hir> {
     pub item_ids: &'hir [ItemId],
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct ForeignMod<'hir> {
     pub abi: Abi,
     pub items: &'hir [ForeignItem<'hir>],
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct GlobalAsm {
     pub asm: Symbol,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct EnumDef<'hir> {
     pub variants: &'hir [Variant<'hir>],
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct Variant<'hir> {
     /// Name of the variant.
     #[stable_hasher(project(name))]
@@ -2196,7 +2202,7 @@ pub struct Variant<'hir> {
     pub span: Span,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum UseKind {
     /// One import, e.g., `use foo::bar` or `use foo::bar as baz`.
     /// Also produced for each element of a list `use`, e.g.
@@ -2218,7 +2224,7 @@ pub enum UseKind {
 /// that the `ref_id` is for. Note that `ref_id`'s value is not the `HirId` of the
 /// trait being referred to but just a unique `HirId` that serves as a key
 /// within the resolution map.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct TraitRef<'hir> {
     pub path: &'hir Path<'hir>,
     // Don't hash the `ref_id`. It is tracked via the thing it is used to access.
@@ -2240,7 +2246,7 @@ impl TraitRef<'_> {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct PolyTraitRef<'hir> {
     /// The `'a` in `<'a> Foo<&'a T>`.
     pub bound_generic_params: &'hir [GenericParam<'hir>],
@@ -2286,7 +2292,7 @@ impl VisibilityKind<'_> {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct StructField<'hir> {
     pub span: Span,
     #[stable_hasher(project(name))]
@@ -2306,7 +2312,7 @@ impl StructField<'_> {
 }
 
 /// Fields and constructor IDs of enum variants and structs.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum VariantData<'hir> {
     /// A struct variant.
     ///
@@ -2361,7 +2367,7 @@ pub struct Item<'hir> {
     pub span: Span,
 }
 
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct FnHeader {
     pub unsafety: Unsafety,
     pub constness: Constness,
@@ -2378,7 +2384,7 @@ impl FnHeader {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum ItemKind<'hir> {
     /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
     ///
@@ -2474,7 +2480,7 @@ impl ItemKind<'_> {
 /// type or method, and whether it is public). This allows other
 /// passes to find the impl they want without loading the ID (which
 /// means fewer edges in the incremental compilation graph).
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct TraitItemRef {
     pub id: TraitItemId,
     #[stable_hasher(project(name))]
@@ -2490,7 +2496,7 @@ pub struct TraitItemRef {
 /// type or method, and whether it is public). This allows other
 /// passes to find the impl they want without loading the ID (which
 /// means fewer edges in the incremental compilation graph).
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct ImplItemRef<'hir> {
     pub id: ImplItemId,
     #[stable_hasher(project(name))]
@@ -2501,7 +2507,7 @@ pub struct ImplItemRef<'hir> {
     pub defaultness: Defaultness,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum AssocItemKind {
     Const,
     Method { has_self: bool },
@@ -2509,7 +2515,7 @@ pub enum AssocItemKind {
     OpaqueTy,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct ForeignItem<'hir> {
     #[stable_hasher(project(name))]
     pub ident: Ident,
@@ -2521,7 +2527,7 @@ pub struct ForeignItem<'hir> {
 }
 
 /// An item within an `extern` block.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum ForeignItemKind<'hir> {
     /// A foreign function.
     Fn(&'hir FnDecl<'hir>, &'hir [Ident], Generics<'hir>),
@@ -2542,7 +2548,7 @@ impl ForeignItemKind<'hir> {
 }
 
 /// A variable captured by a closure.
-#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable_Generic)]
 pub struct Upvar {
     // First span where it is accessed (there can be multiple).
     pub span: Span,
diff --git a/src/librustc/hir/itemlikevisit.rs b/src/librustc_hir/itemlikevisit.rs
index 369cd49621b..369cd49621b 100644
--- a/src/librustc/hir/itemlikevisit.rs
+++ b/src/librustc_hir/itemlikevisit.rs
diff --git a/src/librustc_hir/lib.rs b/src/librustc_hir/lib.rs
index 7e778736634..4bd1934fac4 100644
--- a/src/librustc_hir/lib.rs
+++ b/src/librustc_hir/lib.rs
@@ -1,5 +1,20 @@
+//! HIR datatypes. See the [rustc guide] for more info.
+//!
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html
+
+#![feature(crate_visibility_modifier)]
+#![feature(const_fn)]
+#![feature(in_band_lifetimes)]
 #![feature(specialization)]
 
+pub mod def;
 pub mod def_id;
+mod hir;
 pub mod hir_id;
+pub mod itemlikevisit;
+pub mod pat_util;
+pub mod print;
+mod stable_hash_impls;
+pub use hir::*;
 pub use hir_id::*;
+pub use stable_hash_impls::HashStableContext;
diff --git a/src/librustc/hir/pat_util.rs b/src/librustc_hir/pat_util.rs
index 56b557b409c..6bca45b4f83 100644
--- a/src/librustc/hir/pat_util.rs
+++ b/src/librustc_hir/pat_util.rs
@@ -1,5 +1,5 @@
-use crate::hir::def::{CtorOf, DefKind, Res};
-use crate::hir::def_id::DefId;
+use crate::def::{CtorOf, DefKind, Res};
+use crate::def_id::DefId;
 use crate::hir::{self, HirId, PatKind};
 use rustc_span::Span;
 use syntax::ast;
diff --git a/src/librustc/hir/print.rs b/src/librustc_hir/print.rs
index c457fc657a1..571bab2cb83 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc_hir/print.rs
@@ -10,7 +10,7 @@ use syntax::sess::ParseSess;
 use syntax::util::parser::{self, AssocOp, Fixity};
 
 use crate::hir;
-use crate::hir::{GenericArg, GenericParam, GenericParamKind};
+use crate::hir::{GenericArg, GenericParam, GenericParamKind, Node};
 use crate::hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier};
 
 use std::borrow::Cow;
@@ -69,6 +69,45 @@ pub struct State<'a> {
     ann: &'a (dyn PpAnn + 'a),
 }
 
+impl<'a> State<'a> {
+    pub fn print_node(&mut self, node: Node<'_>) {
+        match node {
+            Node::Param(a) => self.print_param(&a),
+            Node::Item(a) => self.print_item(&a),
+            Node::ForeignItem(a) => self.print_foreign_item(&a),
+            Node::TraitItem(a) => self.print_trait_item(a),
+            Node::ImplItem(a) => self.print_impl_item(a),
+            Node::Variant(a) => self.print_variant(&a),
+            Node::AnonConst(a) => self.print_anon_const(&a),
+            Node::Expr(a) => self.print_expr(&a),
+            Node::Stmt(a) => self.print_stmt(&a),
+            Node::PathSegment(a) => self.print_path_segment(&a),
+            Node::Ty(a) => self.print_type(&a),
+            Node::TraitRef(a) => self.print_trait_ref(&a),
+            Node::Binding(a) | Node::Pat(a) => self.print_pat(&a),
+            Node::Arm(a) => self.print_arm(&a),
+            Node::Block(a) => {
+                // Containing cbox, will be closed by print-block at `}`.
+                self.cbox(INDENT_UNIT);
+                // Head-ibox, will be closed by print-block after `{`.
+                self.ibox(0);
+                self.print_block(&a)
+            }
+            Node::Lifetime(a) => self.print_lifetime(&a),
+            Node::Visibility(a) => self.print_visibility(&a),
+            Node::GenericParam(_) => panic!("cannot print Node::GenericParam"),
+            Node::Field(_) => panic!("cannot print StructField"),
+            // These cases do not carry enough information in the
+            // `hir_map` to reconstruct their full structure for pretty
+            // printing.
+            Node::Ctor(..) => panic!("cannot print isolated Ctor"),
+            Node::Local(a) => self.print_local_decl(&a),
+            Node::MacroDef(_) => panic!("cannot print MacroDef"),
+            Node::Crate => panic!("cannot print Crate"),
+        }
+    }
+}
+
 impl std::ops::Deref for State<'_> {
     type Target = pp::Printer;
     fn deref(&self) -> &Self::Target {
@@ -92,8 +131,8 @@ impl<'a> PrintState<'a> for State<'a> {
         self.ann.post(self, AnnNode::Name(&ident.name))
     }
 
-    fn print_generic_args(&mut self, args: &ast::GenericArgs, _colons_before_params: bool) {
-        span_bug!(args.span(), "AST generic args printed by HIR pretty-printer");
+    fn print_generic_args(&mut self, _: &ast::GenericArgs, _colons_before_params: bool) {
+        panic!("AST generic args printed by HIR pretty-printer");
     }
 }
 
@@ -1960,7 +1999,7 @@ impl<'a> State<'a> {
                             self.print_lifetime(lt);
                             sep = "+";
                         }
-                        _ => bug!(),
+                        _ => panic!(),
                     }
                 }
             }
@@ -2023,7 +2062,7 @@ impl<'a> State<'a> {
                             GenericBound::Outlives(lt) => {
                                 self.print_lifetime(lt);
                             }
-                            _ => bug!(),
+                            _ => panic!(),
                         }
 
                         if i != 0 {
diff --git a/src/librustc_hir/stable_hash_impls.rs b/src/librustc_hir/stable_hash_impls.rs
new file mode 100644
index 00000000000..696a350ebdd
--- /dev/null
+++ b/src/librustc_hir/stable_hash_impls.rs
@@ -0,0 +1,81 @@
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+
+use crate::def_id::DefId;
+use crate::hir::{BodyId, Expr, ImplItemId, ItemId, Mod, TraitItemId, Ty, VisibilityKind};
+use crate::hir_id::HirId;
+
+/// Requirements for a `StableHashingContext` to be used in this crate.
+/// This is a hack to allow using the `HashStable_Generic` derive macro
+/// instead of implementing everything in librustc.
+pub trait HashStableContext: syntax::HashStableContext + rustc_target::HashStableContext {
+    fn hash_def_id(&mut self, _: DefId, hasher: &mut StableHasher);
+    fn hash_hir_id(&mut self, _: HirId, hasher: &mut StableHasher);
+    fn hash_body_id(&mut self, _: BodyId, hasher: &mut StableHasher);
+    fn hash_item_id(&mut self, _: ItemId, hasher: &mut StableHasher);
+    fn hash_impl_item_id(&mut self, _: ImplItemId, hasher: &mut StableHasher);
+    fn hash_trait_item_id(&mut self, _: TraitItemId, hasher: &mut StableHasher);
+    fn hash_hir_mod(&mut self, _: &Mod<'_>, hasher: &mut StableHasher);
+    fn hash_hir_expr(&mut self, _: &Expr<'_>, hasher: &mut StableHasher);
+    fn hash_hir_ty(&mut self, _: &Ty<'_>, hasher: &mut StableHasher);
+    fn hash_hir_visibility_kind(&mut self, _: &VisibilityKind<'_>, hasher: &mut StableHasher);
+}
+
+impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for HirId {
+    fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
+        hcx.hash_hir_id(*self, hasher)
+    }
+}
+
+impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for DefId {
+    fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
+        hcx.hash_def_id(*self, hasher)
+    }
+}
+
+impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for BodyId {
+    fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
+        hcx.hash_body_id(*self, hasher)
+    }
+}
+
+impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ItemId {
+    fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
+        hcx.hash_item_id(*self, hasher)
+    }
+}
+
+impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ImplItemId {
+    fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
+        hcx.hash_impl_item_id(*self, hasher)
+    }
+}
+
+impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for TraitItemId {
+    fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
+        hcx.hash_trait_item_id(*self, hasher)
+    }
+}
+
+impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Mod<'_> {
+    fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
+        hcx.hash_hir_mod(self, hasher)
+    }
+}
+
+impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Expr<'_> {
+    fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
+        hcx.hash_hir_expr(self, hasher)
+    }
+}
+
+impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Ty<'_> {
+    fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
+        hcx.hash_hir_ty(self, hasher)
+    }
+}
+
+impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for VisibilityKind<'_> {
+    fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
+        hcx.hash_hir_visibility_kind(self, hasher)
+    }
+}
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 0b0a19517ec..72beddf7bb5 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -102,7 +102,17 @@ pub mod print {
 
 pub mod early_buffered_lints;
 
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+
 /// Requirements for a `StableHashingContext` to be used in this crate.
 /// This is a hack to allow using the `HashStable_Generic` derive macro
 /// instead of implementing everything in librustc.
-pub trait HashStableContext: rustc_span::HashStableContext {}
+pub trait HashStableContext: rustc_span::HashStableContext {
+    fn hash_attr(&mut self, _: &ast::Attribute, hasher: &mut StableHasher);
+}
+
+impl<AstCtx: crate::HashStableContext> HashStable<AstCtx> for ast::Attribute {
+    fn hash_stable(&self, hcx: &mut AstCtx, hasher: &mut StableHasher) {
+        hcx.hash_attr(self, hasher)
+    }
+}