about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2017-08-08 14:34:37 +0200
committerMichael Woerister <michaelwoerister@posteo>2017-08-11 12:11:38 +0200
commit4dcc3a4aae48d4ce856a2db2a1234af190fb2eb8 (patch)
tree41f637fe4c4611cc7e8c58f72479edae2cb6e197 /src
parenta8cf6cc6db13efea1057dfefbe9e6b583b23ea4f (diff)
downloadrust-4dcc3a4aae48d4ce856a2db2a1234af190fb2eb8.tar.gz
rust-4dcc3a4aae48d4ce856a2db2a1234af190fb2eb8.zip
Use DefIndex instead of NodeId in UpvarId.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/ich/impls_ty.rs13
-rw-r--r--src/librustc/infer/error_reporting/mod.rs2
-rw-r--r--src/librustc/infer/error_reporting/note.rs18
-rw-r--r--src/librustc/middle/expr_use_visitor.rs11
-rw-r--r--src/librustc/middle/mem_categorization.rs17
-rw-r--r--src/librustc/ty/mod.rs9
-rw-r--r--src/librustc/util/ppaux.rs4
-rw-r--r--src/librustc_borrowck/borrowck/gather_loans/move_error.rs4
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs30
-rw-r--r--src/librustc_mir/build/mod.rs10
-rw-r--r--src/librustc_mir/hair/cx/expr.rs17
-rw-r--r--src/librustc_typeck/check/upvar.rs83
-rw-r--r--src/librustc_typeck/check/writeback.rs9
13 files changed, 142 insertions, 85 deletions
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index 7b98eb0fb71..279e62c6311 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -11,6 +11,7 @@
 //! This module contains `HashStable` implementations for various data types
 //! from rustc::ty in no particular order.
 
+use hir::def_id::DefId;
 use ich::{self, StableHashingContext, NodeIdHashingMode};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
                                            StableHasherResult};
@@ -618,7 +619,7 @@ for ty::TypeckTables<'gcx> {
                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
                                           hasher: &mut StableHasher<W>) {
         let ty::TypeckTables {
-            local_id_root: _,
+            local_id_root,
             ref type_dependent_defs,
             ref node_types,
             ref node_substs,
@@ -649,8 +650,14 @@ for ty::TypeckTables<'gcx> {
                     closure_expr_id
                 } = *up_var_id;
 
-                let var_def_id = hcx.tcx().hir.local_def_id(var_id);
-                let closure_def_id = hcx.tcx().hir.local_def_id(closure_expr_id);
+                let var_def_id = DefId {
+                    krate: local_id_root.krate,
+                    index: var_id,
+                };
+                let closure_def_id = DefId {
+                    krate: local_id_root.krate,
+                    index: closure_expr_id,
+                };
                 (hcx.def_path_hash(var_def_id), hcx.def_path_hash(closure_def_id))
             });
 
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 9f70b4834dd..b5390da7e85 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -913,7 +913,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             }
             infer::UpvarRegion(ref upvar_id, _) => {
                 format!(" for capture of `{}` by closure",
-                        self.tcx.local_var_name_str(upvar_id.var_id).to_string())
+                        self.tcx.local_var_name_str_def_index(upvar_id.var_id))
             }
         };
 
diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs
index 963c14c48c8..87047d0df14 100644
--- a/src/librustc/infer/error_reporting/note.rs
+++ b/src/librustc/infer/error_reporting/note.rs
@@ -45,8 +45,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 err.span_note(span,
                               &format!("...so that closure can access `{}`",
                                        self.tcx
-                                           .local_var_name_str(upvar_id.var_id)
-                                           .to_string()));
+                                           .local_var_name_str_def_index(upvar_id.var_id)));
             }
             infer::InfStackClosure(span) => {
                 err.span_note(span, "...so that closure does not outlive its stack frame");
@@ -176,18 +175,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                                E0313,
                                                "lifetime of borrowed pointer outlives lifetime \
                                                 of captured variable `{}`...",
-                                               self.tcx.local_var_name_str(upvar_id.var_id));
+                                               self.tcx
+                                                   .local_var_name_str_def_index(upvar_id.var_id));
                 self.tcx.note_and_explain_region(&mut err,
                                                  "...the borrowed pointer is valid for ",
                                                  sub,
                                                  "...");
                 self.tcx
