about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/hir/def.rs7
-rw-r--r--src/librustc/hir/mod.rs5
-rw-r--r--src/librustc/middle/expr_use_visitor.rs2
-rw-r--r--src/librustc/middle/mem_categorization.rs2
-rw-r--r--src/librustc_mir/hair/cx/expr.rs6
-rw-r--r--src/librustc_mir/hair/cx/mod.rs16
-rw-r--r--src/librustc_resolve/lib.rs13
7 files changed, 30 insertions, 21 deletions
diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index 03f24dbb290..f342b230a71 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -140,7 +140,6 @@ pub enum Res<Id = hir::HirId> {
     SelfCtor(DefId /* impl */),  // `DefId` refers to the impl
     Local(Id),
     Upvar(Id,           // `HirId` of closed over local
-          usize,        // index in the `upvars` list of the closure
           ast::NodeId), // expr node that creates the closure
 
     // Macro namespace
@@ -397,11 +396,7 @@ impl<Id> Res<Id> {
             Res::SelfCtor(id) => Res::SelfCtor(id),
             Res::PrimTy(id) => Res::PrimTy(id),
             Res::Local(id) => Res::Local(map(id)),
-            Res::Upvar(id, index, closure) => Res::Upvar(
-                map(id),
-                index,
-                closure
-            ),
+            Res::Upvar(id, closure) => Res::Upvar(map(id), closure),
             Res::SelfTy(a, b) => Res::SelfTy(a, b),
             Res::ToolMod => Res::ToolMod,
             Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index bdae04ae478..547a7a7930c 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -2497,9 +2497,8 @@ pub struct Upvar<Id = HirId> {
     /// The variable being captured.
     pub var_id: Id,
 
-    /// The parent closure, if this is not a direct capture,
-    /// and the index within that closure's capture list.
-    pub parent: Option<(ast::NodeId, usize)>,
+    /// The parent closure, if this is not a direct capture.
+    pub parent: Option<ast::NodeId>,
 
     // First span where it is accessed (there can be multiple).
     pub span: Span
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index fd9233acbae..b10acc987a2 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -964,7 +964,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
         let var_ty = self.mc.node_ty(upvar.var_id)?;
         let res = upvar.parent.map_or(
             Res::Local(upvar.var_id),
-            |(closure_node_id, i)| Res::Upvar(upvar.var_id, i, closure_node_id),
+            |closure_node_id| Res::Upvar(upvar.var_id, closure_node_id),
         );
         self.mc.cat_res(closure_hir_id, closure_span, var_ty, res)
     }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 8d7c6f18a85..c58ce762773 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -737,7 +737,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                 })
             }
 
-            Res::Upvar(var_id, _, fn_node_id) => {
+            Res::Upvar(var_id, fn_node_id) => {
                 let var_nid = self.tcx.hir().hir_to_node_id(var_id);
                 self.cat_upvar(hir_id, span, var_nid, fn_node_id)
             }
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 354aec442ed..870de08264d 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -975,7 +975,9 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
     match res {
         Res::Local(id) => ExprKind::VarRef { id },
 
-        Res::Upvar(var_hir_id, index, closure_expr_id) => {
+        Res::Upvar(var_hir_id, closure_expr_id) => {
+            let index = cx.upvar_indices[&var_hir_id];
+
             debug!("convert_var(upvar({:?}, {:?}, {:?}))",
                    var_hir_id,
                    index,
@@ -1190,7 +1192,7 @@ fn capture_upvar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
     let var_ty = cx.tables().node_type(upvar.var_id);
     let upvar_res = upvar.parent.map_or(
         Res::Local(upvar.var_id),
-        |(closure_node_id, i)| Res::Upvar(upvar.var_id, i, closure_node_id),
+        |closure_node_id| Res::Upvar(upvar.var_id, closure_node_id),
     );
     let captured_var = Expr {
         temp_lifetime,
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index 80f64e85f9c..74382bb1fe2 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -5,6 +5,7 @@
 use crate::hair::*;
 use crate::hair::util::UserAnnotatedTyHelpers;
 
+use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_vec::Idx;
 use rustc::hir::def_id::DefId;
 use rustc::hir::Node;
@@ -46,6 +47,9 @@ pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
 
     /// See field with the same name on `mir::Body`.
     control_flow_destroyed: Vec<(Span, String)>,
+
+    /// Reverse map, from upvar variable `HirId`s to their indices.
+    upvar_indices: FxHashMap<hir::HirId, usize>,
 }
 
 impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
@@ -53,6 +57,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
                src_id: hir::HirId) -> Cx<'a, 'gcx, 'tcx> {
         let tcx = infcx.tcx;
         let src_def_id = tcx.hir().local_def_id_from_hir_id(src_id);
+        let tables = tcx.typeck_tables_of(src_def_id);
         let body_owner_kind = tcx.hir().body_owner_kind_by_hir_id(src_id);
 
         let constness = match body_owner_kind {
@@ -75,6 +80,14 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
         // Constants always need overflow checks.
         check_overflow |= constness == hir::Constness::Const;
 
+        // Compute reverse mapping, of uvpars to their indices.
+        let mut upvar_indices = FxHashMap::default();
+        if let Some(upvars) = tables.upvar_list.get(&src_def_id) {
+            upvar_indices.extend(
+                upvars.iter().enumerate().map(|(i, upvar_id)| (upvar_id.var_path.hir_id, i)),
+            );
+        }
+
         Cx {
             tcx,
             infcx,
@@ -82,11 +95,12 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
             param_env: tcx.param_env(src_def_id),
             identity_substs: InternalSubsts::identity_for_item(tcx.global_tcx(), src_def_id),
             region_scope_tree: tcx.region_scope_tree(src_def_id),
-            tables: tcx.typeck_tables_of(src_def_id),
+            tables,
             constness,
             body_owner_kind,
             check_overflow,
             control_flow_destroyed: Vec::new(),
+            upvar_indices,
         }
     }
 
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 67ed6a77305..490d5ae83b8 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1669,7 +1669,7 @@ pub struct Resolver<'a> {
     label_res_map: NodeMap<NodeId>,
 
     pub upvars: UpvarMap,
-    upvars_seen: NodeMap<NodeMap<usize>>,
+    upvars_seen: NodeMap<NodeSet>,
     pub export_map: ExportMap<NodeId>,
     pub trait_map: TraitMap,
 
@@ -4052,22 +4052,21 @@ impl<'a> Resolver<'a> {
                         }
                         ClosureRibKind(function_id) => {
                             let parent = match res {
-                                Res::Upvar(_, i, closure) => Some((closure, i)),
+                                Res::Upvar(_, closure) => Some(closure),
                                 _ => None,
                             };
 
                             let seen = self.upvars_seen
                                            .entry(function_id)
                                            .or_default();
-                            if let Some(&index) = seen.get(&var_id) {
-                                res = Res::Upvar(var_id, index, function_id);
+                            if seen.contains(&var_id) {
+                                res = Res::Upvar(var_id, function_id);
                                 continue;
                             }
                             let vec = self.upvars
                                           .entry(function_id)
                                           .or_default();
-                            let depth = vec.len();
-                            res = Res::Upvar(var_id, depth, function_id);
+                            res = Res::Upvar(var_id, function_id);
 
                             if record_used {
                                 vec.push(Upvar {
@@ -4075,7 +4074,7 @@ impl<'a> Resolver<'a> {
                                     parent,
                                     span,
                                 });
-                                seen.insert(var_id, depth);
+                                seen.insert(var_id);
                             }
                         }
                         ItemRibKind | FnItemRibKind | AssocItemRibKind => {