diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs
index f2f7f95426ab8..eeb41682601f5 100644
--- a/src/librustc/hir/map/blocks.rs
+++ b/src/librustc/hir/map/blocks.rs
@@ -22,8 +22,8 @@
 //! for the `Code` associated with a particular NodeId.
 
 use hir as ast;
-use hir::map::{self, Node};
-use hir::{Expr, FnDecl};
+use hir::map;
+use hir::{Expr, FnDecl, Node};
 use hir::intravisit::FnKind;
 use syntax::ast::{Attribute, Ident, Name, NodeId};
 use syntax_pos::Span;
@@ -39,7 +39,7 @@ use syntax_pos::Span;
 ///
 /// To construct one, use the `Code::from_node` function.
 #[derive(Copy, Clone, Debug)]
-pub struct FnLikeNode<'a> { node: map::Node<'a> }
+pub struct FnLikeNode<'a> { node: Node<'a> }
 
 /// MaybeFnLike wraps a method that indicates if an object
 /// corresponds to some FnLikeNode.
@@ -95,11 +95,11 @@ impl<'a> Code<'a> {
     /// Attempts to construct a Code from presumed FnLike or Expr node input.
     pub fn from_node(map: &map::Map<'a>, id: NodeId) -> Option<Code<'a>> {
         match map.get(id) {
-            map::NodeBlock(_) => {
+            map::Node::Block(_) => {
                 //  Use the parent, hopefully an expression node.
                 Code::from_node(map, map.get_parent_node(id))
             }
-            map::NodeExpr(expr) => Some(Code::Expr(expr)),
+            map::Node::Expr(expr) => Some(Code::Expr(expr)),
             node => FnLikeNode::from_node(node).map(Code::FnLike)
         }
     }
@@ -145,10 +145,10 @@ impl<'a> FnLikeNode<'a> {
     /// Attempts to construct a FnLikeNode from presumed FnLike node input.
     pub fn from_node(node: Node) -> Option<FnLikeNode> {
         let fn_like = match node {
-            map::NodeItem(item) => item.is_fn_like(),
-            map::NodeTraitItem(tm) => tm.is_fn_like(),
-            map::NodeImplItem(it) => it.is_fn_like(),
-            map::NodeExpr(e) => e.is_fn_like(),
+            map::Node::Item(item) => item.is_fn_like(),
+            map::Node::TraitItem(tm) => tm.is_fn_like(),
+            map::Node::ImplItem(it) => it.is_fn_like(),
+            map::Node::Expr(e) => e.is_fn_like(),
             _ => false
         };
         if fn_like {
@@ -234,7 +234,7 @@ impl<'a> FnLikeNode<'a> {
         C: FnOnce(ClosureParts<'a>) -> A,
     {
         match self.node {
-            map::NodeItem(i) => match i.node {
+            map::Node::Item(i) => match i.node {
                 ast::ItemKind::Fn(ref decl, header, ref generics, block) =>
                     item_fn(ItemFnParts {
                         id: i.id,
@@ -249,13 +249,13 @@ impl<'a> FnLikeNode<'a> {
                     }),
                 _ => bug!("item FnLikeNode that is not fn-like"),
             },
-            map::NodeTraitItem(ti) => match ti.node {
+            map::Node::TraitItem(ti) => match ti.node {
                 ast::TraitItemKind::Method(ref sig, ast::TraitMethod::Provided(body)) => {
                     method(ti.id, ti.ident, sig, None, body, ti.span, &ti.attrs)
                 }
                 _ => bug!("trait method FnLikeNode that is not fn-like"),
             },
-            map::NodeImplItem(ii) => {
+            map::Node::ImplItem(ii) => {
                 match ii.node {
                     ast::ImplItemKind::Method(ref sig, body) => {
                         method(ii.id, ii.ident, sig, Some(&ii.vis), body, ii.span, &ii.attrs)
@@ -265,7 +265,7 @@ impl<'a> FnLikeNode<'a> {
                     }
                 }
             },
-            map::NodeExpr(e) => match e.node {
+            map::Node::Expr(e) => match e.node {
                 ast::ExprKind::Closure(_, ref decl, block, _fn_decl_span, _gen) =>
                     closure(ClosureParts::new(&decl, block, e.id, e.span, &e.attrs)),
                 _ => bug!("expr FnLikeNode that is not fn-like"),
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index a14745a138127..30441c331e4cf 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -29,7 +29,7 @@ pub(super) struct NodeCollector<'a, 'hir> {
     /// The crate
     krate: &'hir Crate,
     /// The node map
-    map: Vec<MapEntry<'hir>>,
+    map: Vec<Option<Entry<'hir>>>,
     /// The parent of this node
     parent_node: NodeId,
 
@@ -114,7 +114,11 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
             hcx,
             hir_body_nodes,
         };
-        collector.insert_entry(CRATE_NODE_ID, RootCrate(root_mod_sig_dep_index));
+        collector.insert_entry(CRATE_NODE_ID, Entry {
+            parent: CRATE_NODE_ID,
+            dep_node: root_mod_sig_dep_index,
+            node: Node::Crate,
+        });
 
         collector
     }
@@ -124,9 +128,8 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
                                                   cstore: &dyn CrateStore,
                                                   source_map: &SourceMap,
                                                   commandline_args_hash: u64)
-                                                  -> (Vec<MapEntry<'hir>>, Svh) {
-        self
-            .hir_body_nodes
+                                                  -> (Vec<Option<Entry<'hir>>>, Svh) {
+        self.hir_body_nodes
             .sort_unstable_by(|&(ref d1, _), &(ref d2, _)| d1.cmp(d2));
 
         let node_hashes = self
@@ -178,44 +181,24 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
         (self.map, svh)
     }
 
-    fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'hir>) {
+    fn insert_entry(&mut self, id: NodeId, entry: Entry<'hir>) {
         debug!("hir_map: {:?} => {:?}", id, entry);
         let len = self.map.len();
         if id.as_usize() >= len {
-            self.map.extend(repeat(NotPresent).take(id.as_usize() - len + 1));
+            self.map.extend(repeat(None).take(id.as_usize() - len + 1));
         }
-        self.map[id.as_usize()] = entry;
+        self.map[id.as_usize()] = Some(entry);
     }
 
     fn insert(&mut self, id: NodeId, node: Node<'hir>) {
-        let parent = self.parent_node;
-        let dep_node_index = if self.currently_in_body {
-            self.current_full_dep_index
-        } else {
-            self.current_signature_dep_index
-        };
-
-        let entry = match node {
-            NodeItem(n) => EntryItem(parent, dep_node_index, n),
-            NodeForeignItem(n) => EntryForeignItem(parent, dep_node_index, n),
-            NodeTraitItem(n) => EntryTraitItem(parent, dep_node_index, n),
-            NodeImplItem(n) => EntryImplItem(parent, dep_node_index, n),
-            NodeVariant(n) => EntryVariant(parent, dep_node_index, n),
-            NodeField(n) => EntryField(parent, dep_node_index, n),
-            NodeAnonConst(n) => EntryAnonConst(parent, dep_node_index, n),
-            NodeExpr(n) => EntryExpr(parent, dep_node_index, n),
-            NodeStmt(n) => EntryStmt(parent, dep_node_index, n),
-            NodeTy(n) => EntryTy(parent, dep_node_index, n),
-            NodeTraitRef(n) => EntryTraitRef(parent, dep_node_index, n),
-            NodeBinding(n) => EntryBinding(parent, dep_node_index, n),
-            NodePat(n) => EntryPat(parent, dep_node_index, n),
-            NodeBlock(n) => EntryBlock(parent, dep_node_index, n),
-            NodeStructCtor(n) => EntryStructCtor(parent, dep_node_index, n),
-            NodeLifetime(n) => EntryLifetime(parent, dep_node_index, n),
-            NodeGenericParam(n) => EntryGenericParam(parent, dep_node_index, n),
-            NodeVisibility(n) => EntryVisibility(parent, dep_node_index, n),
-            NodeLocal(n) => EntryLocal(parent, dep_node_index, n),
-            NodeMacroDef(n) => EntryMacroDef(dep_node_index, n),
+        let entry = Entry {
+            parent: self.parent_node,
+            dep_node: if self.currently_in_body {
+                self.current_full_dep_index
+            } else {
+                self.current_signature_dep_index
+            },
+            node,
         };
 
         // Make sure that the DepNode of some node coincides with the HirId
@@ -326,13 +309,13 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         debug_assert_eq!(i.hir_id.owner,
                          self.definitions.opt_def_index(i.id).unwrap());
         self.with_dep_node_owner(i.hir_id.owner, i, |this| {
-            this.insert(i.id, NodeItem(i));
+            this.insert(i.id, Node::Item(i));
             this.with_parent(i.id, |this| {
                 match i.node {
                     ItemKind::Struct(ref struct_def, _) => {
                         // If this is a tuple-like struct, register the constructor.
                         if !struct_def.is_struct() {
-                            this.insert(struct_def.id(), NodeStructCtor(struct_def));
+                            this.insert(struct_def.id(), Node::StructCtor(struct_def));
                         }
                     }
                     _ => {}
@@ -343,7 +326,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     }
 
     fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem) {
-        self.insert(foreign_item.id, NodeForeignItem(foreign_item));
+        self.insert(foreign_item.id, Node::ForeignItem(foreign_item));
 
         self.with_parent(foreign_item.id, |this| {
             intravisit::walk_foreign_item(this, foreign_item);
@@ -351,7 +334,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     }
 
     fn visit_generic_param(&mut self, param: &'hir GenericParam) {
-        self.insert(param.id, NodeGenericParam(param));
+        self.insert(param.id, Node::GenericParam(param));
         intravisit::walk_generic_param(self, param);
     }
 
@@ -359,7 +342,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         debug_assert_eq!(ti.hir_id.owner,
                          self.definitions.opt_def_index(ti.id).unwrap());
         self.with_dep_node_owner(ti.hir_id.owner, ti, |this| {
-            this.insert(ti.id, NodeTraitItem(ti));
+            this.insert(ti.id, Node::TraitItem(ti));
 
             this.with_parent(ti.id, |this| {
                 intravisit::walk_trait_item(this, ti);
@@ -371,7 +354,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         debug_assert_eq!(ii.hir_id.owner,
                          self.definitions.opt_def_index(ii.id).unwrap());
         self.with_dep_node_owner(ii.hir_id.owner, ii, |this| {
-            this.insert(ii.id, NodeImplItem(ii));
+            this.insert(ii.id, Node::ImplItem(ii));
 
             this.with_parent(ii.id, |this| {
                 intravisit::walk_impl_item(this, ii);
@@ -381,9 +364,9 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
 
     fn visit_pat(&mut self, pat: &'hir Pat) {
         let node = if let PatKind::Binding(..) = pat.node {
-            NodeBinding(pat)
+            Node::Binding(pat)
         } else {
-            NodePat(pat)
+            Node::Pat(pat)
         };
         self.insert(pat.id, node);
 
@@ -393,7 +376,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     }
 
     fn visit_anon_const(&mut self, constant: &'hir AnonConst) {
-        self.insert(constant.id, NodeAnonConst(constant));
+        self.insert(constant.id, Node::AnonConst(constant));
 
         self.with_parent(constant.id, |this| {
             intravisit::walk_anon_const(this, constant);
@@ -401,7 +384,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     }
 
     fn visit_expr(&mut self, expr: &'hir Expr) {
-        self.insert(expr.id, NodeExpr(expr));
+        self.insert(expr.id, Node::Expr(expr));
 
         self.with_parent(expr.id, |this| {
             intravisit::walk_expr(this, expr);
@@ -410,7 +393,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
 
     fn visit_stmt(&mut self, stmt: &'hir Stmt) {
         let id = stmt.node.id();
-        self.insert(id, NodeStmt(stmt));
+        self.insert(id, Node::Stmt(stmt));
 
         self.with_parent(id, |this| {
             intravisit::walk_stmt(this, stmt);
@@ -418,7 +401,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     }
 
     fn visit_ty(&mut self, ty: &'hir Ty) {
-        self.insert(ty.id, NodeTy(ty));
+        self.insert(ty.id, Node::Ty(ty));
 
         self.with_parent(ty.id, |this| {
             intravisit::walk_ty(this, ty);
@@ -426,7 +409,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     }
 
     fn visit_trait_ref(&mut self, tr: &'hir TraitRef) {
-        self.insert(tr.ref_id, NodeTraitRef(tr));
+        self.insert(tr.ref_id, Node::TraitRef(tr));
 
         self.with_parent(tr.ref_id, |this| {
             intravisit::walk_trait_ref(this, tr);
@@ -440,21 +423,21 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     }
 
     fn visit_block(&mut self, block: &'hir Block) {
-        self.insert(block.id, NodeBlock(block));
+        self.insert(block.id, Node::Block(block));
         self.with_parent(block.id, |this| {
             intravisit::walk_block(this, block);
         });
     }
 
     fn visit_local(&mut self, l: &'hir Local) {
-        self.insert(l.id, NodeLocal(l));
+        self.insert(l.id, Node::Local(l));
         self.with_parent(l.id, |this| {
             intravisit::walk_local(this, l)
         })
     }
 
     fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) {
-        self.insert(lifetime.id, NodeLifetime(lifetime));
+        self.insert(lifetime.id, Node::Lifetime(lifetime));
     }
 
     fn visit_vis(&mut self, visibility: &'hir Visibility) {
@@ -463,7 +446,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
             VisibilityKind::Crate(_) |
             VisibilityKind::Inherited => {}
             VisibilityKind::Restricted { id, .. } => {
-                self.insert(id, NodeVisibility(visibility));
+                self.insert(id, Node::Visibility(visibility));
                 self.with_parent(id, |this| {
                     intravisit::walk_vis(this, visibility);
                 });
@@ -475,20 +458,20 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         let def_index = self.definitions.opt_def_index(macro_def.id).unwrap();
 
         self.with_dep_node_owner(def_index, macro_def, |this| {
-            this.insert(macro_def.id, NodeMacroDef(macro_def));
+            this.insert(macro_def.id, Node::MacroDef(macro_def));
         });
     }
 
     fn visit_variant(&mut self, v: &'hir Variant, g: &'hir Generics, item_id: NodeId) {
         let id = v.node.data.id();
-        self.insert(id, NodeVariant(v));
+        self.insert(id, Node::Variant(v));
         self.with_parent(id, |this| {
             intravisit::walk_variant(this, v, g, item_id);
         });
     }
 
     fn visit_struct_field(&mut self, field: &'hir StructField) {
-        self.insert(field.id, NodeField(field));
+        self.insert(field.id, Node::Field(field));
         self.with_parent(field.id, |this| {
             intravisit::walk_struct_field(this, field);
         });
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index c3112da4f8c3a..6fffde7cab50c 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub use self::Node::*;
-use self::MapEntry::*;
 use self::collector::NodeCollector;
 pub use self::def_collector::{DefCollector, MacroInvocationData};
 pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData,
@@ -42,172 +40,62 @@ mod def_collector;
 pub mod definitions;
 mod hir_id_validator;
 
-
 pub const ITEM_LIKE_SPACE: DefIndexAddressSpace = DefIndexAddressSpace::Low;
 pub const REGULAR_SPACE: DefIndexAddressSpace = DefIndexAddressSpace::High;
 
+/// Represents an entry and its parent NodeId.
 #[derive(Copy, Clone, Debug)]
-pub enum Node<'hir> {
-    NodeItem(&'hir Item),
-    NodeForeignItem(&'hir ForeignItem),
-    NodeTraitItem(&'hir TraitItem),
-    NodeImplItem(&'hir ImplItem),
-    NodeVariant(&'hir Variant),
-    NodeField(&'hir StructField),
-    NodeAnonConst(&'hir AnonConst),
-    NodeExpr(&'hir Expr),
-    NodeStmt(&'hir Stmt),
-    NodeTy(&'hir Ty),
-    NodeTraitRef(&'hir TraitRef),
-    NodeBinding(&'hir Pat),
-    NodePat(&'hir Pat),
-    NodeBlock(&'hir Block),
-    NodeLocal(&'hir Local),
-    NodeMacroDef(&'hir MacroDef),
-
-    /// NodeStructCtor represents a tuple struct.
-    NodeStructCtor(&'hir VariantData),
-
-    NodeLifetime(&'hir Lifetime),
-    NodeGenericParam(&'hir GenericParam),
-    NodeVisibility(&'hir Visibility),
-}
-
-/// Represents an entry and its parent NodeID.
-/// The odd layout is to bring down the total size.
-#[derive(Copy, Debug)]
-enum MapEntry<'hir> {
-    /// Placeholder for holes in the map.
-    NotPresent,
-
-    /// All the node types, with a parent ID.
-    EntryItem(NodeId, DepNodeIndex, &'hir Item),
-    EntryForeignItem(NodeId, DepNodeIndex, &'hir ForeignItem),
-    EntryTraitItem(NodeId, DepNodeIndex, &'hir TraitItem),
-    EntryImplItem(NodeId, DepNodeIndex, &'hir ImplItem),
-    EntryVariant(NodeId, DepNodeIndex, &'hir Variant),
-    EntryField(NodeId, DepNodeIndex, &'hir StructField),
-    EntryAnonConst(NodeId, DepNodeIndex, &'hir AnonConst),
-    EntryExpr(NodeId, DepNodeIndex, &'hir Expr),
-    EntryStmt(NodeId, DepNodeIndex, &'hir Stmt),
-    EntryTy(NodeId, DepNodeIndex, &'hir Ty),
-    EntryTraitRef(NodeId, DepNodeIndex, &'hir TraitRef),
-    EntryBinding(NodeId, DepNodeIndex, &'hir Pat),
-    EntryPat(NodeId, DepNodeIndex, &'hir Pat),
-    EntryBlock(NodeId, DepNodeIndex, &'hir Block),
-    EntryStructCtor(NodeId, DepNodeIndex, &'hir VariantData),
-    EntryLifetime(NodeId, DepNodeIndex, &'hir Lifetime),
-    EntryGenericParam(NodeId, DepNodeIndex, &'hir GenericParam),
-    EntryVisibility(NodeId, DepNodeIndex, &'hir Visibility),
-    EntryLocal(NodeId, DepNodeIndex, &'hir Local),
-
-    EntryMacroDef(DepNodeIndex, &'hir MacroDef),
-
-    /// Roots for node trees. The DepNodeIndex is the dependency node of the
-    /// crate's root module.
-    RootCrate(DepNodeIndex),
-}
-
-impl<'hir> Clone for MapEntry<'hir> {
-    fn clone(&self) -> MapEntry<'hir> {
-        *self
-    }
+pub struct Entry<'hir> {
+    parent: NodeId,
+    dep_node: DepNodeIndex,
+    node: Node<'hir>,
 }
 
-impl<'hir> MapEntry<'hir> {
+impl<'hir> Entry<'hir> {
     fn parent_node(self) -> Option<NodeId> {
-        Some(match self {
-            EntryItem(id, _, _) => id,
-            EntryForeignItem(id, _, _) => id,
-            EntryTraitItem(id, _, _) => id,
-            EntryImplItem(id, _, _) => id,
-            EntryVariant(id, _, _) => id,
-            EntryField(id, _, _) => id,
-            EntryAnonConst(id, _, _) => id,
-            EntryExpr(id, _, _) => id,
-            EntryStmt(id, _, _) => id,
-            EntryTy(id, _, _) => id,
-            EntryTraitRef(id, _, _) => id,
-            EntryBinding(id, _, _) => id,
-            EntryPat(id, _, _) => id,
-            EntryBlock(id, _, _) => id,
-            EntryStructCtor(id, _, _) => id,
-            EntryLifetime(id, _, _) => id,
-            EntryGenericParam(id, _, _) => id,
-            EntryVisibility(id, _, _) => id,
-            EntryLocal(id, _, _) => id,
-
-            NotPresent |
-            EntryMacroDef(..) |
-            RootCrate(_) => return None,
-        })
-    }
-
-    fn to_node(self) -> Option<Node<'hir>> {
-        Some(match self {
-            EntryItem(_, _, n) => NodeItem(n),
-            EntryForeignItem(_, _, n) => NodeForeignItem(n),
-            EntryTraitItem(_, _, n) => NodeTraitItem(n),
-            EntryImplItem(_, _, n) => NodeImplItem(n),
-            EntryVariant(_, _, n) => NodeVariant(n),
-            EntryField(_, _, n) => NodeField(n),
-            EntryAnonConst(_, _, n) => NodeAnonConst(n),
-            EntryExpr(_, _, n) => NodeExpr(n),
-            EntryStmt(_, _, n) => NodeStmt(n),
-            EntryTy(_, _, n) => NodeTy(n),
-            EntryTraitRef(_, _, n) => NodeTraitRef(n),
-            EntryBinding(_, _, n) => NodeBinding(n),
-            EntryPat(_, _, n) => NodePat(n),
-            EntryBlock(_, _, n) => NodeBlock(n),
-            EntryStructCtor(_, _, n) => NodeStructCtor(n),
-            EntryLifetime(_, _, n) => NodeLifetime(n),
-            EntryGenericParam(_, _, n) => NodeGenericParam(n),
-            EntryVisibility(_, _, n) => NodeVisibility(n),
-            EntryLocal(_, _, n) => NodeLocal(n),
-            EntryMacroDef(_, n) => NodeMacroDef(n),
-
-            NotPresent |
-            RootCrate(_) => return None
-        })
+        match self.node {
+            Node::Crate | Node::MacroDef(_) => None,
+            _ => Some(self.parent),
+        }
     }
 
     fn fn_decl(&self) -> Option<&FnDecl> {
-        match self {
-            EntryItem(_, _, ref item) => {
+        match self.node {
+            Node::Item(ref item) => {
                 match item.node {
                     ItemKind::Fn(ref fn_decl, _, _, _) => Some(&fn_decl),
                     _ => None,
                 }
             }
 
-            EntryTraitItem(_, _, ref item) => {
+            Node::TraitItem(ref item) => {
                 match item.node {
                     TraitItemKind::Method(ref method_sig, _) => Some(&method_sig.decl),
                     _ => None
                 }
             }
 
-            EntryImplItem(_, _, ref item) => {
+            Node::ImplItem(ref item) => {
                 match item.node {
                     ImplItemKind::Method(ref method_sig, _) => Some(&method_sig.decl),
                     _ => None,
                 }
             }
 
-            EntryExpr(_, _, ref expr) => {
+            Node::Expr(ref expr) => {
                 match expr.node {
                     ExprKind::Closure(_, ref fn_decl, ..) => Some(&fn_decl),
                     _ => None,
                 }
             }
 
-            _ => None
+            _ => None,
         }
     }
 
     fn associated_body(self) -> Option<BodyId> {
-        match self {
-            EntryItem(_, _, item) => {
+        match self.node {
+            Node::Item(item) => {
                 match item.node {
                     ItemKind::Const(_, body) |
                     ItemKind::Static(.., body) |
@@ -216,7 +104,7 @@ impl<'hir> MapEntry<'hir> {
                 }
             }
 
-            EntryTraitItem(_, _, item) => {
+            Node::TraitItem(item) => {
                 match item.node {
                     TraitItemKind::Const(_, Some(body)) |
                     TraitItemKind::Method(_, TraitMethod::Provided(body)) => Some(body),
@@ -224,7 +112,7 @@ impl<'hir> MapEntry<'hir> {
                 }
             }
 
-            EntryImplItem(_, _, item) => {
+            Node::ImplItem(item) => {
                 match item.node {
                     ImplItemKind::Const(_, body) |
                     ImplItemKind::Method(_, body) => Some(body),
@@ -232,9 +120,9 @@ impl<'hir> MapEntry<'hir> {
                 }
             }
 
-            EntryAnonConst(_, _, constant) => Some(constant.body),
+            Node::AnonConst(constant) => Some(constant.body),
 
-            EntryExpr(_, _, expr) => {
+            Node::Expr(expr) => {
                 match expr.node {
                     ExprKind::Closure(.., body, _, _) => Some(body),
                     _ => None,
@@ -287,16 +175,16 @@ pub struct Map<'hir> {
     /// The SVH of the local crate.
     pub crate_hash: Svh,
 
-    /// NodeIds are sequential integers from 0, so we can be
+    /// `NodeId`s are sequential integers from 0, so we can be
     /// super-compact by storing them in a vector. Not everything with
-    /// a NodeId is in the map, but empirically the occupancy is about
+    /// a `NodeId` is in the map, but empirically the occupancy is about
     /// 75-80%, so there's not too much overhead (certainly less than
     /// a hashmap, since they (at the time of writing) have a maximum
     /// of 75% occupancy).
     ///
     /// Also, indexing is pretty quick when you've got a vector and
     /// plain old integers.
-    map: Vec<MapEntry<'hir>>,
+    map: Vec<Option<Entry<'hir>>>,
 
     definitions: &'hir Definitions,
 
@@ -313,34 +201,10 @@ impl<'hir> Map<'hir> {
     /// read recorded). If the function just returns a DefId or
     /// NodeId, no actual content was returned, so no read is needed.
     pub fn read(&self, id: NodeId) {
-        let entry = self.map[id.as_usize()];
-        match entry {
-            EntryItem(_, dep_node_index, _) |
-            EntryTraitItem(_, dep_node_index, _) |
-            EntryImplItem(_, dep_node_index, _) |
-            EntryVariant(_, dep_node_index, _) |
-            EntryForeignItem(_, dep_node_index, _) |
-            EntryField(_, dep_node_index, _) |
-            EntryStmt(_, dep_node_index, _) |
-            EntryTy(_, dep_node_index, _) |
-            EntryTraitRef(_, dep_node_index, _) |
-            EntryBinding(_, dep_node_index, _) |
-            EntryPat(_, dep_node_index, _) |
-            EntryBlock(_, dep_node_index, _) |
-            EntryStructCtor(_, dep_node_index, _) |
-            EntryLifetime(_, dep_node_index, _) |
-            EntryGenericParam(_, dep_node_index, _) |
-            EntryVisibility(_, dep_node_index, _) |
-            EntryAnonConst(_, dep_node_index, _) |
-            EntryExpr(_, dep_node_index, _) |
-            EntryLocal(_, dep_node_index, _) |
-            EntryMacroDef(dep_node_index, _) |
-            RootCrate(dep_node_index) => {
-                self.dep_graph.read_index(dep_node_index);
-            }
-            NotPresent => {
-                bug!("called HirMap::read() with invalid NodeId")
-            }
+        if let Some(entry) = self.map[id.as_usize()] {
+            self.dep_graph.read_index(entry.dep_node);
+        } else {
+            bug!("called `HirMap::read()` with invalid `NodeId`")
         }
     }
 
@@ -421,7 +285,7 @@ impl<'hir> Map<'hir> {
         };
 
         match node {
-            NodeItem(item) => {
+            Node::Item(item) => {
                 let def_id = || {
                     self.local_def_id(item.id)
                 };
@@ -448,7 +312,7 @@ impl<'hir> Map<'hir> {
                     ItemKind::Impl(..) => None,
                 }
             }
-            NodeForeignItem(item) => {
+            Node::ForeignItem(item) => {
                 let def_id = self.local_def_id(item.id);
                 match item.node {
                     ForeignItemKind::Fn(..) => Some(Def::Fn(def_id)),
@@ -456,7 +320,7 @@ impl<'hir> Map<'hir> {
                     ForeignItemKind::Type => Some(Def::ForeignTy(def_id)),
                 }
             }
-            NodeTraitItem(item) => {
+            Node::TraitItem(item) => {
                 let def_id = self.local_def_id(item.id);
                 match item.node {
                     TraitItemKind::Const(..) => Some(Def::AssociatedConst(def_id)),
@@ -464,7 +328,7 @@ impl<'hir> Map<'hir> {
                     TraitItemKind::Type(..) => Some(Def::AssociatedTy(def_id)),
                 }
             }
-            NodeImplItem(item) => {
+            Node::ImplItem(item) => {
                 let def_id = self.local_def_id(item.id);
                 match item.node {
                     ImplItemKind::Const(..) => Some(Def::AssociatedConst(def_id)),
@@ -473,30 +337,31 @@ impl<'hir> Map<'hir> {
                     ImplItemKind::Existential(..) => Some(Def::AssociatedExistential(def_id)),
                 }
             }
-            NodeVariant(variant) => {
+            Node::Variant(variant) => {
                 let def_id = self.local_def_id(variant.node.data.id());
                 Some(Def::Variant(def_id))
             }
-            NodeField(_) |
-            NodeAnonConst(_) |
-            NodeExpr(_) |
-            NodeStmt(_) |
-            NodeTy(_) |
-            NodeTraitRef(_) |
-            NodePat(_) |
-            NodeBinding(_) |
-            NodeStructCtor(_) |
-            NodeLifetime(_) |
-            NodeVisibility(_) |
-            NodeBlock(_) => None,
-            NodeLocal(local) => {
+            Node::Field(_) |
+            Node::AnonConst(_) |
+            Node::Expr(_) |
+            Node::Stmt(_) |
+            Node::Ty(_) |
+            Node::TraitRef(_) |
+            Node::Pat(_) |
+            Node::Binding(_) |
+            Node::StructCtor(_) |
+            Node::Lifetime(_) |
+            Node::Visibility(_) |
+            Node::Block(_) |
+            Node::Crate => None,
+            Node::Local(local) => {
                 Some(Def::Local(local.id))
             }
-            NodeMacroDef(macro_def) => {
+            Node::MacroDef(macro_def) => {
                 Some(Def::Macro(self.local_def_id(macro_def.id),
                                 MacroKind::Bang))
             }
-            NodeGenericParam(param) => {
+            Node::GenericParam(param) => {
                 Some(match param.kind {
                     GenericParamKind::Lifetime { .. } => Def::Local(param.id),
                     GenericParamKind::Type { .. } => Def::TyParam(self.local_def_id(param.id)),
@@ -509,8 +374,8 @@ impl<'hir> Map<'hir> {
         self.map.len()
     }
 
-    fn find_entry(&self, id: NodeId) -> Option<MapEntry<'hir>> {
-        self.map.get(id.as_usize()).cloned()
+    fn find_entry(&self, id: NodeId) -> Option<Entry<'hir>> {
+        self.map.get(id.as_usize()).cloned().unwrap_or(None)
     }
 
     pub fn krate(&self) -> &'hir Crate {
@@ -554,7 +419,7 @@ impl<'hir> Map<'hir> {
     /// item (possibly associated), a closure, or a `hir::AnonConst`.
     pub fn body_owner(&self, BodyId { node_id }: BodyId) -> NodeId {
         let parent = self.get_parent_node(node_id);
-        assert!(self.map[parent.as_usize()].is_body_owner(node_id));
+        assert!(self.map[parent.as_usize()].map_or(false, |e| e.is_body_owner(node_id)));
         parent
     }
 
@@ -588,13 +453,13 @@ impl<'hir> Map<'hir> {
 
     pub fn body_owner_kind(&self, id: NodeId) -> BodyOwnerKind {
         match self.get(id) {
-            NodeItem(&Item { node: ItemKind::Const(..), .. }) |
-            NodeTraitItem(&TraitItem { node: TraitItemKind::Const(..), .. }) |
-            NodeImplItem(&ImplItem { node: ImplItemKind::Const(..), .. }) |
-            NodeAnonConst(_) => {
+            Node::Item(&Item { node: ItemKind::Const(..), .. }) |
+            Node::TraitItem(&TraitItem { node: TraitItemKind::Const(..), .. }) |
+            Node::ImplItem(&ImplItem { node: ImplItemKind::Const(..), .. }) |
+            Node::AnonConst(_) => {
                 BodyOwnerKind::Const
             }
-            NodeItem(&Item { node: ItemKind::Static(_, m, _), .. }) => {
+            Node::Item(&Item { node: ItemKind::Static(_, m, _), .. }) => {
                 BodyOwnerKind::Static(m)
             }
             // Default to function if it's not a constant or static.
@@ -604,8 +469,8 @@ impl<'hir> Map<'hir> {
 
     pub fn ty_param_owner(&self, id: NodeId) -> NodeId {
         match self.get(id) {
-            NodeItem(&Item { node: ItemKind::Trait(..), .. }) => id,
-            NodeGenericParam(_) => self.get_parent_node(id),
+            Node::Item(&Item { node: ItemKind::Trait(..), .. }) => id,
+            Node::GenericParam(_) => self.get_parent_node(id),
             _ => {
                 bug!("ty_param_owner: {} not a type parameter",
                     self.node_to_string(id))
@@ -615,10 +480,10 @@ impl<'hir> Map<'hir> {
 
     pub fn ty_param_name(&self, id: NodeId) -> Name {
         match self.get(id) {
-            NodeItem(&Item { node: ItemKind::Trait(..), .. }) => {
+            Node::Item(&Item { node: ItemKind::Trait(..), .. }) => {
                 keywords::SelfType.name()
             }
-            NodeGenericParam(param) => param.name.ident().name,
+            Node::GenericParam(param) => param.name.ident().name,
             _ => bug!("ty_param_name: {} not a type parameter", self.node_to_string(id)),
         }
     }
@@ -669,9 +534,9 @@ impl<'hir> Map<'hir> {
     pub fn get_generics(&self, id: DefId) -> Option<&'hir Generics> {
         self.get_if_local(id).and_then(|node| {
             match node {
-                NodeImplItem(ref impl_item) => Some(&impl_item.generics),
-                NodeTraitItem(ref trait_item) => Some(&trait_item.generics),
-                NodeItem(ref item) => {
+                Node::ImplItem(ref impl_item) => Some(&impl_item.generics),
+                Node::TraitItem(ref trait_item) => Some(&trait_item.generics),
+                Node::Item(ref item) => {
                     match item.node {
                         ItemKind::Fn(_, _, ref generics, _) |
                         ItemKind::Ty(_, ref generics) |
@@ -696,7 +561,13 @@ impl<'hir> Map<'hir> {
     /// Retrieve the Node corresponding to `id`, returning None if
     /// cannot be found.
     pub fn find(&self, id: NodeId) -> Option<Node<'hir>> {
-        let result = self.find_entry(id).and_then(|x| x.to_node());
+        let result = self.find_entry(id).and_then(|entry| {
+            if let Node::Crate = entry.node {
+                None
+            } else {
+                Some(entry.node)
+            }
+        });
         if result.is_some() {
             self.read(id);
         }
@@ -727,14 +598,14 @@ impl<'hir> Map<'hir> {
     /// immediate parent is an item or a closure.
     pub fn is_argument(&self, id: NodeId) -> bool {
         match self.find(id) {
-            Some(NodeBinding(_)) => (),
+            Some(Node::Binding(_)) => (),
             _ => return false,
         }
         match self.find(self.get_parent_node(id)) {
-            Some(NodeItem(_)) |
-            Some(NodeTraitItem(_)) |
-            Some(NodeImplItem(_)) => true,
-            Some(NodeExpr(e)) => {
+            Some(Node::Item(_)) |
+            Some(Node::TraitItem(_)) |
+            Some(Node::ImplItem(_)) => true,
+            Some(Node::Expr(e)) => {
                 match e.node {
                     ExprKind::Closure(..) => true,
                     _ => false,
@@ -766,24 +637,19 @@ impl<'hir> Map<'hir> {
                 return Err(id);
             }
 
-            let node = self.find_entry(parent_node);
-            if node.is_none() {
-                return Err(id);
-            }
-            let node = node.unwrap().to_node();
-            match node {
-                Some(ref node) => {
-                    if found(node) {
-                        return Ok(parent_node);
-                    } else if bail_early(node) {
-                        return Err(parent_node);
-                    }
+            if let Some(entry) = self.find_entry(parent_node) {
+                if let Node::Crate = entry.node {
+                    return Err(id);
                 }
-                None => {
+                if found(&entry.node) {
+                    return Ok(parent_node);
+                } else if bail_early(&entry.node) {
                     return Err(parent_node);
                 }
+                id = parent_node;
+            } else {
+                return Err(id);
             }
-            id = parent_node;
         }
     }
 
@@ -812,16 +678,16 @@ impl<'hir> Map<'hir> {
     pub fn get_return_block(&self, id: NodeId) -> Option<NodeId> {
         let match_fn = |node: &Node| {
             match *node {
-                NodeItem(_) |
-                NodeForeignItem(_) |
-                NodeTraitItem(_) |
-                NodeImplItem(_) => true,
+                Node::Item(_) |
+                Node::ForeignItem(_) |
+                Node::TraitItem(_) |
+                Node::ImplItem(_) => true,
                 _ => false,
             }
         };
         let match_non_returning_block = |node: &Node| {
             match *node {
-                NodeExpr(ref expr) => {
+                Node::Expr(ref expr) => {
                     match expr.node {
                         ExprKind::While(..) | ExprKind::Loop(..) => true,
                         _ => false,
@@ -843,10 +709,10 @@ impl<'hir> Map<'hir> {
     /// in a module, trait, or impl.
     pub fn get_parent(&self, id: NodeId) -> NodeId {
         match self.walk_parent_nodes(id, |node| match *node {
-            NodeItem(_) |
-            NodeForeignItem(_) |
-            NodeTraitItem(_) |
-            NodeImplItem(_) => true,
+            Node::Item(_) |
+            Node::ForeignItem(_) |
+            Node::TraitItem(_) |
+            Node::ImplItem(_) => true,
             _ => false,
         }, |_| false) {
             Ok(id) => id,
@@ -858,7 +724,7 @@ impl<'hir> Map<'hir> {
     /// module parent is in this map.
     pub fn get_module_parent(&self, id: NodeId) -> DefId {
         let id = match self.walk_parent_nodes(id, |node| match *node {
-            NodeItem(&Item { node: ItemKind::Mod(_), .. }) => true,
+            Node::Item(&Item { node: ItemKind::Mod(_), .. }) => true,
             _ => false,
         }, |_| false) {
             Ok(id) => id,
@@ -873,11 +739,11 @@ impl<'hir> Map<'hir> {
     /// regard should be expected to be highly unstable.
     pub fn get_enclosing_scope(&self, id: NodeId) -> Option<NodeId> {
         match self.walk_parent_nodes(id, |node| match *node {
-            NodeItem(_) |
-            NodeForeignItem(_) |
-            NodeTraitItem(_) |
-            NodeImplItem(_) |
-            NodeBlock(_) => true,
+            Node::Item(_) |
+            Node::ForeignItem(_) |
+            Node::TraitItem(_) |
+            Node::ImplItem(_) |
+            Node::Block(_) => true,
             _ => false,
         }, |_| false) {
             Ok(id) => Some(id),
@@ -891,49 +757,43 @@ impl<'hir> Map<'hir> {
 
     pub fn get_foreign_abi(&self, id: NodeId) -> Abi {
         let parent = self.get_parent(id);
-        let abi = match self.find_entry(parent) {
-            Some(EntryItem(_, _, i)) => {
-                match i.node {
-                    ItemKind::ForeignMod(ref nm) => Some(nm.abi),
-                    _ => None
+        if let Some(entry) = self.find_entry(parent) {
+            match entry {
+                Entry { node: Node::Item(Item { node: ItemKind::ForeignMod(ref nm), .. }), .. }
+                    => {
+                    self.read(id); // reveals some of the content of a node
+                    return nm.abi;
                 }
+                _ => {}
             }
-            _ => None
-        };
-        match abi {
-            Some(abi) => {
-                self.read(id); // reveals some of the content of a node
-                abi
-            }
-            None => bug!("expected foreign mod or inlined parent, found {}",
-                          self.node_to_string(parent))
         }
+        bug!("expected foreign mod or inlined parent, found {}", self.node_to_string(parent))
     }
 
     pub fn expect_item(&self, id: NodeId) -> &'hir Item {
         match self.find(id) { // read recorded by `find`
-            Some(NodeItem(item)) => item,
+            Some(Node::Item(item)) => item,
             _ => bug!("expected item, found {}", self.node_to_string(id))
         }
     }
 
     pub fn expect_impl_item(&self, id: NodeId) -> &'hir ImplItem {
         match self.find(id) {
-            Some(NodeImplItem(item)) => item,
+            Some(Node::ImplItem(item)) => item,
             _ => bug!("expected impl item, found {}", self.node_to_string(id))
         }
     }
 
     pub fn expect_trait_item(&self, id: NodeId) -> &'hir TraitItem {
         match self.find(id) {
-            Some(NodeTraitItem(item)) => item,
+            Some(Node::TraitItem(item)) => item,
             _ => bug!("expected trait item, found {}", self.node_to_string(id))
         }
     }
 
     pub fn expect_variant_data(&self, id: NodeId) -> &'hir VariantData {
         match self.find(id) {
-            Some(NodeItem(i)) => {
+            Some(Node::Item(i)) => {
                 match i.node {
                     ItemKind::Struct(ref struct_def, _) |
                     ItemKind::Union(ref struct_def, _) => struct_def,
@@ -943,8 +803,8 @@ impl<'hir> Map<'hir> {
                     }
                 }
             }
-            Some(NodeStructCtor(data)) => data,
-            Some(NodeVariant(variant)) => &variant.node.data,
+            Some(Node::StructCtor(data)) => data,
+            Some(Node::Variant(variant)) => &variant.node.data,
             _ => {
                 bug!("expected struct or variant, found {}",
                      self.node_to_string(id));
@@ -954,21 +814,21 @@ impl<'hir> Map<'hir> {
 
     pub fn expect_variant(&self, id: NodeId) -> &'hir Variant {
         match self.find(id) {
-            Some(NodeVariant(variant)) => variant,
+            Some(Node::Variant(variant)) => variant,
             _ => bug!("expected variant, found {}", self.node_to_string(id)),
         }
     }
 
     pub fn expect_foreign_item(&self, id: NodeId) -> &'hir ForeignItem {
         match self.find(id) {
-            Some(NodeForeignItem(item)) => item,
+            Some(Node::ForeignItem(item)) => item,
             _ => bug!("expected foreign item, found {}", self.node_to_string(id))
         }
     }
 
     pub fn expect_expr(&self, id: NodeId) -> &'hir Expr {
         match self.find(id) { // read recorded by find
-            Some(NodeExpr(expr)) => expr,
+            Some(Node::Expr(expr)) => expr,
             _ => bug!("expected expr, found {}", self.node_to_string(id))
         }
     }
@@ -976,16 +836,16 @@ impl<'hir> Map<'hir> {
     /// Returns the name associated with the given NodeId's AST.
     pub fn name(&self, id: NodeId) -> Name {
         match self.get(id) {
-            NodeItem(i) => i.name,
-            NodeForeignItem(i) => i.name,
-            NodeImplItem(ii) => ii.ident.name,
-            NodeTraitItem(ti) => ti.ident.name,
-            NodeVariant(v) => v.node.name,
-            NodeField(f) => f.ident.name,
-            NodeLifetime(lt) => lt.name.ident().name,
-            NodeGenericParam(param) => param.name.ident().name,
-            NodeBinding(&Pat { node: PatKind::Binding(_,_,l,_), .. }) => l.name,
-            NodeStructCtor(_) => self.name(self.get_parent(id)),
+            Node::Item(i) => i.name,
+            Node::ForeignItem(i) => i.name,
+            Node::ImplItem(ii) => ii.ident.name,
+            Node::TraitItem(ti) => ti.ident.name,
+            Node::Variant(v) => v.node.name,
+            Node::Field(f) => f.ident.name,
+            Node::Lifetime(lt) => lt.name.ident().name,
+            Node::GenericParam(param) => param.name.ident().name,
+            Node::Binding(&Pat { node: PatKind::Binding(_,_,l,_), .. }) => l.name,
+            Node::StructCtor(_) => self.name(self.get_parent(id)),
             _ => bug!("no name for {}", self.node_to_string(id))
         }
     }
@@ -995,18 +855,18 @@ impl<'hir> Map<'hir> {
     pub fn attrs(&self, id: NodeId) -> &'hir [ast::Attribute] {
         self.read(id); // reveals attributes on the node
         let attrs = match self.find(id) {
-            Some(NodeItem(i)) => Some(&i.attrs[..]),
-            Some(NodeForeignItem(fi)) => Some(&fi.attrs[..]),
-            Some(NodeTraitItem(ref ti)) => Some(&ti.attrs[..]),
-            Some(NodeImplItem(ref ii)) => Some(&ii.attrs[..]),
-            Some(NodeVariant(ref v)) => Some(&v.node.attrs[..]),
-            Some(NodeField(ref f)) => Some(&f.attrs[..]),
-            Some(NodeExpr(ref e)) => Some(&*e.attrs),
-            Some(NodeStmt(ref s)) => Some(s.node.attrs()),
-            Some(NodeGenericParam(param)) => Some(&param.attrs[..]),
+            Some(Node::Item(i)) => Some(&i.attrs[..]),
+            Some(Node::ForeignItem(fi)) => Some(&fi.attrs[..]),
+            Some(Node::TraitItem(ref ti)) => Some(&ti.attrs[..]),
+            Some(Node::ImplItem(ref ii)) => Some(&ii.attrs[..]),
+            Some(Node::Variant(ref v)) => Some(&v.node.attrs[..]),
+            Some(Node::Field(ref f)) => Some(&f.attrs[..]),
+            Some(Node::Expr(ref e)) => Some(&*e.attrs),
+            Some(Node::Stmt(ref s)) => Some(s.node.attrs()),
+            Some(Node::GenericParam(param)) => Some(&param.attrs[..]),
             // unit/tuple structs take the attributes straight from
             // the struct definition.
-            Some(NodeStructCtor(_)) => {
+            Some(Node::StructCtor(_)) => {
                 return self.attrs(self.get_parent(id));
             }
             _ => None
@@ -1033,35 +893,33 @@ impl<'hir> Map<'hir> {
 
     pub fn span(&self, id: NodeId) -> Span {
         self.read(id); // reveals span from node
-        match self.find_entry(id) {
-            Some(EntryItem(_, _, item)) => item.span,
-            Some(EntryForeignItem(_, _, foreign_item)) => foreign_item.span,
-            Some(EntryTraitItem(_, _, trait_method)) => trait_method.span,
-            Some(EntryImplItem(_, _, impl_item)) => impl_item.span,
-            Some(EntryVariant(_, _, variant)) => variant.span,
-            Some(EntryField(_, _, field)) => field.span,
-            Some(EntryAnonConst(_, _, constant)) => self.body(constant.body).value.span,
-            Some(EntryExpr(_, _, expr)) => expr.span,
-            Some(EntryStmt(_, _, stmt)) => stmt.span,
-            Some(EntryTy(_, _, ty)) => ty.span,
-            Some(EntryTraitRef(_, _, tr)) => tr.path.span,
-            Some(EntryBinding(_, _, pat)) => pat.span,
-            Some(EntryPat(_, _, pat)) => pat.span,
-            Some(EntryBlock(_, _, block)) => block.span,
-            Some(EntryStructCtor(_, _, _)) => self.expect_item(self.get_parent(id)).span,
-            Some(EntryLifetime(_, _, lifetime)) => lifetime.span,
-            Some(EntryGenericParam(_, _, param)) => param.span,
-            Some(EntryVisibility(_, _, &Spanned {
+        match self.find_entry(id).map(|entry| entry.node) {
+            Some(Node::Item(item)) => item.span,
+            Some(Node::ForeignItem(foreign_item)) => foreign_item.span,
+            Some(Node::TraitItem(trait_method)) => trait_method.span,
+            Some(Node::ImplItem(impl_item)) => impl_item.span,
+            Some(Node::Variant(variant)) => variant.span,
+            Some(Node::Field(field)) => field.span,
+            Some(Node::AnonConst(constant)) => self.body(constant.body).value.span,
+            Some(Node::Expr(expr)) => expr.span,
+            Some(Node::Stmt(stmt)) => stmt.span,
+            Some(Node::Ty(ty)) => ty.span,
+            Some(Node::TraitRef(tr)) => tr.path.span,
+            Some(Node::Binding(pat)) => pat.span,
+            Some(Node::Pat(pat)) => pat.span,
+            Some(Node::Block(block)) => block.span,
+            Some(Node::StructCtor(_)) => self.expect_item(self.get_parent(id)).span,
+            Some(Node::Lifetime(lifetime)) => lifetime.span,
+            Some(Node::GenericParam(param)) => param.span,
+            Some(Node::Visibility(&Spanned {
                 node: VisibilityKind::Restricted { ref path, .. }, ..
             })) => path.span,
-            Some(EntryVisibility(_, _, v)) => bug!("unexpected Visibility {:?}", v),
-            Some(EntryLocal(_, _, local)) => local.span,
-            Some(EntryMacroDef(_, macro_def)) => macro_def.span,
+            Some(Node::Visibility(v)) => bug!("unexpected Visibility {:?}", v),
+            Some(Node::Local(local)) => local.span,
+            Some(Node::MacroDef(macro_def)) => macro_def.span,
 
-            Some(RootCrate(_)) => self.forest.krate.span,
-            Some(NotPresent) | None => {
-                bug!("hir::map::Map::span: id not in map: {:?}", id)
-            }
+            Some(Node::Crate) => self.forest.krate.span,
+            None => bug!("hir::map::Map::span: id not in map: {:?}", id),
         }
     }
 
@@ -1119,7 +977,7 @@ impl<'a, 'hir> NodesMatchingSuffix<'a, 'hir> {
         fn find_first_mod_parent<'a>(map: &'a Map, mut id: NodeId) -> Option<(NodeId, Name)> {
             loop {
                 match map.find(id)? {
-                    NodeItem(item) if item_is_mod(&item) =>
+                    Node::Item(item) if item_is_mod(&item) =>
                         return Some((id, item.name)),
                     _ => {}
                 }
@@ -1154,13 +1012,13 @@ impl<'a, 'hir> Iterator for NodesMatchingSuffix<'a, 'hir> {
                 return None;
             }
             self.idx = NodeId::from_u32(self.idx.as_u32() + 1);
-            let name = match self.map.find_entry(idx) {
-                Some(EntryItem(_, _, n))       => n.name(),
-                Some(EntryForeignItem(_, _, n))=> n.name(),
-                Some(EntryTraitItem(_, _, n))  => n.name(),
-                Some(EntryImplItem(_, _, n))   => n.name(),
-                Some(EntryVariant(_, _, n))    => n.name(),
-                Some(EntryField(_, _, n))      => n.name(),
+            let name = match self.map.find_entry(idx).map(|entry| entry.node) {
+                Some(Node::Item(n)) => n.name(),
+                Some(Node::ForeignItem(n)) => n.name(),
+                Some(Node::TraitItem(n)) => n.name(),
+                Some(Node::ImplItem(n)) => n.name(),
+                Some(Node::Variant(n)) => n.name(),
+                Some(Node::Field(n)) => n.name(),
                 _ => continue,
             };
             if self.matches_names(self.map.get_parent(idx), name) {
@@ -1209,12 +1067,8 @@ pub fn map_crate<'hir>(sess: &::session::Session,
     if log_enabled!(::log::Level::Debug) {
         // This only makes sense for ordered stores; note the
         // enumerate to count the number of entries.
-        let (entries_less_1, _) = map.iter().filter(|&x| {
-            match *x {
-                NotPresent => false,
-                _ => true
-            }
-        }).enumerate().last().expect("AST map was empty after folding?");
+        let (entries_less_1, _) = map.iter().filter_map(|x| *x).enumerate().last()
+            .expect("AST map was empty after folding?");
 
         let entries = entries_less_1 + 1;
         let vector_length = map.len();
@@ -1257,19 +1111,19 @@ impl<'hir> print::PpAnn for Map<'hir> {
 impl<'a> print::State<'a> {
     pub fn print_node(&mut self, node: Node) -> io::Result<()> {
         match node {
-            NodeItem(a)         => self.print_item(&a),
-            NodeForeignItem(a)  => self.print_foreign_item(&a),
-            NodeTraitItem(a)    => self.print_trait_item(a),
-            NodeImplItem(a)     => self.print_impl_item(a),
-            NodeVariant(a)      => self.print_variant(&a),
-            NodeAnonConst(a)    => self.print_anon_const(&a),
-            NodeExpr(a)         => self.print_expr(&a),
-            NodeStmt(a)         => self.print_stmt(&a),
-            NodeTy(a)           => self.print_type(&a),
-            NodeTraitRef(a)     => self.print_trait_ref(&a),
-            NodeBinding(a)       |
-            NodePat(a)          => self.print_pat(&a),
-            NodeBlock(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::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::Block(a)        => {
                 use syntax::print::pprust::PrintState;
 
                 // containing cbox, will be closed by print-block at }
@@ -1278,16 +1132,17 @@ impl<'a> print::State<'a> {
                 self.ibox(0)?;
                 self.print_block(&a)
             }
-            NodeLifetime(a)     => self.print_lifetime(&a),
-            NodeVisibility(a)   => self.print_visibility(&a),
-            NodeGenericParam(_) => bug!("cannot print NodeGenericParam"),
-            NodeField(_)        => bug!("cannot print StructField"),
+            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.
-            NodeStructCtor(_)   => bug!("cannot print isolated StructCtor"),
-            NodeLocal(a)        => self.print_local_decl(&a),
-            NodeMacroDef(_)     => bug!("cannot print MacroDef"),
+            Node::StructCtor(_)   => bug!("cannot print isolated StructCtor"),
+            Node::Local(a)        => self.print_local_decl(&a),
+            Node::MacroDef(_)     => bug!("cannot print MacroDef"),
+            Node::Crate     => bug!("cannot print Crate"),
         }
     }
 }
@@ -1313,7 +1168,7 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
     };
 
     match map.find(id) {
-        Some(NodeItem(item)) => {
+        Some(Node::Item(item)) => {
             let item_str = match item.node {
                 ItemKind::ExternCrate(..) => "extern crate",
                 ItemKind::Use(..) => "use",
@@ -1334,10 +1189,10 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
             };
             format!("{} {}{}", item_str, path_str(), id_str)
         }
-        Some(NodeForeignItem(_)) => {
+        Some(Node::ForeignItem(_)) => {
             format!("foreign item {}{}", path_str(), id_str)
         }
-        Some(NodeImplItem(ii)) => {
+        Some(Node::ImplItem(ii)) => {
             match ii.node {
                 ImplItemKind::Const(..) => {
                     format!("assoc const {} in {}{}", ii.ident, path_str(), id_str)
@@ -1353,7 +1208,7 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
                 }
             }
         }
-        Some(NodeTraitItem(ti)) => {
+        Some(Node::TraitItem(ti)) => {
             let kind = match ti.node {
                 TraitItemKind::Const(..) => "assoc constant",
                 TraitItemKind::Method(..) => "trait method",
@@ -1362,61 +1217,60 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
 
             format!("{} {} in {}{}", kind, ti.ident, path_str(), id_str)
         }
-        Some(NodeVariant(ref variant)) => {
+        Some(Node::Variant(ref variant)) => {
             format!("variant {} in {}{}",
                     variant.node.name,
                     path_str(), id_str)
         }
-        Some(NodeField(ref field)) => {
+        Some(Node::Field(ref field)) => {
             format!("field {} in {}{}",
                     field.ident,
                     path_str(), id_str)
         }
-        Some(NodeAnonConst(_)) => {
+        Some(Node::AnonConst(_)) => {
             format!("const {}{}", map.node_to_pretty_string(id), id_str)
         }
-        Some(NodeExpr(_)) => {
+        Some(Node::Expr(_)) => {
             format!("expr {}{}", map.node_to_pretty_string(id), id_str)
         }
-        Some(NodeStmt(_)) => {
+        Some(Node::Stmt(_)) => {
             format!("stmt {}{}", map.node_to_pretty_string(id), id_str)
         }
-        Some(NodeTy(_)) => {
+        Some(Node::Ty(_)) => {
             format!("type {}{}", map.node_to_pretty_string(id), id_str)
         }
-        Some(NodeTraitRef(_)) => {
+        Some(Node::TraitRef(_)) => {
             format!("trait_ref {}{}", map.node_to_pretty_string(id), id_str)
         }
-        Some(NodeBinding(_)) => {
+        Some(Node::Binding(_)) => {
             format!("local {}{}", map.node_to_pretty_string(id), id_str)
         }
-        Some(NodePat(_)) => {
+        Some(Node::Pat(_)) => {
             format!("pat {}{}", map.node_to_pretty_string(id), id_str)
         }
-        Some(NodeBlock(_)) => {
+        Some(Node::Block(_)) => {
             format!("block {}{}", map.node_to_pretty_string(id), id_str)
         }
-        Some(NodeLocal(_)) => {
+        Some(Node::Local(_)) => {
             format!("local {}{}", map.node_to_pretty_string(id), id_str)
         }
-        Some(NodeStructCtor(_)) => {
+        Some(Node::StructCtor(_)) => {
             format!("struct_ctor {}{}", path_str(), id_str)
         }
-        Some(NodeLifetime(_)) => {
+        Some(Node::Lifetime(_)) => {
             format!("lifetime {}{}", map.node_to_pretty_string(id), id_str)
         }
-        Some(NodeGenericParam(ref param)) => {
+        Some(Node::GenericParam(ref param)) => {
             format!("generic_param {:?}{}", param, id_str)
         }
-        Some(NodeVisibility(ref vis)) => {
+        Some(Node::Visibility(ref vis)) => {
             format!("visibility {:?}{}", vis, id_str)
         }
-        Some(NodeMacroDef(_)) => {
+        Some(Node::MacroDef(_)) => {
             format!("macro {}{}",  path_str(), id_str)
         }
-        None => {
-            format!("unknown node{}", id_str)
-        }
+        Some(Node::Crate) => format!("root_crate"),
+        None => format!("unknown node{}", id_str),
     }
 }
 
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 8aa0f5e07c0ea..7ac334d84a9bf 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -2370,3 +2370,32 @@ impl CodegenFnAttrs {
         self.flags.contains(CodegenFnAttrFlags::NO_MANGLE) || self.export_name.is_some()
     }
 }
+
+#[derive(Copy, Clone, Debug)]
+pub enum Node<'hir> {
+    Item(&'hir Item),
+    ForeignItem(&'hir ForeignItem),
+    TraitItem(&'hir TraitItem),
+    ImplItem(&'hir ImplItem),
+    Variant(&'hir Variant),
+    Field(&'hir StructField),
+    AnonConst(&'hir AnonConst),
+    Expr(&'hir Expr),
+    Stmt(&'hir Stmt),
+    Ty(&'hir Ty),
+    TraitRef(&'hir TraitRef),
+    Binding(&'hir Pat),
+    Pat(&'hir Pat),
+    Block(&'hir Block),
+    Local(&'hir Local),
+    MacroDef(&'hir MacroDef),
+
+    /// StructCtor represents a tuple struct.
+    StructCtor(&'hir VariantData),
+
+    Lifetime(&'hir Lifetime),
+    GenericParam(&'hir GenericParam),
+    Visibility(&'hir Visibility),
+
+    Crate,
+}
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 9fe462e65a2cb..8b221f3463ed3 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub use self::AnnNode::*;
-
 use rustc_target::spec::abi::Abi;
 use syntax::ast;
 use syntax::source_map::{SourceMap, Spanned};
@@ -33,12 +31,12 @@ use std::iter::Peekable;
 use std::vec;
 
 pub enum AnnNode<'a> {
-    NodeName(&'a ast::Name),
-    NodeBlock(&'a hir::Block),
-    NodeItem(&'a hir::Item),
-    NodeSubItem(ast::NodeId),
-    NodeExpr(&'a hir::Expr),
-    NodePat(&'a hir::Pat),
+    Name(&'a ast::Name),
+    Block(&'a hir::Block),
+    Item(&'a hir::Item),
+    SubItem(ast::NodeId),
+    Expr(&'a hir::Expr),
+    Pat(&'a hir::Pat),
 }
 
 pub enum Nested {
@@ -529,7 +527,7 @@ impl<'a> State<'a> {
         self.hardbreak_if_not_bol()?;
         self.maybe_print_comment(item.span.lo())?;
         self.print_outer_attributes(&item.attrs)?;
-        self.ann.pre(self, NodeItem(item))?;
+        self.ann.pre(self, AnnNode::Item(item))?;
         match item.node {
             hir::ItemKind::ExternCrate(orig_name) => {
                 self.head(&visibility_qualified(&item.vis, "extern crate"))?;
@@ -768,7 +766,7 @@ impl<'a> State<'a> {
                 self.s.word(";")?;
             }
         }
-        self.ann.post(self, NodeItem(item))
+        self.ann.post(self, AnnNode::Item(item))
     }
 
     pub fn print_trait_ref(&mut self, t: &hir::TraitRef) -> io::Result<()> {
@@ -933,7 +931,7 @@ impl<'a> State<'a> {
     }
 
     pub fn print_trait_item(&mut self, ti: &hir::TraitItem) -> io::Result<()> {
-        self.ann.pre(self, NodeSubItem(ti.id))?;
+        self.ann.pre(self, AnnNode::SubItem(ti.id))?;
         self.hardbreak_if_not_bol()?;
         self.maybe_print_comment(ti.span.lo())?;
         self.print_outer_attributes(&ti.attrs)?;
@@ -965,11 +963,11 @@ impl<'a> State<'a> {
                                            default.as_ref().map(|ty| &**ty))?;
             }
         }
-        self.ann.post(self, NodeSubItem(ti.id))
+        self.ann.post(self, AnnNode::SubItem(ti.id))
     }
 
     pub fn print_impl_item(&mut self, ii: &hir::ImplItem) -> io::Result<()> {
-        self.ann.pre(self, NodeSubItem(ii.id))?;
+        self.ann.pre(self, AnnNode::SubItem(ii.id))?;
         self.hardbreak_if_not_bol()?;
         self.maybe_print_comment(ii.span.lo())?;
         self.print_outer_attributes(&ii.attrs)?;
@@ -995,7 +993,7 @@ impl<'a> State<'a> {
                 self.print_associated_type(ii.ident, Some(bounds), None)?;
             }
         }
-        self.ann.post(self, NodeSubItem(ii.id))
+        self.ann.post(self, AnnNode::SubItem(ii.id))
     }
 
     pub fn print_stmt(&mut self, st: &hir::Stmt) -> io::Result<()> {
@@ -1055,7 +1053,7 @@ impl<'a> State<'a> {
             hir::DefaultBlock => (),
         }
         self.maybe_print_comment(blk.span.lo())?;
-        self.ann.pre(self, NodeBlock(blk))?;
+        self.ann.pre(self, AnnNode::Block(blk))?;
         self.bopen()?;
 
         self.print_inner_attributes(attrs)?;
@@ -1072,7 +1070,7 @@ impl<'a> State<'a> {
             _ => (),
         }
         self.bclose_maybe_open(blk.span, indented, close_box)?;
-        self.ann.post(self, NodeBlock(blk))
+        self.ann.post(self, AnnNode::Block(blk))
     }
 
     fn print_else(&mut self, els: Option<&hir::Expr>) -> io::Result<()> {
@@ -1321,7 +1319,7 @@ impl<'a> State<'a> {
         self.maybe_print_comment(expr.span.lo())?;
         self.print_outer_attributes(&expr.attrs)?;
         self.ibox(indent_unit)?;
-        self.ann.pre(self, NodeExpr(expr))?;
+        self.ann.pre(self, AnnNode::Expr(expr))?;
         match expr.node {
             hir::ExprKind::Box(ref expr) => {
                 self.word_space("box")?;
@@ -1559,7 +1557,7 @@ impl<'a> State<'a> {
                 self.print_expr_maybe_paren(&expr, parser::PREC_JUMP)?;
             }
         }
-        self.ann.post(self, NodeExpr(expr))?;
+        self.ann.post(self, AnnNode::Expr(expr))?;
         self.end()
     }
 
@@ -1606,7 +1604,7 @@ impl<'a> State<'a> {
         } else {
             self.s.word(&ident.as_str())?;
         }
-        self.ann.post(self, NodeName(&ident.name))
+        self.ann.post(self, AnnNode::Name(&ident.name))
     }
 
     pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> {
@@ -1774,7 +1772,7 @@ impl<'a> State<'a> {
 
     pub fn print_pat(&mut self, pat: &hir::Pat) -> io::Result<()> {
         self.maybe_print_comment(pat.span.lo())?;
-        self.ann.pre(self, NodePat(pat))?;
+        self.ann.pre(self, AnnNode::Pat(pat))?;
         // Pat isn't normalized, but the beauty of it
         // is that it doesn't matter
         match pat.node {
@@ -1928,7 +1926,7 @@ impl<'a> State<'a> {
                 self.s.word("]")?;
             }
         }
-        self.ann.post(self, NodePat(pat))
+        self.ann.post(self, AnnNode::Pat(pat))
     }
 
     fn print_arm(&mut self, arm: &hir::Arm) -> io::Result<()> {
diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs
index 96c64c05ccfbd..8eab07ece05ef 100644
--- a/src/librustc/infer/anon_types/mod.rs
+++ b/src/librustc/infer/anon_types/mod.rs
@@ -10,6 +10,7 @@
 
 use hir::def_id::DefId;
 use hir;
+use hir::Node;
 use infer::{self, InferCtxt, InferOk, TypeVariableOrigin};
 use infer::outlives::free_region_map::FreeRegionRelations;
 use rustc_data_structures::fx::FxHashMap;
@@ -697,7 +698,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
                             parent_def_id == tcx.hir.local_def_id(anon_parent_node_id)
                         };
                         let in_definition_scope = match tcx.hir.find(anon_node_id) {
-                            Some(hir::map::NodeItem(item)) => match item.node {
+                            Some(Node::Item(item)) => match item.node {
                                 // impl trait
                                 hir::ItemKind::Existential(hir::ExistTy {
                                     impl_trait_fn: Some(parent),
@@ -714,7 +715,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
                                 ),
                                 _ => def_scope_default(),
                             },
-                            Some(hir::map::NodeImplItem(item)) => match item.node {
+                            Some(Node::ImplItem(item)) => match item.node {
                                 hir::ImplItemKind::Existential(_) => may_define_existential_type(
                                     tcx,
                                     self.parent_def_id,
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index b05ea9a5ed4b0..cf0d0ceadca91 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -62,7 +62,7 @@ use super::lexical_region_resolve::RegionResolutionError;
 
 use std::{cmp, fmt};
 use hir;
-use hir::map as hir_map;
+use hir::Node;
 use hir::def_id::DefId;
 use middle::region;
 use traits::{ObligationCause, ObligationCauseCode};
@@ -100,8 +100,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 };
                 let span = scope.span(self, region_scope_tree);
                 let tag = match self.hir.find(scope.node_id(self, region_scope_tree)) {
-                    Some(hir_map::NodeBlock(_)) => "block",
-                    Some(hir_map::NodeExpr(expr)) => match expr.node {
+                    Some(Node::Block(_)) => "block",
+                    Some(Node::Expr(expr)) => match expr.node {
                         hir::ExprKind::Call(..) => "call",
                         hir::ExprKind::MethodCall(..) => "method call",
                         hir::ExprKind::Match(.., hir::MatchSource::IfLetDesugar { .. }) => "if let",
@@ -110,10 +110,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                         hir::ExprKind::Match(..) => "match",
                         _ => "expression",
                     },
-                    Some(hir_map::NodeStmt(_)) => "statement",
-                    Some(hir_map::NodeItem(it)) => Self::item_scope_tag(&it),
-                    Some(hir_map::NodeTraitItem(it)) => Self::trait_item_scope_tag(&it),
-                    Some(hir_map::NodeImplItem(it)) => Self::impl_item_scope_tag(&it),
+                    Some(Node::Stmt(_)) => "statement",
+                    Some(Node::Item(it)) => Self::item_scope_tag(&it),
+                    Some(Node::TraitItem(it)) => Self::trait_item_scope_tag(&it),
+                    Some(Node::ImplItem(it)) => Self::impl_item_scope_tag(&it),
                     Some(_) | None => {
                         err.span_note(span, &unknown_scope());
                         return;
@@ -194,10 +194,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         let scope = region.free_region_binding_scope(self);
         let node = self.hir.as_local_node_id(scope).unwrap_or(DUMMY_NODE_ID);
         let tag = match self.hir.find(node) {
-            Some(hir_map::NodeBlock(_)) | Some(hir_map::NodeExpr(_)) => "body",
-            Some(hir_map::NodeItem(it)) => Self::item_scope_tag(&it),
-            Some(hir_map::NodeTraitItem(it)) => Self::trait_item_scope_tag(&it),
-            Some(hir_map::NodeImplItem(it)) => Self::impl_item_scope_tag(&it),
+            Some(Node::Block(_)) | Some(Node::Expr(_)) => "body",
+            Some(Node::Item(it)) => Self::item_scope_tag(&it),
+            Some(Node::TraitItem(it)) => Self::trait_item_scope_tag(&it),
+            Some(Node::ImplItem(it)) => Self::impl_item_scope_tag(&it),
             _ => unreachable!()
         };
         let (prefix, span) = match *region {
@@ -1127,7 +1127,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                             // We do this to avoid suggesting code that ends up as `T: 'a'b`,
                             // instead we suggest `T: 'a + 'b` in that case.
                             let mut has_bounds = false;
-                            if let hir_map::NodeGenericParam(ref param) = hir.get(id) {
+                            if let Node::GenericParam(ref param) = hir.get(id) {
                                 has_bounds = !param.bounds.is_empty();
                             }
                             let sp = hir.span(id);
diff --git a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
index 21be09b0ba193..e3faf755672a1 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
@@ -10,7 +10,7 @@
 
 use hir;
 use ty::{self, Region, TyCtxt};
-use hir::map as hir_map;
+use hir::Node;
 use middle::resolve_lifetime as rl;
 use hir::intravisit::{self, NestedVisitorMap, Visitor};
 use infer::error_reporting::nice_region_error::NiceRegionError;
@@ -40,15 +40,15 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
             let def_id = anon_reg.def_id;
             if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
                 let fndecl = match self.tcx.hir.get(node_id) {
-                    hir_map::NodeItem(&hir::Item {
+                    Node::Item(&hir::Item {
                         node: hir::ItemKind::Fn(ref fndecl, ..),
                         ..
                     }) => &fndecl,
-                    hir_map::NodeTraitItem(&hir::TraitItem {
+                    Node::TraitItem(&hir::TraitItem {
                         node: hir::TraitItemKind::Method(ref m, ..),
                         ..
                     })
-                    | hir_map::NodeImplItem(&hir::ImplItem {
+                    | Node::ImplItem(&hir::ImplItem {
                         node: hir::ImplItemKind::Method(ref m, ..),
                         ..
                     }) => &m.decl,
diff --git a/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs
index f4ef197e5b422..5c27cdb6fb553 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs
@@ -15,7 +15,7 @@ use infer::error_reporting::nice_region_error::NiceRegionError;
 use infer::SubregionOrigin;
 use ty::RegionKind;
 use hir::{Expr, ExprKind::Closure};
-use hir::map::NodeExpr;
+use hir::Node;
 use util::common::ErrorReported;
 use infer::lexical_region_resolve::RegionResolutionError::SubSupConflict;
 
@@ -59,7 +59,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
                 let hir = &self.tcx.hir;
                 if let Some(node_id) = hir.as_local_node_id(free_region.scope) {
                     match hir.get(node_id) {
-                        NodeExpr(Expr {
+                        Node::Expr(Expr {
                             node: Closure(_, _, _, closure_span, None),
                             ..
                         }) => {
diff --git a/src/librustc/infer/error_reporting/nice_region_error/util.rs b/src/librustc/infer/error_reporting/nice_region_error/util.rs
index 8cb0df18bc8ff..30406f1fec55c 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/util.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/util.rs
@@ -10,11 +10,12 @@
 
 //! Helper functions corresponding to lifetime errors due to
 //! anonymous regions.
+
 use hir;
 use infer::error_reporting::nice_region_error::NiceRegionError;
 use ty::{self, Region, Ty};
 use hir::def_id::DefId;
-use hir::map as hir_map;
+use hir::Node;
 use syntax_pos::Span;
 
 // The struct contains the information about the anonymous region
@@ -137,8 +138,8 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
             .as_local_node_id(suitable_region_binding_scope)
             .unwrap();
         let is_impl_item = match self.tcx.hir.find(node_id) {
-            Some(hir_map::NodeItem(..)) | Some(hir_map::NodeTraitItem(..)) => false,
-            Some(hir_map::NodeImplItem(..)) => {
+            Some(Node::Item(..)) | Some(Node::TraitItem(..)) => false,
+            Some(Node::ImplItem(..)) => {
                 self.is_bound_region_in_impl_item(suitable_region_binding_scope)
             }
             _ => return None,
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 30701654f299d..d320173f9f47d 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -12,7 +12,7 @@
 // closely. The idea is that all reachable symbols are live, codes called
 // from live codes are live, and everything else is dead.
 
-use hir::map as hir_map;
+use hir::Node;
 use hir::{self, PatKind};
 use hir::intravisit::{self, Visitor, NestedVisitorMap};
 use hir::itemlikevisit::ItemLikeVisitor;
@@ -29,16 +29,16 @@ use syntax::attr;
 use syntax_pos;
 
 // Any local node that may call something in its body block should be
-// explored. For example, if it's a live NodeItem that is a
+// explored. For example, if it's a live Node::Item that is a
 // function, then we should explore its block to check for codes that
 // may need to be marked as live.
 fn should_explore<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             node_id: ast::NodeId) -> bool {
     match tcx.hir.find(node_id) {
-        Some(hir_map::NodeItem(..)) |
-        Some(hir_map::NodeImplItem(..)) |
-        Some(hir_map::NodeForeignItem(..)) |
-        Some(hir_map::NodeTraitItem(..)) =>
+        Some(Node::Item(..)) |
+        Some(Node::ImplItem(..)) |
+        Some(Node::ForeignItem(..)) |
+        Some(Node::TraitItem(..)) =>
             true,
         _ =>
             false
@@ -145,13 +145,13 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
         }
     }
 
-    fn visit_node(&mut self, node: &hir_map::Node<'tcx>) {
+    fn visit_node(&mut self, node: &Node<'tcx>) {
         let had_repr_c = self.repr_has_repr_c;
         self.repr_has_repr_c = false;
         let had_inherited_pub_visibility = self.inherited_pub_visibility;
         self.inherited_pub_visibility = false;
         match *node {
-            hir_map::NodeItem(item) => {
+            Node::Item(item) => {
                 match item.node {
                     hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
                         let def_id = self.tcx.hir.local_def_id(item.id);
@@ -173,13 +173,13 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
                     _ => ()
                 }
             }
-            hir_map::NodeTraitItem(trait_item) => {
+            Node::TraitItem(trait_item) => {
                 intravisit::walk_trait_item(self, trait_item);
             }
-            hir_map::NodeImplItem(impl_item) => {
+            Node::ImplItem(impl_item) => {
                 intravisit::walk_impl_item(self, impl_item);
             }
-            hir_map::NodeForeignItem(foreign_item) => {
+            Node::ForeignItem(foreign_item) => {
                 intravisit::walk_foreign_item(self, &foreign_item);
             }
             _ => ()
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 7d9590ee578e6..2697d62cf467a 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -102,11 +102,13 @@
 //!   only dead if the end of the function's block can never be reached.
 //!   It is the responsibility of typeck to ensure that there are no
 //!   `return` expressions in a function declared as diverging.
+
 use self::LoopKind::*;
 use self::LiveNodeKind::*;
 use self::VarKind::*;
 
 use hir::def::*;
+use hir::Node;
 use ty::{self, TyCtxt};
 use lint;
 use errors::Applicability;
@@ -362,7 +364,7 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
     // Don't run unused pass for #[derive()]
     if let FnKind::Method(..) = fk {
         let parent = ir.tcx.hir.get_parent(id);
-        if let Some(hir::map::Node::NodeItem(i)) = ir.tcx.hir.find(parent) {
+        if let Some(Node::Item(i)) = ir.tcx.hir.find(parent) {
             if i.attrs.iter().any(|a| a.check_name("automatically_derived")) {
                 return;
             }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index e0ed0f1da509e..b63cde0f205f7 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -70,7 +70,7 @@ use self::Aliasability::*;
 
 use middle::region;
 use hir::def_id::{DefId, LocalDefId};
-use hir::map as hir_map;
+use hir::Node;
 use infer::InferCtxt;
 use hir::def::{Def, CtorKind};
 use ty::adjustment;
@@ -343,7 +343,7 @@ impl MutabilityCategory {
 
     fn from_local(tcx: TyCtxt, tables: &ty::TypeckTables, id: ast::NodeId) -> MutabilityCategory {
         let ret = match tcx.hir.get(id) {
-            hir_map::NodeBinding(p) => match p.node {
+            Node::Binding(p) => match p.node {
                 PatKind::Binding(..) => {
                     let bm = *tables.pat_binding_modes()
                                     .get(p.hir_id)
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index ccfc84940f2df..55ee8987e8ad5 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -16,7 +16,7 @@
 // reachable as well.
 
 use hir::{CodegenFnAttrs, CodegenFnAttrFlags};
-use hir::map as hir_map;
+use hir::Node;
 use hir::def::Def;
 use hir::def_id::{DefId, CrateNum};
 use rustc_data_structures::sync::Lrc;
@@ -64,7 +64,7 @@ fn method_might_be_inlined<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
     if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_src) {
         match tcx.hir.find(impl_node_id) {
-            Some(hir_map::NodeItem(item)) =>
+            Some(Node::Item(item)) =>
                 item_might_be_inlined(tcx, &item, codegen_fn_attrs),
             Some(..) | None =>
                 span_bug!(impl_item.span, "impl did is not an item")
@@ -156,14 +156,14 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
         };
 
         match self.tcx.hir.find(node_id) {
-            Some(hir_map::NodeItem(item)) => {
+            Some(Node::Item(item)) => {
                 match item.node {
                     hir::ItemKind::Fn(..) =>
                         item_might_be_inlined(self.tcx, &item, self.tcx.codegen_fn_attrs(def_id)),
                     _ => false,
                 }
             }
-            Some(hir_map::NodeTraitItem(trait_method)) => {
+            Some(Node::TraitItem(trait_method)) => {
                 match trait_method.node {
                     hir::TraitItemKind::Const(_, ref default) => default.is_some(),
                     hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(_)) => true,
@@ -171,7 +171,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                     hir::TraitItemKind::Type(..) => false,
                 }
             }
-            Some(hir_map::NodeImplItem(impl_item)) => {
+            Some(Node::ImplItem(impl_item)) => {
                 match impl_item.node {
                     hir::ImplItemKind::Const(..) => true,
                     hir::ImplItemKind::Method(..) => {
@@ -219,12 +219,12 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
         }
     }
 
-    fn propagate_node(&mut self, node: &hir_map::Node<'tcx>,
+    fn propagate_node(&mut self, node: &Node<'tcx>,
                       search_item: ast::NodeId) {
         if !self.any_library {
             // If we are building an executable, only explicitly extern
             // types need to be exported.
-            if let hir_map::NodeItem(item) = *node {
+            if let Node::Item(item) = *node {
                 let reachable = if let hir::ItemKind::Fn(_, header, ..) = item.node {
                     header.abi != Abi::Rust
                 } else {
@@ -248,7 +248,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
         }
 
         match *node {
-            hir_map::NodeItem(item) => {
+            Node::Item(item) => {
                 match item.node {
                     hir::ItemKind::Fn(.., body) => {
                         let def_id = self.tcx.hir.local_def_id(item.id);
@@ -285,7 +285,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                     hir::ItemKind::GlobalAsm(..) => {}
                 }
             }
-            hir_map::NodeTraitItem(trait_method) => {
+            Node::TraitItem(trait_method) => {
                 match trait_method.node {
                     hir::TraitItemKind::Const(_, None) |
                     hir::TraitItemKind::Method(_, hir::TraitMethod::Required(_)) => {
@@ -298,7 +298,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                     hir::TraitItemKind::Type(..) => {}
                 }
             }
-            hir_map::NodeImplItem(impl_item) => {
+            Node::ImplItem(impl_item) => {
                 match impl_item.node {
                     hir::ImplItemKind::Const(_, body) => {
                         self.visit_nested_body(body);
@@ -313,16 +313,16 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                     hir::ImplItemKind::Type(_) => {}
                 }
             }
-            hir_map::NodeExpr(&hir::Expr { node: hir::ExprKind::Closure(.., body, _, _), .. }) => {
+            Node::Expr(&hir::Expr { node: hir::ExprKind::Closure(.., body, _, _), .. }) => {
                 self.visit_nested_body(body);
             }
             // Nothing to recurse on for these
-            hir_map::NodeForeignItem(_) |
-            hir_map::NodeVariant(_) |
-            hir_map::NodeStructCtor(_) |
-            hir_map::NodeField(_) |
-            hir_map::NodeTy(_) |
-            hir_map::NodeMacroDef(_) => {}
+            Node::ForeignItem(_) |
+            Node::Variant(_) |
+            Node::StructCtor(_) |
+            Node::Field(_) |
+            Node::Ty(_) |
+            Node::MacroDef(_) => {}
             _ => {
                 bug!("found unexpected thingy in worklist: {}",
                      self.tcx.hir.node_to_string(search_item))
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index be1d93dbad1b8..20ee5f0b04635 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -30,6 +30,7 @@ use ty::TyCtxt;
 use ty::query::Providers;
 
 use hir;
+use hir::Node;
 use hir::def_id::DefId;
 use hir::intravisit::{self, Visitor, NestedVisitorMap};
 use hir::{Block, Arm, Pat, PatKind, Stmt, Expr, Local};
@@ -257,7 +258,7 @@ impl Scope {
         }
         let span = tcx.hir.span(node_id);
         if let ScopeData::Remainder(r) = self.data() {
-            if let hir::map::NodeBlock(ref blk) = tcx.hir.get(node_id) {
+            if let Node::Block(ref blk) = tcx.hir.get(node_id) {
                 // Want span for scope starting after the
                 // indexed statement and ending at end of
                 // `blk`; reuse span of `blk` and shift `lo`
@@ -1420,8 +1421,8 @@ fn region_scope_tree<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
         // record its impl/trait parent, as it can also have
         // lifetime parameters free in this body.
         match tcx.hir.get(id) {
-            hir::map::NodeImplItem(_) |
-            hir::map::NodeTraitItem(_) => {
+            Node::ImplItem(_) |
+            Node::TraitItem(_) => {
                 visitor.scope_tree.root_parent = Some(tcx.hir.get_parent(id));
             }
             _ => {}
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 379f4df11fa7b..d0f801e661b43 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -18,7 +18,7 @@
 use hir::def::Def;
 use hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
 use hir::map::Map;
-use hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, ParamName};
+use hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, ParamName, Node};
 use ty::{self, TyCtxt, GenericParamDefKind};
 
 use errors::DiagnosticBuilder;
@@ -1440,10 +1440,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                     let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
                     debug!("node id first={:?}", node_id);
                     if let Some((id, span, name)) = match self.tcx.hir.get(node_id) {
-                        hir::map::NodeLifetime(hir_lifetime) => {
+                        Node::Lifetime(hir_lifetime) => {
                             Some((hir_lifetime.id, hir_lifetime.span, hir_lifetime.name.ident()))
                         }
-                        hir::map::NodeGenericParam(param) => {
+                        Node::GenericParam(param) => {
                             Some((param.id, param.span, param.name.ident()))
                         }
                         _ => None,
@@ -1466,10 +1466,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                 None => {
                     let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
                     if let Some((id, span, name)) = match self.tcx.hir.get(node_id) {
-                        hir::map::NodeLifetime(hir_lifetime) => {
+                        Node::Lifetime(hir_lifetime) => {
                             Some((hir_lifetime.id, hir_lifetime.span, hir_lifetime.name.ident()))
                         }
-                        hir::map::NodeGenericParam(param) => {
+                        Node::GenericParam(param) => {
                             Some((param.id, param.span, param.name.ident()))
                         }
                         _ => None,
@@ -1643,15 +1643,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             } else if let Some(body_id) = outermost_body {
                 let fn_id = self.tcx.hir.body_owner(body_id);
                 match self.tcx.hir.get(fn_id) {
-                    hir::map::NodeItem(&hir::Item {
+                    Node::Item(&hir::Item {
                         node: hir::ItemKind::Fn(..),
                         ..
                     })
-                    | hir::map::NodeTraitItem(&hir::TraitItem {
+                    | Node::TraitItem(&hir::TraitItem {
                         node: hir::TraitItemKind::Method(..),
                         ..
                     })
-                    | hir::map::NodeImplItem(&hir::ImplItem {
+                    | Node::ImplItem(&hir::ImplItem {
                         node: hir::ImplItemKind::Method(..),
                         ..
                     }) => {
@@ -1868,12 +1868,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         let parent = self.tcx.hir.get_parent_node(output.id);
         let body = match self.tcx.hir.get(parent) {
             // `fn` definitions and methods.
-            hir::map::NodeItem(&hir::Item {
+            Node::Item(&hir::Item {
                 node: hir::ItemKind::Fn(.., body),
                 ..
             }) => Some(body),
 
-            hir::map::NodeTraitItem(&hir::TraitItem {
+            Node::TraitItem(&hir::TraitItem {
                 node: hir::TraitItemKind::Method(_, ref m),
                 ..
             }) => {
@@ -1896,7 +1896,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                 }
             }
 
-            hir::map::NodeImplItem(&hir::ImplItem {
+            Node::ImplItem(&hir::ImplItem {
                 node: hir::ImplItemKind::Method(_, body),
                 ..
             }) => {
@@ -1918,7 +1918,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
 
             // Foreign functions, `fn(...) -> R` and `Trait(...) -> R` (both types and bounds).
-            hir::map::NodeForeignItem(_) | hir::map::NodeTy(_) | hir::map::NodeTraitRef(_) => None,
+            Node::ForeignItem(_) | Node::Ty(_) | Node::TraitRef(_) => None,
             // Everything else (only closures?) doesn't
             // actually enjoy elision in return types.
             _ => {
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 405b320f3feaf..b34378151ccb3 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -29,6 +29,7 @@ use super::{
 
 use errors::{Applicability, DiagnosticBuilder};
 use hir;
+use hir::Node;
 use hir::def_id::DefId;
 use infer::{self, InferCtxt};
 use infer::type_variable::TypeVariableOrigin;
@@ -864,7 +865,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                        err: &mut DiagnosticBuilder<'tcx>) {
         if let &ObligationCauseCode::VariableType(node_id) = code {
             let parent_node = self.tcx.hir.get_parent_node(node_id);
-            if let Some(hir::map::NodeLocal(ref local)) = self.tcx.hir.find(parent_node) {
+            if let Some(Node::Local(ref local)) = self.tcx.hir.find(parent_node) {
                 if let Some(ref expr) = local.init {
                     if let hir::ExprKind::Index(_, _) = expr.node {
                         if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
@@ -932,9 +933,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     /// returns a span and `ArgKind` information that describes the
     /// arguments it expects. This can be supplied to
     /// `report_arg_count_mismatch`.
-    pub fn get_fn_like_arguments(&self, node: hir::map::Node) -> (Span, Vec<ArgKind>) {
+    pub fn get_fn_like_arguments(&self, node: Node) -> (Span, Vec<ArgKind>) {
         match node {
-            hir::map::NodeExpr(&hir::Expr {
+            Node::Expr(&hir::Expr {
                 node: hir::ExprKind::Closure(_, ref _decl, id, span, _),
                 ..
             }) => {
@@ -961,17 +962,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                     })
                     .collect::<Vec<ArgKind>>())
             }
-            hir::map::NodeItem(&hir::Item {
+            Node::Item(&hir::Item {
                 span,
                 node: hir::ItemKind::Fn(ref decl, ..),
                 ..
             }) |
-            hir::map::NodeImplItem(&hir::ImplItem {
+            Node::ImplItem(&hir::ImplItem {
                 span,
                 node: hir::ImplItemKind::Method(hir::MethodSig { ref decl, .. }, _),
                 ..
             }) |
-            hir::map::NodeTraitItem(&hir::TraitItem {
+            Node::TraitItem(&hir::TraitItem {
                 span,
                 node: hir::TraitItemKind::Method(hir::MethodSig { ref decl, .. }, _),
                 ..
@@ -987,7 +988,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                     _ => ArgKind::Arg("_".to_owned(), "_".to_owned())
                 }).collect::<Vec<ArgKind>>())
             }
-            hir::map::NodeVariant(&hir::Variant {
+            Node::Variant(&hir::Variant {
                 span,
                 node: hir::VariantKind {
                     data: hir::VariantData::Tuple(ref fields, _),
@@ -1000,7 +1001,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                      ArgKind::Arg(field.ident.to_string(), "_".to_string())
                  }).collect::<Vec<_>>())
             }
-            hir::map::NodeStructCtor(ref variant_data) => {
+            Node::StructCtor(ref variant_data) => {
                 (self.tcx.sess.source_map().def_span(self.tcx.hir.span(variant_data.id())),
                  variant_data.fields()
                     .iter().map(|_| ArgKind::Arg("_".to_owned(), "_".to_owned()))
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 77b4d32c397d7..63308ac46d10f 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -15,6 +15,7 @@ pub use self::IntVarValue::*;
 pub use self::fold::TypeFoldable;
 
 use hir::{map as hir_map, FreevarMap, TraitMap};
+use hir::Node;
 use hir::def::{Def, CtorKind, ExportMap};
 use hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use hir::map::DefPathData;
@@ -2478,7 +2479,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
 
     pub fn expr_span(self, id: NodeId) -> Span {
         match self.hir.find(id) {
-            Some(hir_map::NodeExpr(e)) => {
+            Some(Node::Expr(e)) => {
                 e.span
             }
             Some(f) => {
@@ -2505,7 +2506,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub fn opt_associated_item(self, def_id: DefId) -> Option<AssociatedItem> {
         let is_associated_item = if let Some(node_id) = self.hir.as_local_node_id(def_id) {
             match self.hir.get(node_id) {
-                hir_map::NodeTraitItem(_) | hir_map::NodeImplItem(_) => true,
+                Node::TraitItem(_) | Node::ImplItem(_) => true,
                 _ => false,
             }
         } else {
@@ -2895,7 +2896,7 @@ fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option
 /// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition
 pub fn is_impl_trait_defn(tcx: TyCtxt, def_id: DefId) -> Option<DefId> {
     if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
-        if let hir::map::NodeItem(item) = tcx.hir.get(node_id) {
+        if let Node::Item(item) = tcx.hir.get(node_id) {
             if let hir::ItemKind::Existential(ref exist_ty) = item.node {
                 return exist_ty.impl_trait_fn;
             }
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 938cdf3048b1c..f7679dc8ce0f0 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -12,8 +12,8 @@
 
 use hir::def::Def;
 use hir::def_id::DefId;
-use hir::map::{DefPathData, Node};
-use hir;
+use hir::map::DefPathData;
+use hir::{self, Node};
 use ich::NodeIdHashingMode;
 use traits::{self, ObligationCause};
 use ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
@@ -604,10 +604,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub fn is_static(&self, def_id: DefId) -> Option<hir::Mutability> {
         if let Some(node) = self.hir.get_if_local(def_id) {
             match node {
-                Node::NodeItem(&hir::Item {
+                Node::Item(&hir::Item {
                     node: hir::ItemKind::Static(_, mutbl, _), ..
                 }) => Some(mutbl),
-                Node::NodeForeignItem(&hir::ForeignItem {
+                Node::ForeignItem(&hir::ForeignItem {
                     node: hir::ForeignItemKind::Static(_, is_mutbl), ..
                 }) =>
                     Some(if is_mutbl {
diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs
index 847d37be89933..1af117c97f569 100644
--- a/src/librustc_borrowck/borrowck/check_loans.rs
+++ b/src/librustc_borrowck/borrowck/check_loans.rs
@@ -16,6 +16,7 @@
 // 2. loans made in overlapping scopes do not conflict
 // 3. assignments do not affect things loaned out as immutable
 // 4. moves do not affect things loaned out in any way
+
 use self::UseError::*;
 
 use borrowck::*;
@@ -29,6 +30,7 @@ use rustc::ty::{self, TyCtxt, RegionKind};
 use syntax::ast;
 use syntax_pos::Span;
 use rustc::hir;
+use rustc::hir::Node;
 use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin};
 
 use std::rc::Rc;
@@ -201,7 +203,7 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
 
     let node_id = bccx.tcx.hir.as_local_node_id(def_id).unwrap();
     let movable_generator = !match bccx.tcx.hir.get(node_id) {
-        hir::map::Node::NodeExpr(&hir::Expr {
+        Node::Expr(&hir::Expr {
             node: hir::ExprKind::Closure(.., Some(hir::GeneratorMovability::Static)),
             ..
         }) => true,
diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
index 5c165fbad6943..ffc4fbfb4c9cb 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
@@ -24,7 +24,7 @@ use std::rc::Rc;
 use syntax::ast;
 use syntax_pos::Span;
 use rustc::hir::*;
-use rustc::hir::map::Node::*;
+use rustc::hir::Node;
 
 struct GatherMoveInfo<'c, 'tcx: 'c> {
     id: hir::ItemLocalId,
@@ -60,7 +60,7 @@ fn get_pattern_source<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &Pat) -> Patte
     let parent = tcx.hir.get_parent_node(pat.id);
 
     match tcx.hir.get(parent) {
-        NodeExpr(ref e) => {
+        Node::Expr(ref e) => {
             // the enclosing expression must be a `match` or something else
             assert!(match e.node {
                         ExprKind::Match(..) => true,
@@ -68,7 +68,7 @@ fn get_pattern_source<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &Pat) -> Patte
                     });
             PatternSource::MatchExpr(e)
         }
-        NodeLocal(local) => PatternSource::LetDecl(local),
+        Node::Local(local) => PatternSource::LetDecl(local),
         _ => return PatternSource::Other,
 
     }
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index a3ca329b92d7f..ad45c5429a512 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -21,7 +21,7 @@ pub use self::MovedValueUseKind::*;
 use self::InteriorKind::*;
 
 use rustc::hir::HirId;
-use rustc::hir::map as hir_map;
+use rustc::hir::Node;
 use rustc::hir::map::blocks::FnLikeNode;
 use rustc::cfg;
 use rustc::middle::borrowck::{BorrowCheckResult, SignalledError};
@@ -95,8 +95,8 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
     let owner_id = tcx.hir.as_local_node_id(owner_def_id).unwrap();
 
     match tcx.hir.get(owner_id) {
-        hir_map::NodeStructCtor(_) |
-        hir_map::NodeVariant(_) => {
+        Node::StructCtor(_) |
+        Node::Variant(_) => {
             // We get invoked with anything that has MIR, but some of
             // those things (notably the synthesized constructors from
             // tuple structs/variants) do not have an associated body
@@ -419,7 +419,7 @@ fn closure_to_block(closure_id: LocalDefId,
                     tcx: TyCtxt) -> ast::NodeId {
     let closure_id = tcx.hir.local_def_id_to_node_id(closure_id);
     match tcx.hir.get(closure_id) {
-        hir_map::NodeExpr(expr) => match expr.node {
+        Node::Expr(expr) => match expr.node {
             hir::ExprKind::Closure(.., body_id, _, _) => {
                 body_id.node_id
             }
@@ -908,7 +908,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                     let node =  self.tcx.hir.get(node_id);
 
                     // This pattern probably always matches.
-                    if let hir_map::NodeExpr(
+                    if let Node::Expr(
                         hir::Expr { node: hir::ExprKind::Index(lhs, _), ..}
                     ) = node {
                         let ty = self.tables.expr_ty(lhs);
@@ -1032,7 +1032,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                 if let ty::ReScope(scope) = *super_scope {
                     let node_id = scope.node_id(self.tcx, &self.region_scope_tree);
                     match self.tcx.hir.find(node_id) {
-                        Some(hir_map::NodeStmt(_)) => {
+                        Some(Node::Stmt(_)) => {
                             if *sub_scope != ty::ReStatic {
                                 db.note("consider using a `let` binding to increase its lifetime");
                             }
@@ -1183,7 +1183,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
 
     fn local_binding_mode(&self, node_id: ast::NodeId) -> ty::BindingMode {
         let pat = match self.tcx.hir.get(node_id) {
-            hir_map::Node::NodeBinding(pat) => pat,
+            Node::Binding(pat) => pat,
             node => bug!("bad node for local: {:?}", node)
         };
 
@@ -1259,7 +1259,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                     None => return
                 };
 
-                if let hir_map::Node::NodeField(ref field) = self.tcx.hir.get(node_id) {
+                if let Node::Field(ref field) = self.tcx.hir.get(node_id) {
                     if let Some(msg) = self.suggest_mut_for_immutable(&field.ty, false) {
                         db.span_label(field.ty.span, msg);
                     }
diff --git a/src/librustc_borrowck/dataflow.rs b/src/librustc_borrowck/dataflow.rs
index 640c23ebf9ddc..832b69cb2acc4 100644
--- a/src/librustc_borrowck/dataflow.rs
+++ b/src/librustc_borrowck/dataflow.rs
@@ -117,12 +117,12 @@ impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O
            ps: &mut pprust::State,
            node: pprust::AnnNode) -> io::Result<()> {
         let id = match node {
-            pprust::NodeName(_) => return Ok(()),
-            pprust::NodeExpr(expr) => expr.hir_id.local_id,
-            pprust::NodeBlock(blk) => blk.hir_id.local_id,
-            pprust::NodeItem(_) |
-            pprust::NodeSubItem(_) => return Ok(()),
-            pprust::NodePat(pat) => pat.hir_id.local_id
+            pprust::AnnNode::Name(_) => return Ok(()),
+            pprust::AnnNode::Expr(expr) => expr.hir_id.local_id,
+            pprust::AnnNode::Block(blk) => blk.hir_id.local_id,
+            pprust::AnnNode::Item(_) |
+            pprust::AnnNode::SubItem(_) => return Ok(()),
+            pprust::AnnNode::Pat(pat) => pat.hir_id.local_id
         };
 
         if !self.has_bitset_for_local_id(id) {
diff --git a/src/librustc_codegen_llvm/back/symbol_export.rs b/src/librustc_codegen_llvm/back/symbol_export.rs
index edb1da0b5582e..6b1b0b94fd9d7 100644
--- a/src/librustc_codegen_llvm/back/symbol_export.rs
+++ b/src/librustc_codegen_llvm/back/symbol_export.rs
@@ -13,6 +13,7 @@ use std::sync::Arc;
 
 use monomorphize::Instance;
 use rustc::hir;
+use rustc::hir::Node;
 use rustc::hir::CodegenFnAttrFlags;
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX};
 use rustc_data_structures::fingerprint::Fingerprint;
@@ -94,7 +95,7 @@ fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             // As a result, if this id is an FFI item (foreign item) then we only
             // let it through if it's included statically.
             match tcx.hir.get(node_id) {
-                hir::map::NodeForeignItem(..) => {
+                Node::ForeignItem(..) => {
                     let def_id = tcx.hir.local_def_id(node_id);
                     if tcx.is_statically_included_foreign_item(def_id) {
                         Some(def_id)
@@ -104,14 +105,14 @@ fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 }
 
                 // Only consider nodes that actually have exported symbols.
-                hir::map::NodeItem(&hir::Item {
+                Node::Item(&hir::Item {
                     node: hir::ItemKind::Static(..),
                     ..
                 }) |
-                hir::map::NodeItem(&hir::Item {
+                Node::Item(&hir::Item {
                     node: hir::ItemKind::Fn(..), ..
                 }) |
-                hir::map::NodeImplItem(&hir::ImplItem {
+                Node::ImplItem(&hir::ImplItem {
                     node: hir::ImplItemKind::Method(..),
                     ..
                 }) => {
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 6f09ebb382697..522de2f15e0a9 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -11,7 +11,7 @@
 use libc::c_uint;
 use llvm::{self, SetUnnamedAddr, True};
 use rustc::hir::def_id::DefId;
-use rustc::hir::map as hir_map;
+use rustc::hir::Node;
 use debuginfo;
 use base;
 use monomorphize::MonoItem;
@@ -135,7 +135,7 @@ pub fn get_static(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll Value {
 
         let llty = cx.layout_of(ty).llvm_type(cx);
         let (g, attrs) = match cx.tcx.hir.get(id) {
-            hir_map::NodeItem(&hir::Item {
+            Node::Item(&hir::Item {
                 ref attrs, span, node: hir::ItemKind::Static(..), ..
             }) => {
                 if declare::get_declared_value(cx, &sym[..]).is_some() {
@@ -153,7 +153,7 @@ pub fn get_static(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll Value {
                 (g, attrs)
             }
 
-            hir_map::NodeForeignItem(&hir::ForeignItem {
+            Node::ForeignItem(&hir::ForeignItem {
                 ref attrs, span, node: hir::ForeignItemKind::Static(..), ..
             }) => {
                 let fn_attrs = cx.tcx.codegen_fn_attrs(def_id);
diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs
index 4f5e76c24e379..39b88b225edc7 100644
--- a/src/librustc_codegen_utils/symbol_names.rs
+++ b/src/librustc_codegen_utils/symbol_names.rs
@@ -98,7 +98,7 @@
 //! DefPaths which are much more robust in the face of changes to the code base.
 
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
-use rustc::hir::map as hir_map;
+use rustc::hir::Node;
 use rustc::hir::CodegenFnAttrFlags;
 use rustc::hir::map::definitions::DefPathData;
 use rustc::ich::NodeIdHashingMode;
@@ -261,7 +261,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
     // FIXME(eddyb) Precompute a custom symbol name based on attributes.
     let is_foreign = if let Some(id) = node_id {
         match tcx.hir.get(id) {
-            hir_map::NodeForeignItem(_) => true,
+            Node::ForeignItem(_) => true,
             _ => false,
         }
     } else {
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 65cbee821e864..c49631515eab9 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -355,33 +355,33 @@ impl<'hir> PrinterSupport for IdentifiedAnnotation<'hir> {
 impl<'hir> pprust::PpAnn for IdentifiedAnnotation<'hir> {
     fn pre(&self, s: &mut pprust::State, node: pprust::AnnNode) -> io::Result<()> {
         match node {
-            pprust::NodeExpr(_) => s.popen(),
+            pprust::AnnNode::Expr(_) => s.popen(),
             _ => Ok(()),
         }
     }
     fn post(&self, s: &mut pprust::State, node: pprust::AnnNode) -> io::Result<()> {
         match node {
-            pprust::NodeIdent(_) |
-            pprust::NodeName(_) => Ok(()),
+            pprust::AnnNode::Ident(_) |
+            pprust::AnnNode::Name(_) => Ok(()),
 
-            pprust::NodeItem(item) => {
+            pprust::AnnNode::Item(item) => {
                 s.s.space()?;
                 s.synth_comment(item.id.to_string())
             }
-            pprust::NodeSubItem(id) => {
+            pprust::AnnNode::SubItem(id) => {
                 s.s.space()?;
                 s.synth_comment(id.to_string())
             }
-            pprust::NodeBlock(blk) => {
+            pprust::AnnNode::Block(blk) => {
                 s.s.space()?;
                 s.synth_comment(format!("block {}", blk.id))
             }
-            pprust::NodeExpr(expr) => {
+            pprust::AnnNode::Expr(expr) => {
                 s.s.space()?;
                 s.synth_comment(expr.id.to_string())?;
                 s.pclose()
             }
-            pprust::NodePat(pat) => {
+            pprust::AnnNode::Pat(pat) => {
                 s.s.space()?;
                 s.synth_comment(format!("pat {}", pat.id))
             }
@@ -414,34 +414,34 @@ impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> {
     }
     fn pre(&self, s: &mut pprust_hir::State, node: pprust_hir::AnnNode) -> io::Result<()> {
         match node {
-            pprust_hir::NodeExpr(_) => s.popen(),
+            pprust_hir::AnnNode::Expr(_) => s.popen(),
             _ => Ok(()),
         }
     }
     fn post(&self, s: &mut pprust_hir::State, node: pprust_hir::AnnNode) -> io::Result<()> {
         match node {
-            pprust_hir::NodeName(_) => Ok(()),
-            pprust_hir::NodeItem(item) => {
+            pprust_hir::AnnNode::Name(_) => Ok(()),
+            pprust_hir::AnnNode::Item(item) => {
                 s.s.space()?;
                 s.synth_comment(format!("node_id: {} hir local_id: {}",
                                         item.id, item.hir_id.local_id.0))
             }
-            pprust_hir::NodeSubItem(id) => {
+            pprust_hir::AnnNode::SubItem(id) => {
                 s.s.space()?;
                 s.synth_comment(id.to_string())
             }
-            pprust_hir::NodeBlock(blk) => {
+            pprust_hir::AnnNode::Block(blk) => {
                 s.s.space()?;
                 s.synth_comment(format!("block node_id: {} hir local_id: {}",
                                         blk.id, blk.hir_id.local_id.0))
             }
-            pprust_hir::NodeExpr(expr) => {
+            pprust_hir::AnnNode::Expr(expr) => {
                 s.s.space()?;
                 s.synth_comment(format!("node_id: {} hir local_id: {}",
                                         expr.id, expr.hir_id.local_id.0))?;
                 s.pclose()
             }
-            pprust_hir::NodePat(pat) => {
+            pprust_hir::AnnNode::Pat(pat) => {
                 s.s.space()?;
                 s.synth_comment(format!("pat node_id: {} hir local_id: {}",
                                         pat.id, pat.hir_id.local_id.0))
@@ -467,13 +467,13 @@ impl<'a> PrinterSupport for HygieneAnnotation<'a> {
 impl<'a> pprust::PpAnn for HygieneAnnotation<'a> {
     fn post(&self, s: &mut pprust::State, node: pprust::AnnNode) -> io::Result<()> {
         match node {
-            pprust::NodeIdent(&ast::Ident { name, span }) => {
+            pprust::AnnNode::Ident(&ast::Ident { name, span }) => {
                 s.s.space()?;
                 // FIXME #16420: this doesn't display the connections
                 // between syntax contexts
                 s.synth_comment(format!("{}{:?}", name.as_u32(), span.ctxt()))
             }
-            pprust::NodeName(&name) => {
+            pprust::AnnNode::Name(&name) => {
                 s.s.space()?;
                 s.synth_comment(name.as_u32().to_string())
             }
@@ -519,13 +519,13 @@ impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> {
     }
     fn pre(&self, s: &mut pprust_hir::State, node: pprust_hir::AnnNode) -> io::Result<()> {
         match node {
-            pprust_hir::NodeExpr(_) => s.popen(),
+            pprust_hir::AnnNode::Expr(_) => s.popen(),
             _ => Ok(()),
         }
     }
     fn post(&self, s: &mut pprust_hir::State, node: pprust_hir::AnnNode) -> io::Result<()> {
         match node {
-            pprust_hir::NodeExpr(expr) => {
+            pprust_hir::AnnNode::Expr(expr) => {
                 s.s.space()?;
                 s.s.word("as")?;
                 s.s.space()?;
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index 7f2da5a326ace..f715057541ffa 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -30,7 +30,7 @@ use std::vec::Vec;
 use rustc::dep_graph::{DepNode, label_strs};
 use rustc::hir;
 use rustc::hir::{ItemKind as HirItem, ImplItemKind, TraitItemKind};
-use rustc::hir::map::Node as HirNode;
+use rustc::hir::Node as HirNode;
 use rustc::hir::def_id::DefId;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::hir::intravisit;
@@ -336,7 +336,7 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
     fn auto_labels(&mut self, item_id: ast::NodeId, attr: &Attribute) -> (&'static str, Labels) {
         let node = self.tcx.hir.get(item_id);
         let (name, labels) = match node {
-            HirNode::NodeItem(item) => {
+            HirNode::Item(item) => {
                 match item.node {
                     // note: these are in the same order as hir::Item_;
                     // FIXME(michaelwoerister): do commented out ones
@@ -399,22 +399,23 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
                     _ => self.tcx.sess.span_fatal(
                         attr.span,
                         &format!(
-                            "clean/dirty auto-assertions not yet defined for NodeItem.node={:?}",
+                            "clean/dirty auto-assertions not yet defined \
+                             for Node::Item.node={:?}",
                             item.node
                         )
                     ),
                 }
             },
-            HirNode::NodeTraitItem(item) => {
+            HirNode::TraitItem(item) => {
                 match item.node {
-                    TraitItemKind::Method(..) => ("NodeTraitItem", LABELS_FN_IN_TRAIT),
+                    TraitItemKind::Method(..) => ("Node::TraitItem", LABELS_FN_IN_TRAIT),
                     TraitItemKind::Const(..) => ("NodeTraitConst", LABELS_CONST_IN_TRAIT),
                     TraitItemKind::Type(..) => ("NodeTraitType", LABELS_CONST_IN_TRAIT),
                 }
             },
-            HirNode::NodeImplItem(item) => {
+            HirNode::ImplItem(item) => {
                 match item.node {
-                    ImplItemKind::Method(..) => ("NodeImplItem", LABELS_FN_IN_IMPL),
+                    ImplItemKind::Method(..) => ("Node::ImplItem", LABELS_FN_IN_IMPL),
                     ImplItemKind::Const(..) => ("NodeImplConst", LABELS_CONST_IN_IMPL),
                     ImplItemKind::Type(..) => ("NodeImplType", LABELS_CONST_IN_IMPL),
                     ImplItemKind::Existential(..) => ("NodeImplType", LABELS_CONST_IN_IMPL),
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 92a2ea2bf2d7e..9b3dbe5bed685 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -34,7 +34,7 @@ use rustc::cfg;
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, Ty};
 use rustc::traits;
-use rustc::hir::map as hir_map;
+use hir::Node;
 use util::nodemap::NodeSet;
 use lint::{LateContext, LintContext, LintArray};
 use lint::{LintPass, LateLintPass, EarlyLintPass, EarlyContext};
@@ -427,7 +427,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
                 let real_trait = trait_ref.path.def.def_id();
                 if let Some(node_id) = cx.tcx.hir.as_local_node_id(real_trait) {
                     match cx.tcx.hir.find(node_id) {
-                        Some(hir_map::NodeItem(item)) => {
+                        Some(Node::Item(item)) => {
                             if let hir::VisibilityKind::Inherited = item.vis.node {
                                 for impl_item_ref in impl_item_refs {
                                     self.private_traits.insert(impl_item_ref.id.node_id);
@@ -981,7 +981,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
 
         fn expr_refers_to_this_fn(cx: &LateContext, fn_id: ast::NodeId, id: ast::NodeId) -> bool {
             match cx.tcx.hir.get(id) {
-                hir_map::NodeExpr(&hir::Expr { node: hir::ExprKind::Call(ref callee, _), .. }) => {
+                Node::Expr(&hir::Expr { node: hir::ExprKind::Call(ref callee, _), .. }) => {
                     let def = if let hir::ExprKind::Path(ref qpath) = callee.node {
                         cx.tables.qpath_def(qpath, callee.hir_id)
                     } else {
@@ -1004,7 +1004,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
             use rustc::ty::adjustment::*;
 
             // Ignore non-expressions.
-            let expr = if let hir_map::NodeExpr(e) = cx.tcx.hir.get(id) {
+            let expr = if let Node::Expr(e) = cx.tcx.hir.get(id) {
                 e
             } else {
                 return false;
@@ -1864,7 +1864,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestFunctions {
                     if attr.name() == "test" {
                         let parent = cx.tcx.hir.get_parent(it.id);
                         match cx.tcx.hir.find(parent) {
-                            Some(hir_map::NodeItem(hir::Item {node: hir::ItemKind::Mod(_), ..})) |
+                            Some(Node::Item(hir::Item {node: hir::ItemKind::Mod(_), ..})) |
                             None => {}
                             _ => {
                                 cx.struct_span_lint(
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index d9f6e7de5b5e4..2c410e8efb10a 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -10,7 +10,7 @@
 
 #![allow(non_snake_case)]
 
-use rustc::hir::map as hir_map;
+use rustc::hir::Node;
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
 use rustc::ty::layout::{self, IntegerExt, LayoutOf};
@@ -137,7 +137,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
                         };
                         if lit_val < min || lit_val > max {
                             let parent_id = cx.tcx.hir.get_parent_node(e.id);
-                            if let hir_map::NodeExpr(parent_expr) = cx.tcx.hir.get(parent_id) {
+                            if let Node::Expr(parent_expr) = cx.tcx.hir.get(parent_id) {
                                 if let hir::ExprKind::Cast(..) = parent_expr.node {
                                     if let ty::Char = cx.tables.expr_ty(parent_expr).sty {
                                         let mut err = cx.struct_span_lint(
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 6181eae5f602e..16d34082642bd 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -12,6 +12,7 @@
 
 use borrow_check::nll::region_infer::RegionInferenceContext;
 use rustc::hir;
+use rustc::hir::Node;
 use rustc::hir::def_id::DefId;
 use rustc::hir::map::definitions::DefPathData;
 use rustc::infer::InferCtxt;
@@ -232,7 +233,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
     ));
 
     let movable_generator = match tcx.hir.get(id) {
-        hir::map::Node::NodeExpr(&hir::Expr {
+        Node::Expr(&hir::Expr {
             node: hir::ExprKind::Closure(.., Some(hir::GeneratorMovability::Static)),
             ..
         }) => false,
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 251586cd7949d..f96ef909c0df8 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use rustc::hir;
+use rustc::hir::Node;
 use rustc::mir::{self, BindingForm, ClearCrossCrate, Local, Location, Mir};
 use rustc::mir::{Mutability, Place, Projection, ProjectionElem, Static};
 use rustc::ty::{self, TyCtxt};
@@ -246,7 +247,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                     .var_hir_id
                     .assert_crate_local();
                 let upvar_node_id = self.tcx.hir.hir_to_node_id(upvar_hir_id);
-                if let Some(hir::map::NodeBinding(pat)) = self.tcx.hir.find(upvar_node_id) {
+                if let Some(Node::Binding(pat)) = self.tcx.hir.find(upvar_node_id) {
                     if let hir::PatKind::Binding(
                         hir::BindingAnnotation::Unannotated,
                         _,
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index dc88446319cf3..f178ea8bdbab1 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -14,6 +14,7 @@ use build::scope::{CachedBlock, DropKind};
 use hair::cx::Cx;
 use hair::{LintLevel, BindingMode, PatternKind};
 use rustc::hir;
+use rustc::hir::Node;
 use rustc::hir::def_id::{DefId, LocalDefId};
 use rustc::middle::region;
 use rustc::mir::*;
@@ -40,9 +41,9 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
 
     // Figure out what primary body this item has.
     let body_id = match tcx.hir.get(id) {
-        hir::map::NodeVariant(variant) =>
+        Node::Variant(variant) =>
             return create_constructor_shim(tcx, id, &variant.node.data),
-        hir::map::NodeStructCtor(ctor) =>
+        Node::StructCtor(ctor) =>
             return create_constructor_shim(tcx, id, ctor),
 
         _ => match tcx.hir.maybe_body_owned_by(id) {
@@ -520,7 +521,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
                 by_ref,
                 mutability: Mutability::Not,
             };
-            if let Some(hir::map::NodeBinding(pat)) = tcx.hir.find(var_id) {
+            if let Some(Node::Binding(pat)) = tcx.hir.find(var_id) {
                 if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
                     decl.debug_name = ident.name;
 
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index ef21348cd3ca1..c9fd1d04e547b 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -19,6 +19,7 @@ use hair::*;
 use rustc_data_structures::indexed_vec::Idx;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::hir::map::blocks::FnLikeNode;
+use rustc::hir::Node;
 use rustc::middle::region;
 use rustc::infer::InferCtxt;
 use rustc::ty::subst::Subst;
@@ -202,7 +203,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
     pub fn pattern_from_hir(&mut self, p: &hir::Pat) -> Pattern<'tcx> {
         let tcx = self.tcx.global_tcx();
         let p = match tcx.hir.get(p.id) {
-            hir::map::NodePat(p) | hir::map::NodeBinding(p) => p,
+            Node::Pat(p) | Node::Binding(p) => p,
             node => bug!("pattern became {:?}", node)
         };
         Pattern::from_hir(tcx,
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 52ed17f86d9c0..f19c4532b47d8 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -191,7 +191,7 @@
 use rustc::hir::{self, CodegenFnAttrFlags};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 
-use rustc::hir::map as hir_map;
+use rustc::hir::Node;
 use rustc::hir::def_id::DefId;
 use rustc::mir::interpret::{AllocId, ConstValue, ScalarMaybeUndef};
 use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
@@ -740,7 +740,7 @@ fn should_monomorphize_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance:
     };
 
     return match tcx.hir.get_if_local(def_id) {
-        Some(hir_map::NodeForeignItem(..)) => {
+        Some(Node::ForeignItem(..)) => {
             false // foreign items are linked against, not codegened.
         }
         Some(_) => true,
diff --git a/src/librustc_mir/transform/add_validation.rs b/src/librustc_mir/transform/add_validation.rs
index 9061b34ae4445..6efefdaa00400 100644
--- a/src/librustc_mir/transform/add_validation.rs
+++ b/src/librustc_mir/transform/add_validation.rs
@@ -85,7 +85,7 @@ fn place_context<'a, 'tcx, D>(
 fn fn_contains_unsafe<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource) -> bool {
     use rustc::hir::intravisit::{self, Visitor, FnKind};
     use rustc::hir::map::blocks::FnLikeNode;
-    use rustc::hir::map::Node;
+    use rustc::hir::Node;
 
     /// Decide if this is an unsafe block
     fn block_is_unsafe(block: &hir::Block) -> bool {
@@ -142,13 +142,13 @@ fn fn_contains_unsafe<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource) ->
             }
             // Check if this is an unsafe block, or an item
             match node {
-                Node::NodeExpr(&hir::Expr { node: hir::ExprKind::Block(ref block, _), ..}) => {
+                Node::Expr(&hir::Expr { node: hir::ExprKind::Block(ref block, _), ..}) => {
                     if block_is_unsafe(&*block) {
                         // Found an unsafe block, we can bail out here.
                         return true;
                     }
                 }
-                Node::NodeItem(..) => {
+                Node::Item(..) => {
                     // No walking up beyond items.  This makes sure the loop always terminates.
                     break;
                 }
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index 5d284981c70af..f6006ae045ee7 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -15,6 +15,7 @@ use rustc_data_structures::sync::Lrc;
 use rustc::ty::query::Providers;
 use rustc::ty::{self, TyCtxt};
 use rustc::hir;
+use rustc::hir::Node;
 use rustc::hir::def_id::DefId;
 use rustc::lint::builtin::{SAFE_EXTERN_STATICS, SAFE_PACKED_BORROWS, UNUSED_UNSAFE};
 use rustc::mir::*;
@@ -407,7 +408,7 @@ fn is_enclosed(tcx: TyCtxt,
     if parent_id != id {
         if used_unsafe.contains(&parent_id) {
             Some(("block".to_string(), parent_id))
-        } else if let Some(hir::map::NodeItem(&hir::Item {
+        } else if let Some(Node::Item(&hir::Item {
             node: hir::ItemKind::Fn(_, header, _, _),
             ..
         })) = tcx.hir.find(parent_id) {
diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs
index 8ef20126e035f..44030c284fd81 100644
--- a/src/librustc_passes/loops.rs
+++ b/src/librustc_passes/loops.rs
@@ -13,7 +13,7 @@ use rustc::session::Session;
 
 use rustc::hir::map::Map;
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
-use rustc::hir::{self, Destination};
+use rustc::hir::{self, Node, Destination};
 use syntax::ast;
 use syntax_pos::Span;
 
@@ -115,7 +115,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
 
                 if loop_id != ast::DUMMY_NODE_ID {
                     match self.hir_map.find(loop_id).unwrap() {
-                        hir::map::NodeBlock(_) => return,
+                        Node::Block(_) => return,
                         _=> (),
                     }
                 }
@@ -158,7 +158,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
 
                 match label.target_id {
                     Ok(loop_id) => {
-                        if let hir::map::NodeBlock(block) = self.hir_map.find(loop_id).unwrap() {
+                        if let Node::Block(block) = self.hir_map.find(loop_id).unwrap() {
                             struct_span_err!(self.sess, e.span, E0696,
                                             "`continue` pointing to a labeled block")
                                 .span_label(e.span,
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index fecfc43226769..5166f69ba0330 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -25,6 +25,7 @@ extern crate syntax_pos;
 extern crate rustc_data_structures;
 
 use rustc::hir::{self, PatKind};
+use hir::Node;
 use rustc::hir::def::Def;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId};
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
@@ -659,17 +660,17 @@ impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
         match self.tcx.hir.as_local_node_id(did) {
             Some(node_id) => {
                 let vis = match self.tcx.hir.get(node_id) {
-                    hir::map::NodeItem(item) => &item.vis,
-                    hir::map::NodeForeignItem(foreign_item) => &foreign_item.vis,
-                    hir::map::NodeImplItem(impl_item) => &impl_item.vis,
-                    hir::map::NodeTraitItem(..) |
-                    hir::map::NodeVariant(..) => {
+                    Node::Item(item) => &item.vis,
+                    Node::ForeignItem(foreign_item) => &foreign_item.vis,
+                    Node::ImplItem(impl_item) => &impl_item.vis,
+                    Node::TraitItem(..) |
+                    Node::Variant(..) => {
                         return self.def_id_visibility(self.tcx.hir.get_parent_did(node_id));
                     }
-                    hir::map::NodeStructCtor(vdata) => {
+                    Node::StructCtor(vdata) => {
                         let struct_node_id = self.tcx.hir.get_parent(node_id);
                         let struct_vis = match self.tcx.hir.get(struct_node_id) {
-                            hir::map::NodeItem(item) => &item.vis,
+                            Node::Item(item) => &item.vis,
                             node => bug!("unexpected node kind: {:?}", node),
                         };
                         let mut ctor_vis
@@ -1037,7 +1038,7 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
             // .. and it corresponds to a private type in the AST (this returns
             // None for type parameters)
             match self.tcx.hir.find(node_id) {
-                Some(hir::map::NodeItem(ref item)) => !item.vis.node.is_pub(),
+                Some(Node::Item(ref item)) => !item.vis.node.is_pub(),
                 Some(_) | None => false,
             }
         } else {
@@ -1469,8 +1470,8 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
             // Non-local means public (private items can't leave their crate, modulo bugs)
             if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
                 let hir_vis = match self.tcx.hir.find(node_id) {
-                    Some(hir::map::NodeItem(item)) => &item.vis,
-                    Some(hir::map::NodeForeignItem(item)) => &item.vis,
+                    Some(Node::Item(item)) => &item.vis,
+                    Some(Node::ForeignItem(item)) => &item.vis,
                     _ => bug!("expected item of foreign item"),
                 };
 
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 8ef6cd7ae6bab..fd29dac5af8cc 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -43,7 +43,7 @@ mod sig;
 
 use rustc::hir;
 use rustc::hir::def::Def as HirDef;
-use rustc::hir::map::{Node, NodeTraitItem, NodeImplItem};
+use rustc::hir::Node;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::middle::cstore::ExternCrate;
 use rustc::session::config::CrateType;
@@ -420,7 +420,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
         let (qualname, parent_scope, decl_id, docs, attributes) =
             match self.tcx.impl_of_method(self.tcx.hir.local_def_id(id)) {
                 Some(impl_id) => match self.tcx.hir.get_if_local(impl_id) {
-                    Some(Node::NodeItem(item)) => match item.node {
+                    Some(Node::Item(item)) => match item.node {
                         hir::ItemKind::Impl(.., ref ty, _) => {
                             let mut qualname = String::from("<");
                             qualname.push_str(&self.tcx.hir.node_to_pretty_string(ty.id));
@@ -429,7 +429,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                             let mut decl_id = None;
                             let mut docs = String::new();
                             let mut attrs = vec![];
-                            if let Some(NodeImplItem(item)) = self.tcx.hir.find(id) {
+                            if let Some(Node::ImplItem(item)) = self.tcx.hir.find(id) {
                                 docs = self.docs_for_attrs(&item.attrs);
                                 attrs = item.attrs.to_vec();
                             }
@@ -471,7 +471,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                         let mut docs = String::new();
                         let mut attrs = vec![];
 
-                        if let Some(NodeTraitItem(item)) = self.tcx.hir.find(id) {
+                        if let Some(Node::TraitItem(item)) = self.tcx.hir.find(id) {
                             docs = self.docs_for_attrs(&item.attrs);
                             attrs = item.attrs.to_vec();
                         }
@@ -541,7 +541,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
         match expr.node {
             ast::ExprKind::Field(ref sub_ex, ident) => {
                 let hir_node = match self.tcx.hir.find(sub_ex.id) {
-                    Some(Node::NodeExpr(expr)) => expr,
+                    Some(Node::Expr(expr)) => expr,
                     _ => {
                         debug!(
                             "Missing or weird node for sub-expression {} in {:?}",
@@ -628,32 +628,32 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
 
     pub fn get_path_def(&self, id: NodeId) -> HirDef {
         match self.tcx.hir.get(id) {
-            Node::NodeTraitRef(tr) => tr.path.def,
+            Node::TraitRef(tr) => tr.path.def,
 
-            Node::NodeItem(&hir::Item {
+            Node::Item(&hir::Item {
                 node: hir::ItemKind::Use(ref path, _),
                 ..
             }) |
-            Node::NodeVisibility(&Spanned {
+            Node::Visibility(&Spanned {
                 node: hir::VisibilityKind::Restricted { ref path, .. }, .. }) => path.def,
 
-            Node::NodeExpr(&hir::Expr {
+            Node::Expr(&hir::Expr {
                 node: hir::ExprKind::Struct(ref qpath, ..),
                 ..
             }) |
-            Node::NodeExpr(&hir::Expr {
+            Node::Expr(&hir::Expr {
                 node: hir::ExprKind::Path(ref qpath),
                 ..
             }) |
-            Node::NodePat(&hir::Pat {
+            Node::Pat(&hir::Pat {
                 node: hir::PatKind::Path(ref qpath),
                 ..
             }) |
-            Node::NodePat(&hir::Pat {
+            Node::Pat(&hir::Pat {
                 node: hir::PatKind::Struct(ref qpath, ..),
                 ..
             }) |
-            Node::NodePat(&hir::Pat {
+            Node::Pat(&hir::Pat {
                 node: hir::PatKind::TupleStruct(ref qpath, ..),
                 ..
             }) => {
@@ -661,12 +661,12 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                 self.tables.qpath_def(qpath, hir_id)
             }
 
-            Node::NodeBinding(&hir::Pat {
+            Node::Binding(&hir::Pat {
                 node: hir::PatKind::Binding(_, canonical_id, ..),
                 ..
             }) => HirDef::Local(canonical_id),
 
-            Node::NodeTy(ty) => if let hir::Ty {
+            Node::Ty(ty) => if let hir::Ty {
                 node: hir::TyKind::Path(ref qpath),
                 ..
             } = *ty
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index b0b2799c793b2..85646b9ab675a 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -17,7 +17,7 @@ use syntax::util::parser::PREC_POSTFIX;
 use syntax_pos::Span;
 use rustc::hir;
 use rustc::hir::def::Def;
-use rustc::hir::map::{NodeItem, NodeExpr};
+use rustc::hir::Node;
 use rustc::hir::{Item, ItemKind, print};
 use rustc::ty::{self, Ty, AssociatedItem};
 use rustc::ty::adjustment::AllowTwoPhase;
@@ -199,13 +199,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = expr.node {
             if let hir::def::Def::Local(id) = path.def {
                 let parent = self.tcx.hir.get_parent_node(id);
-                if let Some(NodeExpr(hir::Expr {
+                if let Some(Node::Expr(hir::Expr {
                     id,
                     node: hir::ExprKind::Closure(_, decl, ..),
                     ..
                 })) = self.tcx.hir.find(parent) {
                     let parent = self.tcx.hir.get_parent_node(*id);
-                    if let (Some(NodeExpr(hir::Expr {
+                    if let (Some(Node::Expr(hir::Expr {
                         node: hir::ExprKind::MethodCall(path, span, expr),
                         ..
                     })), 1) = (self.tcx.hir.find(parent), decl.inputs.len()) {
@@ -377,7 +377,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         match self.tcx.hir.find(parent_id) {
             Some(parent) => {
                 // Shouldn't suggest `.into()` on `const`s.
-                if let NodeItem(Item { node: ItemKind::Const(_, _), .. }) = parent {
+                if let Node::Item(Item { node: ItemKind::Const(_, _), .. }) = parent {
                     // FIXME(estebank): modify once we decide to suggest `as` casts
                     return false;
                 }
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 14e36ba3429ec..abc32ed2ea043 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -13,6 +13,7 @@
 
 use check::FnCtxt;
 use rustc::hir::map as hir_map;
+use hir::Node;
 use rustc_data_structures::sync::Lrc;
 use rustc::ty::{self, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable};
 use hir::def::Def;
@@ -275,7 +276,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                         );
 
                                         match (filename, parent_node) {
-                                            (FileName::Real(_), hir_map::NodeLocal(hir::Local {
+                                            (FileName::Real(_), Node::Local(hir::Local {
                                                 source: hir::LocalSource::Normal,
                                                 ty,
                                                 ..
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 2b33f28934630..bbb45c04e4e98 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -132,7 +132,7 @@ use syntax_pos::{self, BytePos, Span, MultiSpan};
 
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
-use rustc::hir::map::Node;
+use rustc::hir::Node;
 use rustc::hir::{self, PatKind, ItemKind};
 use rustc::middle::lang_items;
 
@@ -761,7 +761,7 @@ fn primary_body_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                              -> Option<(hir::BodyId, Option<&'tcx hir::FnDecl>)>
 {
     match tcx.hir.get(id) {
-        hir::map::NodeItem(item) => {
+        Node::Item(item) => {
             match item.node {
                 hir::ItemKind::Const(_, body) |
                 hir::ItemKind::Static(_, _, body) =>
@@ -772,7 +772,7 @@ fn primary_body_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     None,
             }
         }
-        hir::map::NodeTraitItem(item) => {
+        Node::TraitItem(item) => {
             match item.node {
                 hir::TraitItemKind::Const(_, Some(body)) =>
                     Some((body, None)),
@@ -782,7 +782,7 @@ fn primary_body_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     None,
             }
         }
-        hir::map::NodeImplItem(item) => {
+        Node::ImplItem(item) => {
             match item.node {
                 hir::ImplItemKind::Const(_, body) =>
                     Some((body, None)),
@@ -792,7 +792,7 @@ fn primary_body_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     None,
             }
         }
-        hir::map::NodeAnonConst(constant) => Some((constant.body, None)),
+        Node::AnonConst(constant) => Some((constant.body, None)),
         _ => None,
     }
 }
@@ -1167,7 +1167,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
                         );
                     }
 
-                    if let Node::NodeItem(item) = fcx.tcx.hir.get(fn_id) {
+                    if let Node::Item(item) = fcx.tcx.hir.get(fn_id) {
                         if let ItemKind::Fn(_, _, ref generics, _) = item.node {
                             if !generics.params.is_empty() {
                                 fcx.tcx.sess.span_err(
@@ -1214,7 +1214,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
                         );
                     }
 
-                    if let Node::NodeItem(item) = fcx.tcx.hir.get(fn_id) {
+                    if let Node::Item(item) = fcx.tcx.hir.get(fn_id) {
                         if let ItemKind::Fn(_, _, ref generics, _) = item.node {
                             if !generics.params.is_empty() {
                                 fcx.tcx.sess.span_err(
@@ -4646,7 +4646,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         if let Some(fn_id) = self.tcx.hir.get_return_block(blk_id) {
             let parent = self.tcx.hir.get(fn_id);
 
-            if let Node::NodeItem(&hir::Item {
+            if let Node::Item(&hir::Item {
                 name, node: hir::ItemKind::Fn(ref decl, ..), ..
             }) = parent {
                 decl.clone().and_then(|decl| {
@@ -4655,7 +4655,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     // but it will still present it as the reason for the expected type.
                     Some((decl, name != Symbol::intern("main")))
                 })
-            } else if let Node::NodeTraitItem(&hir::TraitItem {
+            } else if let Node::TraitItem(&hir::TraitItem {
                 node: hir::TraitItemKind::Method(hir::MethodSig {
                     ref decl, ..
                 }, ..), ..
@@ -4663,7 +4663,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 decl.clone().and_then(|decl| {
                     Some((decl, true))
                 })
-            } else if let Node::NodeImplItem(&hir::ImplItem {
+            } else if let Node::ImplItem(&hir::ImplItem {
                 node: hir::ImplItemKind::Method(hir::MethodSig {
                     ref decl, ..
                 }, ..), ..
@@ -5174,7 +5174,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // If our calling expression is indeed the function itself, we're good!
         // If not, generate an error that this can only be called directly.
         match self.tcx.hir.get(self.tcx.hir.get_parent_node(node_id)) {
-            Node::NodeExpr(expr) => {
+            Node::Expr(expr) => {
                 match expr.node {
                     hir::ExprKind::Call(ref callee, ..) => {
                         if callee.id == node_id {
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index d01e7dbdfefe5..efc35fad820c8 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -23,7 +23,7 @@ use rustc::ty::util::CopyImplementationError;
 use rustc::infer;
 
 use rustc::hir::def_id::DefId;
-use rustc::hir::map as hir_map;
+use hir::Node;
 use rustc::hir::{self, ItemKind};
 
 pub fn check_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_def_id: DefId) {
@@ -60,7 +60,7 @@ fn visit_implementation_of_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did:
             // Destructors only work on nominal types.
             if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_did) {
                 match tcx.hir.find(impl_node_id) {
-                    Some(hir_map::NodeItem(item)) => {
+                    Some(Node::Item(item)) => {
                         let span = match item.node {
                             ItemKind::Impl(.., ref ty, _) => ty.span,
                             _ => item.span,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 79061c250f7d6..a42667ab45fc8 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -50,10 +50,11 @@ use syntax::symbol::{keywords, Symbol};
 use syntax_pos::{Span, DUMMY_SP};
 
 use rustc::hir::def::{CtorKind, Def};
+use rustc::hir::Node;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc::hir::GenericParamKind;
-use rustc::hir::{self, map as hir_map, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety};
+use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety};
 
 ///////////////////////////////////////////////////////////////////////////
 // Main entry point
@@ -238,7 +239,6 @@ fn type_param_predicates<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     (item_def_id, def_id): (DefId, DefId),
 ) -> ty::GenericPredicates<'tcx> {
-    use rustc::hir::map::*;
     use rustc::hir::*;
 
     // In the AST, bounds can derive from two places. Either
@@ -272,11 +272,11 @@ fn type_param_predicates<'a, 'tcx>(
 
     let item_node_id = tcx.hir.as_local_node_id(item_def_id).unwrap();
     let ast_generics = match tcx.hir.get(item_node_id) {
-        NodeTraitItem(item) => &item.generics,
+        Node::TraitItem(item) => &item.generics,
 
-        NodeImplItem(item) => &item.generics,
+        Node::ImplItem(item) => &item.generics,
 
-        NodeItem(item) => {
+        Node::Item(item) => {
             match item.node {
                 ItemKind::Fn(.., ref generics, _)
                 | ItemKind::Impl(_, _, _, ref generics, ..)
@@ -302,7 +302,7 @@ fn type_param_predicates<'a, 'tcx>(
             }
         }
 
-        NodeForeignItem(item) => match item.node {
+        Node::ForeignItem(item) => match item.node {
             ForeignItemKind::Fn(_, _, ref generics) => generics,
             _ => return result,
         },
@@ -595,12 +595,11 @@ fn convert_struct_variant<'a, 'tcx>(
 }
 
 fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::AdtDef {
-    use rustc::hir::map::*;
     use rustc::hir::*;
 
     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
     let item = match tcx.hir.get(node_id) {
-        NodeItem(item) => item,
+        Node::Item(item) => item,
         _ => bug!(),
     };
 
@@ -671,7 +670,7 @@ fn super_predicates_of<'a, 'tcx>(
     let trait_node_id = tcx.hir.as_local_node_id(trait_def_id).unwrap();
 
     let item = match tcx.hir.get(trait_node_id) {
-        hir_map::NodeItem(item) => item,
+        Node::Item(item) => item,
         _ => bug!("trait_node_id {} is not an item", trait_node_id),
     };
 
@@ -740,7 +739,7 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::
 
 fn has_late_bound_regions<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    node: hir_map::Node<'tcx>,
+    node: Node<'tcx>,
 ) -> Option<Span> {
     struct LateBoundRegionsDetector<'a, 'tcx: 'a> {
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -826,25 +825,25 @@ fn has_late_bound_regions<'a, 'tcx>(
     }
 
     match node {
-        hir_map::NodeTraitItem(item) => match item.node {
+        Node::TraitItem(item) => match item.node {
             hir::TraitItemKind::Method(ref sig, _) => {
                 has_late_bound_regions(tcx, &item.generics, &sig.decl)
             }
             _ => None,
         },
-        hir_map::NodeImplItem(item) => match item.node {
+        Node::ImplItem(item) => match item.node {
             hir::ImplItemKind::Method(ref sig, _) => {
                 has_late_bound_regions(tcx, &item.generics, &sig.decl)
             }
             _ => None,
         },
-        hir_map::NodeForeignItem(item) => match item.node {
+        Node::ForeignItem(item) => match item.node {
             hir::ForeignItemKind::Fn(ref fn_decl, _, ref generics) => {
                 has_late_bound_regions(tcx, generics, fn_decl)
             }
             _ => None,
         },
-        hir_map::NodeItem(item) => match item.node {
+        Node::Item(item) => match item.node {
             hir::ItemKind::Fn(ref fn_decl, .., ref generics, _) => {
                 has_late_bound_regions(tcx, generics, fn_decl)
             }
@@ -855,22 +854,22 @@ fn has_late_bound_regions<'a, 'tcx>(
 }
 
 fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Generics {
-    use rustc::hir::map::*;
     use rustc::hir::*;
 
     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
 
     let node = tcx.hir.get(node_id);
     let parent_def_id = match node {
-        NodeImplItem(_) | NodeTraitItem(_) | NodeVariant(_) | NodeStructCtor(_) | NodeField(_) => {
+        Node::ImplItem(_) | Node::TraitItem(_) | Node::Variant(_)
+        | Node::StructCtor(_) | Node::Field(_) => {
             let parent_id = tcx.hir.get_parent(node_id);
             Some(tcx.hir.local_def_id(parent_id))
         }
-        NodeExpr(&hir::Expr {
+        Node::Expr(&hir::Expr {
             node: hir::ExprKind::Closure(..),
             ..
         }) => Some(tcx.closure_base_def_id(def_id)),
-        NodeItem(item) => match item.node {
+        Node::Item(item) => match item.node {
             ItemKind::Existential(hir::ExistTy { impl_trait_fn, .. }) => impl_trait_fn,
             _ => None,
         },
@@ -882,11 +881,11 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty
 
     let no_generics = hir::Generics::empty();
     let ast_generics = match node {
-        NodeTraitItem(item) => &item.generics,
+        Node::TraitItem(item) => &item.generics,
 
-        NodeImplItem(item) => &item.generics,
+        Node::ImplItem(item) => &item.generics,
 
-        NodeItem(item) => {
+        Node::Item(item) => {
             match item.node {
                 ItemKind::Fn(.., ref generics, _) | ItemKind::Impl(_, _, _, ref generics, ..) => {
                     generics
@@ -929,7 +928,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty
             }
         }
 
-        NodeForeignItem(item) => match item.node {
+        Node::ForeignItem(item) => match item.node {
             ForeignItemKind::Static(..) => &no_generics,
             ForeignItemKind::Fn(_, _, ref generics) => generics,
             ForeignItemKind::Type => &no_generics,
@@ -1024,7 +1023,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty
     // provide junk type parameter defs - the only place that
     // cares about anything but the length is instantiation,
     // and we don't do that for closures.
-    if let NodeExpr(&hir::Expr {
+    if let Node::Expr(&hir::Expr {
         node: hir::ExprKind::Closure(.., gen),
         ..
     }) = node
@@ -1094,7 +1093,6 @@ fn report_assoc_ty_on_inherent_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span:
 }
 
 fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
-    use rustc::hir::map::*;
     use rustc::hir::*;
 
     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
@@ -1102,7 +1100,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
     let icx = ItemCtxt::new(tcx, def_id);
 
     match tcx.hir.get(node_id) {
-        NodeTraitItem(item) => match item.node {
+        Node::TraitItem(item) => match item.node {
             TraitItemKind::Method(..) => {
                 let substs = Substs::identity_for_item(tcx, def_id);
                 tcx.mk_fn_def(def_id, substs)
@@ -1113,7 +1111,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
             }
         },
 
-        NodeImplItem(item) => match item.node {
+        Node::ImplItem(item) => match item.node {
             ImplItemKind::Method(..) => {
                 let substs = Substs::identity_for_item(tcx, def_id);
                 tcx.mk_fn_def(def_id, substs)
@@ -1141,7 +1139,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
             }
         },
 
-        NodeItem(item) => {
+        Node::Item(item) => {
             match item.node {
                 ItemKind::Static(ref t, ..)
                 | ItemKind::Const(ref t, _)
@@ -1199,7 +1197,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
             }
         }
 
-        NodeForeignItem(foreign_item) => match foreign_item.node {
+        Node::ForeignItem(foreign_item) => match foreign_item.node {
             ForeignItemKind::Fn(..) => {
                 let substs = Substs::identity_for_item(tcx, def_id);
                 tcx.mk_fn_def(def_id, substs)
@@ -1208,8 +1206,8 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
             ForeignItemKind::Type => tcx.mk_foreign(def_id),
         },
 
-        NodeStructCtor(&ref def)
-        | NodeVariant(&Spanned {
+        Node::StructCtor(&ref def)
+        | Node::Variant(&Spanned {
             node: hir::VariantKind { data: ref def, .. },
             ..
         }) => match *def {
@@ -1222,9 +1220,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
             }
         },
 
-        NodeField(field) => icx.to_ty(&field.ty),
+        Node::Field(field) => icx.to_ty(&field.ty),
 
-        NodeExpr(&hir::Expr {
+        Node::Expr(&hir::Expr {
             node: hir::ExprKind::Closure(.., gen),
             ..
         }) => {
@@ -1240,16 +1238,16 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
             tcx.mk_closure(def_id, substs)
         }
 
-        NodeAnonConst(_) => match tcx.hir.get(tcx.hir.get_parent_node(node_id)) {
-            NodeTy(&hir::Ty {
+        Node::AnonConst(_) => match tcx.hir.get(tcx.hir.get_parent_node(node_id)) {
+            Node::Ty(&hir::Ty {
                 node: hir::TyKind::Array(_, ref constant),
                 ..
             })
-            | NodeTy(&hir::Ty {
+            | Node::Ty(&hir::Ty {
                 node: hir::TyKind::Typeof(ref constant),
                 ..
             })
-            | NodeExpr(&hir::Expr {
+            | Node::Expr(&hir::Expr {
                 node: ExprKind::Repeat(_, ref constant),
                 ..
             }) if constant.id == node_id =>
@@ -1257,7 +1255,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
                 tcx.types.usize
             }
 
-            NodeVariant(&Spanned {
+            Node::Variant(&Spanned {
                 node:
                     VariantKind {
                         disr_expr: Some(ref e),
@@ -1277,7 +1275,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
             }
         },
 
-        NodeGenericParam(param) => match param.kind {
+        Node::GenericParam(param) => match param.kind {
             hir::GenericParamKind::Type {
                 default: Some(ref ty),
                 ..
@@ -1295,7 +1293,6 @@ fn find_existential_constraints<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     def_id: DefId,
 ) -> ty::Ty<'tcx> {
-    use rustc::hir::map::*;
     use rustc::hir::*;
 
     struct ConstraintLocator<'a, 'tcx: 'a> {
@@ -1375,9 +1372,9 @@ fn find_existential_constraints<'a, 'tcx>(
     } else {
         trace!("parent: {:?}", tcx.hir.get(parent));
         match tcx.hir.get(parent) {
-            NodeItem(ref it) => intravisit::walk_item(&mut locator, it),
-            NodeImplItem(ref it) => intravisit::walk_impl_item(&mut locator, it),
-            NodeTraitItem(ref it) => intravisit::walk_trait_item(&mut locator, it),
+            Node::Item(ref it) => intravisit::walk_item(&mut locator, it),
+            Node::ImplItem(ref it) => intravisit::walk_impl_item(&mut locator, it),
+            Node::TraitItem(ref it) => intravisit::walk_trait_item(&mut locator, it),
             other => bug!(
                 "{:?} is not a valid parent of an existential type item",
                 other
@@ -1395,29 +1392,29 @@ fn find_existential_constraints<'a, 'tcx>(
 }
 
 fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::PolyFnSig<'tcx> {
-    use rustc::hir::map::*;
     use rustc::hir::*;
+    use rustc::hir::Node::*;
 
     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
 
     let icx = ItemCtxt::new(tcx, def_id);
 
     match tcx.hir.get(node_id) {
-        NodeTraitItem(hir::TraitItem {
+        TraitItem(hir::TraitItem {
             node: TraitItemKind::Method(sig, _),
             ..
         })
-        | NodeImplItem(hir::ImplItem {
+        | ImplItem(hir::ImplItem {
             node: ImplItemKind::Method(sig, _),
             ..
         }) => AstConv::ty_of_fn(&icx, sig.header.unsafety, sig.header.abi, &sig.decl),
 
-        NodeItem(hir::Item {
+        Item(hir::Item {
             node: ItemKind::Fn(decl, header, _, _),
             ..
         }) => AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl),
 
-        NodeForeignItem(&hir::ForeignItem {
+        ForeignItem(&hir::ForeignItem {
             node: ForeignItemKind::Fn(ref fn_decl, _, _),
             ..
         }) => {
@@ -1425,8 +1422,8 @@ fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::PolyFnSig
             compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
         }
 
-        NodeStructCtor(&VariantData::Tuple(ref fields, _))
-        | NodeVariant(&Spanned {
+        StructCtor(&VariantData::Tuple(ref fields, _))
+        | Variant(&Spanned {
             node:
                 hir::VariantKind {
                     data: VariantData::Tuple(ref fields, _),
@@ -1447,7 +1444,7 @@ fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::PolyFnSig
             ))
         }
 
-        NodeExpr(&hir::Expr {
+        Expr(&hir::Expr {
             node: hir::ExprKind::Closure(..),
             ..
         }) => {
@@ -1625,7 +1622,6 @@ fn explicit_predicates_of<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     def_id: DefId,
 ) -> ty::GenericPredicates<'tcx> {
-    use rustc::hir::map::*;
     use rustc::hir::*;
 
     debug!("explicit_predicates_of(def_id={:?})", def_id);
@@ -1642,9 +1638,9 @@ fn explicit_predicates_of<'a, 'tcx>(
     let mut predicates = vec![];
 
     let ast_generics = match node {
-        NodeTraitItem(item) => &item.generics,
+        Node::TraitItem(item) => &item.generics,
 
-        NodeImplItem(item) => match item.node {
+        Node::ImplItem(item) => match item.node {
             ImplItemKind::Existential(ref bounds) => {
                 let substs = Substs::identity_for_item(tcx, def_id);
                 let anon_ty = tcx.mk_anon(def_id, substs);
@@ -1664,7 +1660,7 @@ fn explicit_predicates_of<'a, 'tcx>(
             _ => &item.generics,
         },
 
-        NodeItem(item) => {
+        Node::Item(item) => {
             match item.node {
                 ItemKind::Impl(_, _, defaultness, ref generics, ..) => {
                     if defaultness.is_default() {
@@ -1716,7 +1712,7 @@ fn explicit_predicates_of<'a, 'tcx>(
             }
         }
 
-        NodeForeignItem(item) => match item.node {
+        Node::ForeignItem(item) => match item.node {
             ForeignItemKind::Static(..) => &no_generics,
             ForeignItemKind::Fn(_, _, ref generics) => generics,
             ForeignItemKind::Type => &no_generics,
@@ -1876,7 +1872,7 @@ fn explicit_predicates_of<'a, 'tcx>(
     // before uses of `U`.  This avoids false ambiguity errors
     // in trait checking. See `setup_constraining_predicates`
     // for details.
-    if let NodeItem(&Item {
+    if let Node::Item(&Item {
         node: ItemKind::Impl(..),
         ..
     }) = node
@@ -2026,7 +2022,7 @@ fn compute_sig_of_foreign_fn_decl<'a, 'tcx>(
 
 fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool {
     match tcx.hir.get_if_local(def_id) {
-        Some(hir_map::NodeForeignItem(..)) => true,
+        Some(Node::ForeignItem(..)) => true,
         Some(_) => false,
         _ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id),
     }
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index d4460bd1168eb..e31ae8eb8c7ae 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -103,7 +103,7 @@ use rustc::middle;
 use rustc::session;
 use rustc::util;
 
-use hir::map as hir_map;
+use hir::Node;
 use rustc::infer::InferOk;
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, Ty, TyCtxt};
@@ -187,7 +187,7 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     match main_t.sty {
         ty::FnDef(..) => {
             match tcx.hir.find(main_id) {
-                Some(hir_map::NodeItem(it)) => {
+                Some(Node::Item(it)) => {
                     match it.node {
                         hir::ItemKind::Fn(.., ref generics, _) => {
                             let mut error = false;
@@ -259,7 +259,7 @@ fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     match start_t.sty {
         ty::FnDef(..) => {
             match tcx.hir.find(start_id) {
-                Some(hir_map::NodeItem(it)) => {
+                Some(Node::Item(it)) => {
                     match it.node {
                         hir::ItemKind::Fn(.., ref generics, _) => {
                             let mut error = false;
diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs
index 46934d7bca711..092e4d62e2e9f 100644
--- a/src/librustc_typeck/outlives/implicit_infer.rs
+++ b/src/librustc_typeck/outlives/implicit_infer.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use rustc::hir;
+use hir::Node;
 use rustc::hir::def_id::DefId;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::ty::subst::{Kind, Subst, UnpackedKind};
@@ -70,7 +71,7 @@ impl<'cx, 'tcx> ItemLikeVisitor<'tcx> for InferVisitor<'cx, 'tcx> {
             .as_local_node_id(item_did)
             .expect("expected local def-id");
         let item = match self.tcx.hir.get(node_id) {
-            hir::map::NodeItem(item) => item,
+            Node::Item(item) => item,
             _ => bug!(),
         };
 
diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs
index 1b6d51d2b0280..63a424936eb4c 100644
--- a/src/librustc_typeck/outlives/mod.rs
+++ b/src/librustc_typeck/outlives/mod.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use hir::map as hir_map;
+use hir::Node;
 use rustc::hir;
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::ty::query::Providers;
@@ -40,7 +40,7 @@ fn inferred_outlives_of<'a, 'tcx>(
         .expect("expected local def-id");
 
     match tcx.hir.get(id) {
-        hir_map::NodeItem(item) => match item.node {
+        Node::Item(item) => match item.node {
             hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..) => {
                 let crate_map = tcx.inferred_outlives_crate(LOCAL_CRATE);
 
diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs
index 3d70550c1dfb2..aaa0fd8e099ef 100644
--- a/src/librustc_typeck/variance/mod.rs
+++ b/src/librustc_typeck/variance/mod.rs
@@ -15,6 +15,7 @@
 
 use arena;
 use rustc::hir;
+use hir::Node;
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::ty::{self, CrateVariancesMap, TyCtxt};
 use rustc::ty::query::Providers;
@@ -61,7 +62,7 @@ fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
         span_bug!(tcx.hir.span(id), "asked to compute variance for wrong kind of item")
     };
     match tcx.hir.get(id) {
-        hir::map::NodeItem(item) => match item.node {
+        Node::Item(item) => match item.node {
             hir::ItemKind::Enum(..) |
             hir::ItemKind::Struct(..) |
             hir::ItemKind::Union(..) |
@@ -70,25 +71,25 @@ fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
             _ => unsupported()
         },
 
-        hir::map::NodeTraitItem(item) => match item.node {
+        Node::TraitItem(item) => match item.node {
             hir::TraitItemKind::Method(..) => {}
 
             _ => unsupported()
         },
 
-        hir::map::NodeImplItem(item) => match item.node {
+        Node::ImplItem(item) => match item.node {
             hir::ImplItemKind::Method(..) => {}
 
             _ => unsupported()
         },
 
-        hir::map::NodeForeignItem(item) => match item.node {
+        Node::ForeignItem(item) => match item.node {
             hir::ForeignItemKind::Fn(..) => {}
 
             _ => unsupported()
         },
 
-        hir::map::NodeVariant(_) | hir::map::NodeStructCtor(_) => {}
+        Node::Variant(_) | Node::StructCtor(_) => {}
 
         _ => unsupported()
     }
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 15a94b8adfcb2..451e24d6c0dc9 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -18,7 +18,7 @@ use syntax::attr;
 use syntax::source_map::Spanned;
 use syntax_pos::{self, Span};
 
-use rustc::hir::map as hir_map;
+use rustc::hir::Node;
 use rustc::hir::def::Def;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::middle::privacy::AccessLevel;
@@ -295,7 +295,7 @@ impl<'a, 'tcx, 'rcx, 'cstore> RustdocVisitor<'a, 'tcx, 'rcx, 'cstore> {
         if !self.view_item_stack.insert(def_node_id) { return false }
 
         let ret = match tcx.hir.get(def_node_id) {
-            hir_map::NodeItem(&hir::Item { node: hir::ItemKind::Mod(ref m), .. }) if glob => {
+            Node::Item(&hir::Item { node: hir::ItemKind::Mod(ref m), .. }) if glob => {
                 let prev = mem::replace(&mut self.inlining, true);
                 for i in &m.item_ids {
                     let i = self.cx.tcx.hir.expect_item(i.id);
@@ -304,13 +304,13 @@ impl<'a, 'tcx, 'rcx, 'cstore> RustdocVisitor<'a, 'tcx, 'rcx, 'cstore> {
                 self.inlining = prev;
                 true
             }
-            hir_map::NodeItem(it) if !glob => {
+            Node::Item(it) if !glob => {
                 let prev = mem::replace(&mut self.inlining, true);
                 self.visit_item(it, renamed, om);
                 self.inlining = prev;
                 true
             }
-            hir_map::NodeForeignItem(it) if !glob => {
+            Node::ForeignItem(it) if !glob => {
                 // generate a fresh `extern {}` block if we want to inline a foreign item.
                 om.foreigns.push(hir::ForeignMod {
                     abi: tcx.hir.get_foreign_abi(it.id),
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index be63c8f060a8e..e78e1afe3a402 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub use self::AnnNode::*;
-
 use rustc_target::spec::abi::{self, Abi};
 use ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
 use ast::{SelfKind, GenericBound, TraitBoundModifier};
@@ -36,13 +34,13 @@ use std::iter::Peekable;
 use std::vec;
 
 pub enum AnnNode<'a> {
-    NodeIdent(&'a ast::Ident),
-    NodeName(&'a ast::Name),
-    NodeBlock(&'a ast::Block),
-    NodeItem(&'a ast::Item),
-    NodeSubItem(ast::NodeId),
-    NodeExpr(&'a ast::Expr),
-    NodePat(&'a ast::Pat),
+    Ident(&'a ast::Ident),
+    Name(&'a ast::Name),
+    Block(&'a ast::Block),
+    Item(&'a ast::Item),
+    SubItem(ast::NodeId),
+    Expr(&'a ast::Expr),
+    Pat(&'a ast::Pat),
 }
 
 pub trait PpAnn {
@@ -1196,7 +1194,7 @@ impl<'a> State<'a> {
         self.hardbreak_if_not_bol()?;
         self.maybe_print_comment(item.span.lo())?;
         self.print_outer_attributes(&item.attrs)?;
-        self.ann.pre(self, NodeItem(item))?;
+        self.ann.pre(self, AnnNode::Item(item))?;
         match item.node {
             ast::ItemKind::ExternCrate(orig_name) => {
                 self.head(&visibility_qualified(&item.vis, "extern crate"))?;
@@ -1439,7 +1437,7 @@ impl<'a> State<'a> {
                 self.end()?;
             }
         }
-        self.ann.post(self, NodeItem(item))
+        self.ann.post(self, AnnNode::Item(item))
     }
 
     fn print_trait_ref(&mut self, t: &ast::TraitRef) -> io::Result<()> {
@@ -1596,7 +1594,7 @@ impl<'a> State<'a> {
 
     pub fn print_trait_item(&mut self, ti: &ast::TraitItem)
                             -> io::Result<()> {
-        self.ann.pre(self, NodeSubItem(ti.id))?;
+        self.ann.pre(self, AnnNode::SubItem(ti.id))?;
         self.hardbreak_if_not_bol()?;
         self.maybe_print_comment(ti.span.lo())?;
         self.print_outer_attributes(&ti.attrs)?;
@@ -1638,11 +1636,11 @@ impl<'a> State<'a> {
                 }
             }
         }
-        self.ann.post(self, NodeSubItem(ti.id))
+        self.ann.post(self, AnnNode::SubItem(ti.id))
     }
 
     pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> io::Result<()> {
-        self.ann.pre(self, NodeSubItem(ii.id))?;
+        self.ann.pre(self, AnnNode::SubItem(ii.id))?;
         self.hardbreak_if_not_bol()?;
         self.maybe_print_comment(ii.span.lo())?;
         self.print_outer_attributes(&ii.attrs)?;
@@ -1672,7 +1670,7 @@ impl<'a> State<'a> {
                 }
             }
         }
-        self.ann.post(self, NodeSubItem(ii.id))
+        self.ann.post(self, AnnNode::SubItem(ii.id))
     }
 
     pub fn print_stmt(&mut self, st: &ast::Stmt) -> io::Result<()> {
@@ -1756,7 +1754,7 @@ impl<'a> State<'a> {
             BlockCheckMode::Default => ()
         }
         self.maybe_print_comment(blk.span.lo())?;
-        self.ann.pre(self, NodeBlock(blk))?;
+        self.ann.pre(self, AnnNode::Block(blk))?;
         self.bopen()?;
 
         self.print_inner_attributes(attrs)?;
@@ -1774,7 +1772,7 @@ impl<'a> State<'a> {
         }
 
         self.bclose_maybe_open(blk.span, indented, close_box)?;
-        self.ann.post(self, NodeBlock(blk))
+        self.ann.post(self, AnnNode::Block(blk))
     }
 
     fn print_else(&mut self, els: Option<&ast::Expr>) -> io::Result<()> {
@@ -2065,7 +2063,7 @@ impl<'a> State<'a> {
         }
 
         self.ibox(INDENT_UNIT)?;
-        self.ann.pre(self, NodeExpr(expr))?;
+        self.ann.pre(self, AnnNode::Expr(expr))?;
         match expr.node {
             ast::ExprKind::Box(ref expr) => {
                 self.word_space("box")?;
@@ -2385,7 +2383,7 @@ impl<'a> State<'a> {
                 self.print_block_with_attrs(blk, attrs)?
             }
         }
-        self.ann.post(self, NodeExpr(expr))?;
+        self.ann.post(self, AnnNode::Expr(expr))?;
         self.end()
     }
 
@@ -2404,7 +2402,7 @@ impl<'a> State<'a> {
         } else {
             self.s.word(&ident.as_str())?;
         }
-        self.ann.post(self, NodeIdent(&ident))
+        self.ann.post(self, AnnNode::Ident(&ident))
     }
 
     pub fn print_usize(&mut self, i: usize) -> io::Result<()> {
@@ -2413,7 +2411,7 @@ impl<'a> State<'a> {
 
     pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> {
         self.s.word(&name.as_str())?;
-        self.ann.post(self, NodeName(&name))
+        self.ann.post(self, AnnNode::Name(&name))
     }
 
     pub fn print_for_decl(&mut self, loc: &ast::Local,
@@ -2537,7 +2535,7 @@ impl<'a> State<'a> {
 
     pub fn print_pat(&mut self, pat: &ast::Pat) -> io::Result<()> {
         self.maybe_print_comment(pat.span.lo())?;
-        self.ann.pre(self, NodePat(pat))?;
+        self.ann.pre(self, AnnNode::Pat(pat))?;
         /* Pat isn't normalized, but the beauty of it
          is that it doesn't matter */
         match pat.node {
@@ -2675,7 +2673,7 @@ impl<'a> State<'a> {
             }
             PatKind::Mac(ref m) => self.print_mac(m)?,
         }
-        self.ann.post(self, NodePat(pat))
+        self.ann.post(self, AnnNode::Pat(pat))
     }
 
     fn print_pats(&mut self, pats: &[P<ast::Pat>]) -> io::Result<()> {
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs
index adcd2d605e3ce..f525e0f082a44 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs
+++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs
@@ -27,6 +27,7 @@ use syntax::symbol::Symbol;
 use rustc::hir;
 use rustc::hir::intravisit;
 use rustc::hir::map as hir_map;
+use hir::Node;
 use rustc::lint::{LateContext, LintPass, LintArray, LateLintPass, LintContext};
 use rustc::ty;
 use syntax::{ast, source_map};
@@ -58,7 +59,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingWhitelistedAttrPass {
                 id: ast::NodeId) {
 
         let item = match cx.tcx.hir.get(id) {
-            hir_map::Node::NodeItem(item) => item,
+            Node::Item(item) => item,
             _ => cx.tcx.hir.expect_item(cx.tcx.hir.get_parent(id)),
         };