-                    .note_and_explain_region(&mut err,
-                                             &format!("...but `{}` is only valid for ",
-                                                      self.tcx
-                                                          .local_var_name_str(upvar_id.var_id)),
-                                             sup,
-                                             "");
+                    .note_and_explain_region(
+                      &mut err,
+                      &format!("...but `{}` is only valid for ",
+                               self.tcx.local_var_name_str_def_index(upvar_id.var_id)),
+                      sup,
+                      "");
                 err
             }
             infer::InfStackClosure(span) => {
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index a11511c2434..73800fe7f08 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -890,10 +890,13 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
 
         self.tcx().with_freevars(closure_expr.id, |freevars| {
             for freevar in freevars {
-                let def_id = freevar.def.def_id();
-                let id_var = self.tcx().hir.as_local_node_id(def_id).unwrap();
-                let upvar_id = ty::UpvarId { var_id: id_var,
-                                             closure_expr_id: closure_expr.id };
+                let var_def_id = freevar.def.def_id();
+                debug_assert!(var_def_id.is_local());
+                let closure_def_id = self.tcx().hir.local_def_id(closure_expr.id);
+                let upvar_id = ty::UpvarId {
+                    var_id: var_def_id.index,
+                    closure_expr_id: closure_def_id.index
+                };
                 let upvar_capture = self.mc.tables.upvar_capture(upvar_id);
                 let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
                                                                    fn_decl_span,
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index e8c6cc81212..08231a9ba1b 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -70,7 +70,7 @@ pub use self::Note::*;
 use self::Aliasability::*;
 
 use middle::region::RegionMaps;
-use hir::def_id::DefId;
+use hir::def_id::{DefId, DefIndex};
 use hir::map as hir_map;
 use infer::InferCtxt;
 use hir::def::{Def, CtorKind};
@@ -190,7 +190,7 @@ pub type cmt<'tcx> = Rc<cmt_<'tcx>>;
 
 pub enum ImmutabilityBlame<'tcx> {
     ImmLocal(ast::NodeId),
-    ClosureEnv(ast::NodeId),
+    ClosureEnv(DefIndex),
     LocalDeref(ast::NodeId),
     AdtFieldDeref(&'tcx ty::AdtDef, &'tcx ty::FieldDef)
 }
@@ -728,8 +728,13 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
             None => span_bug!(span, "missing closure kind")
         };
 
-        let upvar_id = ty::UpvarId { var_id,
-                                     closure_expr_id: fn_node_id };
+        let closure_expr_def_index = self.tcx.hir.local_def_id(fn_node_id).index;
+        let var_def_index = self.tcx.hir.local_def_id(var_id).index;
+
+        let upvar_id = ty::UpvarId {
+            var_id: var_def_index,
+            closure_expr_id: closure_expr_def_index
+        };
         let var_hir_id = self.tcx.hir.node_to_hir_id(var_id);
         let var_ty = self.node_ty(var_hir_id)?;
 
@@ -766,8 +771,6 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         // If this is a by-ref capture, then the upvar we loaded is
         // actually a reference, so we have to add an implicit deref
         // for that.
-        let upvar_id = ty::UpvarId { var_id,
-                                     closure_expr_id: fn_node_id };
         let upvar_capture = self.tables.upvar_capture(upvar_id);
         let cmt_result = match upvar_capture {
             ty::UpvarCapture::ByValue => {
@@ -805,7 +808,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
             // The environment of a closure is guaranteed to
             // outlive any bindings introduced in the body of the
             // closure itself.
-            scope: self.tcx.hir.local_def_id(upvar_id.closure_expr_id),
+            scope: DefId::local(upvar_id.closure_expr_id),
             bound_region: ty::BrEnv
         }));
 
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 28a73f4a4d3..af322fc72d8 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -572,8 +572,8 @@ impl<T> Slice<T> {
 /// by the upvar) and the id of the closure expression.
 #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub struct UpvarId {
-    pub var_id: NodeId,
-    pub closure_expr_id: NodeId,
+    pub var_id: DefIndex,
+    pub closure_expr_id: DefIndex,
 }
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
@@ -1983,6 +1983,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         }
     }
 
+    pub fn local_var_name_str_def_index(self, def_index: DefIndex) -> InternedString {
+        let node_id = self.hir.as_local_node_id(DefId::local(def_index)).unwrap();
+        self.local_var_name_str(node_id)
+    }
+
     pub fn expr_is_lval(self, expr: &hir::Expr) -> bool {
          match expr.node {
             hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index d9c99ccd508..184fd75135e 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -864,9 +864,9 @@ impl<'tcx> fmt::Display for ty::TyS<'tcx> {
 
 impl fmt::Debug for ty::UpvarId {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "UpvarId({};`{}`;{})",
+        write!(f, "UpvarId({:?};`{}`;{:?})",
                self.var_id,
-               ty::tls::with(|tcx| tcx.local_var_name_str(self.var_id)),
+               ty::tls::with(|tcx| tcx.local_var_name_str_def_index(self.var_id)),
                self.closure_expr_id)
     }
 }
diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
index cceb4a7b3cc..bfd883be848 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
@@ -93,11 +93,11 @@ fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, errors: &Vec<Move
             }
         }
         if let NoteClosureEnv(upvar_id) = error.move_from.note {
-            err.span_label(bccx.tcx.hir.span(upvar_id.var_id),
+            let var_node_id = bccx.tcx.hir.def_index_to_node_id(upvar_id.var_id);
+            err.span_label(bccx.tcx.hir.span(var_node_id),
                            "captured outer variable");
         }
         err.emit();
-
     }
 }
 
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 7c9f4abe418..07981cc67fc 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -27,7 +27,7 @@ use rustc::middle::dataflow::DataFlowContext;
 use rustc::middle::dataflow::BitwiseOperator;
 use rustc::middle::dataflow::DataFlowOperator;
 use rustc::middle::dataflow::KillFrom;
-use rustc::hir::def_id::DefId;
+use rustc::hir::def_id::{DefId, DefIndex};
 use rustc::middle::expr_use_visitor as euv;
 use rustc::middle::mem_categorization as mc;
 use rustc::middle::mem_categorization::Categorization;
@@ -323,8 +323,9 @@ pub enum LoanPathElem<'tcx> {
     LpInterior(Option<DefId>, InteriorKind),
 }
 
-pub fn closure_to_block(closure_id: ast::NodeId,
-                        tcx: TyCtxt) -> ast::NodeId {
+fn closure_to_block(closure_id: DefIndex,
+                    tcx: TyCtxt) -> ast::NodeId {
+    let closure_id = tcx.hir.def_index_to_node_id(closure_id);
     match tcx.hir.get(closure_id) {
         hir_map::NodeExpr(expr) => match expr.node {
             hir::ExprClosure(.., body_id, _) => {
@@ -845,7 +846,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                 } else {
                     "consider changing this closure to take self by mutable reference"
                 };
-                err.span_help(self.tcx.hir.span(id), help);
+                let node_id = self.tcx.hir.def_index_to_node_id(id);
+                err.span_help(self.tcx.hir.span(node_id), help);
                 err
             }
             _ =>  {
@@ -1181,7 +1183,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                     _ => bug!()
                 };
                 if kind == ty::ClosureKind::Fn {
-                    db.span_help(self.tcx.hir.span(upvar_id.closure_expr_id),
+                    let closure_node_id =
+                        self.tcx.hir.def_index_to_node_id(upvar_id.closure_expr_id);
+                    db.span_help(self.tcx.hir.span(closure_node_id),
                                  "consider changing this closure to take \
                                   self by mutable reference");
                 }
@@ -1214,7 +1218,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                                       loan_path: &LoanPath<'tcx>,
                                       out: &mut String) {
         match loan_path.kind {
-            LpUpvar(ty::UpvarId{ var_id: id, closure_expr_id: _ }) |
+            LpUpvar(ty::UpvarId { var_id: id, closure_expr_id: _ }) => {
+                out.push_str(&self.tcx.local_var_name_str_def_index(id));
+            }
             LpVar(id) => {
                 out.push_str(&self.tcx.local_var_name_str(id));
             }
@@ -1352,8 +1358,11 @@ impl<'tcx> fmt::Debug for LoanPath<'tcx> {
             }
 
             LpUpvar(ty::UpvarId{ var_id, closure_expr_id }) => {
-                let s = ty::tls::with(|tcx| tcx.hir.node_to_string(var_id));
-                write!(f, "$({} captured by id={})", s, closure_expr_id)
+                let s = ty::tls::with(|tcx| {
+                    let var_node_id = tcx.hir.def_index_to_node_id(var_id);
+                    tcx.hir.node_to_string(var_node_id)
+                });
+                write!(f, "$({} captured by id={:?})", s, closure_expr_id)
             }
 
             LpDowncast(ref lp, variant_def_id) => {
@@ -1384,7 +1393,10 @@ impl<'tcx> fmt::Display for LoanPath<'tcx> {
             }
 
             LpUpvar(ty::UpvarId{ var_id, closure_expr_id: _ }) => {
-                let s = ty::tls::with(|tcx| tcx.hir.node_to_user_string(var_id));
+                let s = ty::tls::with(|tcx| {
+                    let var_node_id = tcx.hir.def_index_to_node_id(var_id);
+                    tcx.hir.node_to_string(var_node_id)
+                });
                 write!(f, "$({} captured by closure)", s)
             }
 
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index ae951d50a8c..d029e2f10e8 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -368,10 +368,12 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
     // Gather the upvars of a closure, if any.
     let upvar_decls: Vec<_> = tcx.with_freevars(fn_id, |freevars| {
         freevars.iter().map(|fv| {
-            let var_id = tcx.hir.as_local_node_id(fv.def.def_id()).unwrap();
+            let var_def_id = fv.def.def_id();
+            let var_node_id = tcx.hir.as_local_node_id(var_def_id).unwrap();
+            let closure_expr_id = tcx.hir.local_def_id(fn_id).index;
             let capture = hir.tables().upvar_capture(ty::UpvarId {
-                var_id: var_id,
-                closure_expr_id: fn_id
+                var_id: var_def_id.index,
+                closure_expr_id,
             });
             let by_ref = match capture {
                 ty::UpvarCapture::ByValue => false,
@@ -381,7 +383,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
                 debug_name: keywords::Invalid.name(),
                 by_ref: by_ref
             };
-            if let Some(hir::map::NodeLocal(pat)) = tcx.hir.find(var_id) {
+            if let Some(hir::map::NodeLocal(pat)) = tcx.hir.find(var_node_id) {
                 if let hir::PatKind::Binding(_, _, ref ident, _) = pat.node {
                     decl.debug_name = ident.node;
                 }
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 05709fed0af..11da73187b3 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -684,8 +684,8 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             ExprKind::VarRef { id: node_id }
         }
 
-        Def::Upvar(def_id, index, closure_expr_id) => {
-            let id_var = cx.tcx.hir.as_local_node_id(def_id).unwrap();
+        Def::Upvar(var_def_id, index, closure_expr_id) => {
+            let id_var = cx.tcx.hir.as_local_node_id(var_def_id).unwrap();
             debug!("convert_var(upvar({:?}, {:?}, {:?}))",
                    id_var,
                    index,
@@ -768,8 +768,8 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             // ...but the upvar might be an `&T` or `&mut T` capture, at which
             // point we need an implicit deref
             let upvar_id = ty::UpvarId {
-                var_id: id_var,
-                closure_expr_id: closure_expr_id,
+                var_id: var_def_id.index,
+                closure_expr_id: closure_def_id.index,
             };
             match cx.tables().upvar_capture(upvar_id) {
                 ty::UpvarCapture::ByValue => field_kind,
@@ -880,15 +880,16 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                                    freevar: &hir::Freevar,
                                    freevar_ty: Ty<'tcx>)
                                    -> ExprRef<'tcx> {
-    let id_var = cx.tcx.hir.as_local_node_id(freevar.def.def_id()).unwrap();
+    let var_def_id = freevar.def.def_id();
+    let var_node_id = cx.tcx.hir.as_local_node_id(var_def_id).unwrap();
     let upvar_id = ty::UpvarId {
-        var_id: id_var,
-        closure_expr_id: closure_expr.id,
+        var_id: var_def_id.index,
+        closure_expr_id: cx.tcx.hir.local_def_id(closure_expr.id).index,
     };
     let upvar_capture = cx.tables().upvar_capture(upvar_id);
     let temp_lifetime = cx.region_maps.temporary_scope(closure_expr.id);
     let var_ty = cx.tables()
-                   .node_id_to_type(cx.tcx.hir.node_to_hir_id(id_var));
+                   .node_id_to_type(cx.tcx.hir.node_to_hir_id(var_node_id));
     let captured_var = Expr {
         temp_lifetime: temp_lifetime,
         ty: var_ty,
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index 6621c9d027e..111f224c3d1 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -50,8 +50,9 @@ use rustc::infer::UpvarRegion;
 use syntax::ast;
 use syntax_pos::Span;
 use rustc::hir;
+use rustc::hir::def_id::DefIndex;
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
-use rustc::util::nodemap::NodeMap;
+use rustc::util::nodemap::FxHashMap;
 
 use std::collections::hash_map::Entry;
 
@@ -90,7 +91,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for InferBorrowKindVisitor<'a, 'gcx, 'tcx> {
 
 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     fn analyze_closure(&self,
-                       (id, hir_id): (ast::NodeId, hir::HirId),
+                       (closure_node_id, closure_hir_id): (ast::NodeId, hir::HirId),
                        span: Span,
                        body: &hir::Body,
                        capture_clause: hir::CaptureClause) {
@@ -98,23 +99,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
          * Analysis starting point.
          */
 
-        debug!("analyze_closure(id={:?}, body.id={:?})", id, body.id());
+        debug!("analyze_closure(id={:?}, body.id={:?})", closure_node_id, body.id());
 
-        let infer_kind = match self.tables.borrow_mut().closure_kinds.entry(hir_id.local_id) {
+        let infer_kind = match self.tables
+                                   .borrow_mut()
+                                   .closure_kinds
+                                   .entry(closure_hir_id.local_id) {
             Entry::Occupied(_) => false,
             Entry::Vacant(entry) => {
-                debug!("check_closure: adding closure {:?} as Fn", id);
+                debug!("check_closure: adding closure {:?} as Fn", closure_node_id);
                 entry.insert((ty::ClosureKind::Fn, None));
                 true
             }
         };
 
-        self.tcx.with_freevars(id, |freevars| {
+        let closure_def_id = self.tcx.hir.local_def_id(closure_node_id);
+
+        self.tcx.with_freevars(closure_node_id, |freevars| {
             for freevar in freevars {
-                let def_id = freevar.def.def_id();
-                let var_node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
-                let upvar_id = ty::UpvarId { var_id: var_node_id,
-                                             closure_expr_id: id };
+                let var_def_id = freevar.def.def_id();
+                let upvar_id = ty::UpvarId {
+                    var_id: var_def_id.index,
+                    closure_expr_id: closure_def_id.index,
+                };
                 debug!("seed upvar_id {:?}", upvar_id);
 
                 let capture_kind = match capture_clause {
@@ -139,7 +146,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             let region_maps = &self.tcx.region_maps(body_owner_def_id);
             let mut delegate = InferBorrowKind {
                 fcx: self,
-                adjust_closure_kinds: NodeMap(),
+                adjust_closure_kinds: FxHashMap(),
                 adjust_upvar_captures: ty::UpvarCaptureMap::default(),
             };
             euv::ExprUseVisitor::with_infer(&mut delegate,
@@ -151,8 +158,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
             // Write the adjusted values back into the main tables.
             if infer_kind {
-                if let Some(kind) = delegate.adjust_closure_kinds.remove(&id) {
-                    self.tables.borrow_mut().closure_kinds.insert(hir_id.local_id, kind);
+                if let Some(kind) = delegate.adjust_closure_kinds
+                                            .remove(&closure_def_id.index) {
+                    self.tables
+                        .borrow_mut()
+                        .closure_kinds
+                        .insert(closure_hir_id.local_id, kind);
                 }
             }
             self.tables.borrow_mut().upvar_capture_map.extend(
@@ -172,20 +183,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // inference algorithm will reject it).
 
         // Extract the type variables UV0...UVn.
-        let (def_id, closure_substs) = match self.node_ty(hir_id).sty {
+        let (def_id, closure_substs) = match self.node_ty(closure_hir_id).sty {
             ty::TyClosure(def_id, substs) => (def_id, substs),
             ref t => {
                 span_bug!(
                     span,
                     "type of closure expr {:?} is not a closure {:?}",
-                    id, t);
+                    closure_node_id, t);
             }
         };
 
         // Equate the type variables with the actual types.
-        let final_upvar_tys = self.final_upvar_tys(id);
+        let final_upvar_tys = self.final_upvar_tys(closure_node_id);
         debug!("analyze_closure: id={:?} closure_substs={:?} final_upvar_tys={:?}",
-               id, closure_substs, final_upvar_tys);
+               closure_node_id, closure_substs, final_upvar_tys);
         for (upvar_ty, final_upvar_ty) in
             closure_substs.upvar_tys(def_id, self.tcx).zip(final_upvar_tys)
         {
@@ -195,7 +206,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // If we are also inferred the closure kind here,
         // process any deferred resolutions.
         if infer_kind {
-            let closure_def_id = self.tcx.hir.local_def_id(id);
             let deferred_call_resolutions =
                 self.remove_deferred_call_resolutions(closure_def_id);
             for deferred_call_resolution in deferred_call_resolutions {
@@ -212,19 +222,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // This may change if abstract return types of some sort are
         // implemented.
         let tcx = self.tcx;
+        let closure_def_index = tcx.hir.local_def_id(closure_id).index;
+
         tcx.with_freevars(closure_id, |freevars| {
             freevars.iter().map(|freevar| {
-                let def_id = freevar.def.def_id();
-                let var_id = tcx.hir.as_local_node_id(def_id).unwrap();
-                let freevar_ty = self.node_ty(tcx.hir.node_to_hir_id(var_id));
+                let var_def_id = freevar.def.def_id();
+                let var_node_id = tcx.hir.as_local_node_id(var_def_id).unwrap();
+                let freevar_ty = self.node_ty(tcx.hir.node_to_hir_id(var_node_id));
                 let upvar_id = ty::UpvarId {
-                    var_id: var_id,
-                    closure_expr_id: closure_id
+                    var_id: var_def_id.index,
+                    closure_expr_id: closure_def_index,
                 };
                 let capture = self.tables.borrow().upvar_capture(upvar_id);
 
                 debug!("var_id={:?} freevar_ty={:?} capture={:?}",
-                       var_id, freevar_ty, capture);
+                       var_node_id, freevar_ty, capture);
 
                 match capture {
                     ty::UpvarCapture::ByValue => freevar_ty,
@@ -242,7 +254,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
 struct InferBorrowKind<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
-    adjust_closure_kinds: NodeMap<(ty::ClosureKind, Option<(Span, ast::Name)>)>,
+    adjust_closure_kinds: FxHashMap<DefIndex, (ty::ClosureKind, Option<(Span, ast::Name)>)>,
     adjust_upvar_captures: ty::UpvarCaptureMap<'tcx>,
 }
 
@@ -281,7 +293,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
                         self.adjust_closure_kind(upvar_id.closure_expr_id,
                                                  ty::ClosureKind::FnOnce,
                                                  guarantor.span,
-                                                 tcx.hir.name(upvar_id.var_id));
+                                                 var_name(tcx, upvar_id.var_id));
 
                         self.adjust_upvar_captures.insert(upvar_id, ty::UpvarCapture::ByValue);
                     }
@@ -295,7 +307,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
                         self.adjust_closure_kind(upvar_id.closure_expr_id,
                                                  ty::ClosureKind::FnOnce,
                                                  guarantor.span,
-                                                 tcx.hir.name(upvar_id.var_id));
+                                                 var_name(tcx, upvar_id.var_id));
                     }
                     mc::NoteNone => {
                     }
@@ -400,7 +412,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
                 self.adjust_closure_kind(upvar_id.closure_expr_id,
                                          ty::ClosureKind::FnMut,
                                          cmt.span,
-                                         tcx.hir.name(upvar_id.var_id));
+                                         var_name(tcx, upvar_id.var_id));
 
                 true
             }
@@ -411,7 +423,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
                 self.adjust_closure_kind(upvar_id.closure_expr_id,
                                          ty::ClosureKind::FnMut,
                                          cmt.span,
-                                         tcx.hir.name(upvar_id.var_id));
+                                         var_name(tcx, upvar_id.var_id));
 
                 true
             }
@@ -460,23 +472,23 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
     }
 
     fn adjust_closure_kind(&mut self,
-                           closure_id: ast::NodeId,
+                           closure_id: DefIndex,
                            new_kind: ty::ClosureKind,
                            upvar_span: Span,
                            var_name: ast::Name) {
-        debug!("adjust_closure_kind(closure_id={}, new_kind={:?}, upvar_span={:?}, var_name={})",
+        debug!("adjust_closure_kind(closure_id={:?}, new_kind={:?}, upvar_span={:?}, var_name={})",
                closure_id, new_kind, upvar_span, var_name);
 
         let closure_kind = self.adjust_closure_kinds.get(&closure_id).cloned()
             .or_else(|| {
-                let closure_id = self.fcx.tcx.hir.node_to_hir_id(closure_id);
+                let closure_id = self.fcx.tcx.hir.def_index_to_hir_id(closure_id);
                 let fcx_tables = self.fcx.tables.borrow();
                 fcx_tables.validate_hir_id(closure_id);
                 fcx_tables.closure_kinds.get(&closure_id.local_id).cloned()
             });
 
         if let Some((existing_kind, _)) = closure_kind {
-            debug!("adjust_closure_kind: closure_id={}, existing_kind={:?}, new_kind={:?}",
+            debug!("adjust_closure_kind: closure_id={:?}, existing_kind={:?}, new_kind={:?}",
                    closure_id, existing_kind, new_kind);
 
             match (existing_kind, new_kind) {
@@ -566,3 +578,8 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'gcx, 'tcx> {
         self.adjust_upvar_borrow_kind_for_mut(assignee_cmt);
     }
 }
+
+fn var_name(tcx: ty::TyCtxt, var_def_index: DefIndex) -> ast::Name {
+    let var_node_id = tcx.hir.def_index_to_node_id(var_def_index);
+    tcx.hir.name(var_node_id)
+}
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 45ec788b1b8..515bbe49c39 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -14,7 +14,7 @@
 
 use check::FnCtxt;
 use rustc::hir;
-use rustc::hir::def_id::DefId;
+use rustc::hir::def_id::{DefId, DefIndex};
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::infer::{InferCtxt};
 use rustc::ty::{self, Ty, TyCtxt};
@@ -401,6 +401,13 @@ impl Locatable for ast::NodeId {
     fn to_span(&self, tcx: &TyCtxt) -> Span { tcx.hir.span(*self) }
 }
 
+impl Locatable for DefIndex {
+    fn to_span(&self, tcx: &TyCtxt) -> Span {
+        let node_id = tcx.hir.def_index_to_node_id(*self);
+        tcx.hir.span(node_id)
+    }
+}
+
 impl Locatable for hir::HirId {
     fn to_span(&self, tcx: &TyCtxt) -> Span {
         let node_id = tcx.hir.definitions().find_node_for_hir_id(*self);