about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-08-18 17:54:56 -0400
committerNiko Matsakis <niko@alum.mit.edu>2015-09-06 07:27:22 -0400
commit004d70212ab40b35bcbe87df272b91fde10513b2 (patch)
treedd7a3eb5a469b6523f7c9c7a9de7dd5292b40b3d
parent9b52c5bfff16a5f95c04a01325c55881f652a802 (diff)
downloadrust-004d70212ab40b35bcbe87df272b91fde10513b2.tar.gz
rust-004d70212ab40b35bcbe87df272b91fde10513b2.zip
track, for each upvar, its index in list of upvars
-rw-r--r--src/librustc/middle/astencode.rs4
-rw-r--r--src/librustc/middle/def.rs3
-rw-r--r--src/librustc/middle/mem_categorization.rs2
-rw-r--r--src/librustc_resolve/lib.rs27
-rw-r--r--src/librustc_trans/trans/_match.rs6
-rw-r--r--src/librustc_trans/trans/expr.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs2
7 files changed, 23 insertions, 23 deletions
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 4d921c007c6..abf2d5f3625 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -470,8 +470,8 @@ impl tr for def::Def {
           def::DefPrimTy(p) => def::DefPrimTy(p),
           def::DefTyParam(s, index, def_id, n) => def::DefTyParam(s, index, def_id.tr(dcx), n),
           def::DefUse(did) => def::DefUse(did.tr(dcx)),
-          def::DefUpvar(nid1, nid2) => {
-            def::DefUpvar(dcx.tr_id(nid1), dcx.tr_id(nid2))
+          def::DefUpvar(nid1, index, nid2) => {
+            def::DefUpvar(dcx.tr_id(nid1), index, dcx.tr_id(nid2))
           }
           def::DefStruct(did) => def::DefStruct(did.tr(dcx)),
           def::DefRegion(nid) => def::DefRegion(dcx.tr_id(nid)),
diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs
index 2930dd67f45..86133aad672 100644
--- a/src/librustc/middle/def.rs
+++ b/src/librustc/middle/def.rs
@@ -38,6 +38,7 @@ pub enum Def {
     DefTyParam(ParamSpace, u32, DefId, ast::Name),
     DefUse(DefId),
     DefUpvar(ast::NodeId,  // id of closed over local
+             usize,        // index in the freevars list of the closure
              ast::NodeId), // expr node that creates the closure
 
     /// Note that if it's a tuple struct's definition, the node id of the DefId
@@ -129,7 +130,7 @@ impl Def {
                 id
             }
             DefLocal(id) |
-            DefUpvar(id, _) |
+            DefUpvar(id, _, _) |
             DefRegion(id) |
             DefLabel(id)  |
             DefSelfTy(_, Some((_, id))) => {
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index ba7c675817f..51005ef8b97 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -578,7 +578,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
               }))
           }
 
-          def::DefUpvar(var_id, fn_node_id) => {
+          def::DefUpvar(var_id, _, fn_node_id) => {
               let ty = try!(self.node_ty(fn_node_id));
               match ty.sty {
                   ty::TyClosure(closure_id, _) => {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index da9bae62d04..cd5f2a2e764 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -62,7 +62,7 @@ use rustc::middle::pat_util::pat_bindings;
 use rustc::middle::privacy::*;
 use rustc::middle::subst::{ParamSpace, FnSpace, TypeSpace};
 use rustc::middle::ty::{Freevar, FreevarMap, TraitMap, GlobMap};
-use rustc::util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
+use rustc::util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
 use rustc::util::lev_distance::lev_distance;
 
 use syntax::ast;
@@ -95,7 +95,6 @@ use rustc_front::hir::TypeImplItem;
 use rustc_front::util::walk_pat;
 
 use std::collections::{HashMap, HashSet};
-use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::cell::{Cell, RefCell};
 use std::fmt;
 use std::mem::replace;
@@ -1152,7 +1151,7 @@ pub struct Resolver<'a, 'tcx:'a> {
 
     def_map: DefMap,
     freevars: RefCell<FreevarMap>,
-    freevars_seen: RefCell<NodeMap<NodeSet>>,
+    freevars_seen: RefCell<NodeMap<NodeMap<usize>>>,
     export_map: ExportMap,
     trait_map: TraitMap,
     external_exports: ExternalExports,
@@ -1992,21 +1991,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         }
                         ClosureRibKind(function_id) => {
                             let prev_def = def;
-                            def = DefUpvar(node_id, function_id);
 
                             let mut seen = self.freevars_seen.borrow_mut();
-                            let seen = match seen.entry(function_id) {
-                                Occupied(v) => v.into_mut(),
-                                Vacant(v) => v.insert(NodeSet()),
-                            };
-                            if seen.contains(&node_id) {
+                            let seen = seen.entry(function_id).or_insert_with(|| NodeMap());
+                            if let Some(&index) = seen.get(&node_id) {
+                                def = DefUpvar(node_id, index, function_id);
                                 continue;
                             }
-                            match self.freevars.borrow_mut().entry(function_id) {
-                                Occupied(v) => v.into_mut(),
-                                Vacant(v) => v.insert(vec![]),
-                            }.push(Freevar { def: prev_def, span: span });
-                            seen.insert(node_id);
+                            let mut freevars = self.freevars.borrow_mut();
+                            let vec = freevars.entry(function_id)
+                                              .or_insert_with(|| vec![]);
+                            let depth = vec.len();
+                            vec.push(Freevar { def: prev_def, span: span });
+
+                            def = DefUpvar(node_id, depth, function_id);
+                            seen.insert(node_id, depth);
                         }
                         ItemRibKind | MethodRibKind => {
                             // This was an attempt to access an upvar inside a
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs
index 05a3e81839e..c6866004df9 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -1428,19 +1428,19 @@ pub fn trans_match<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 fn is_discr_reassigned(bcx: Block, discr: &hir::Expr, body: &hir::Expr) -> bool {
     let (vid, field) = match discr.node {
         hir::ExprPath(..) => match bcx.def(discr.id) {
-            def::DefLocal(vid) | def::DefUpvar(vid, _) => (vid, None),
+            def::DefLocal(vid) | def::DefUpvar(vid, _, _) => (vid, None),
             _ => return false
         },
         hir::ExprField(ref base, field) => {
             let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) {
-                Some(def::DefLocal(vid)) | Some(def::DefUpvar(vid, _)) => vid,
+                Some(def::DefLocal(vid)) | Some(def::DefUpvar(vid, _, _)) => vid,
                 _ => return false
             };
             (vid, Some(mc::NamedField(field.node.name)))
         },
         hir::ExprTupField(ref base, field) => {
             let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) {
-                Some(def::DefLocal(vid)) | Some(def::DefUpvar(vid, _)) => vid,
+                Some(def::DefLocal(vid)) | Some(def::DefUpvar(vid, _, _)) => vid,
                 _ => return false
             };
             (vid, Some(mc::PositionalField(field.node)))
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index 9dc96ff72eb..7602956cb8e 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -1319,7 +1319,7 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let _icx = push_ctxt("trans_local_var");
 
     match def {
-        def::DefUpvar(nid, _) => {
+        def::DefUpvar(nid, _, _) => {
             // Can't move upvars, so this is never a ZeroMemLastUse.
             let local_ty = node_id_type(bcx, nid);
             let lval = Lvalue::new_with_hint("expr::trans_local_var (upvar)",
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index c4368a3898d..b1fbf97d1a7 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4318,7 +4318,7 @@ fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                                 defn: def::Def)
                                                 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
     match defn {
-        def::DefLocal(nid) | def::DefUpvar(nid, _) => {
+        def::DefLocal(nid) | def::DefUpvar(nid, _, _) => {
             let typ = fcx.local_ty(sp, nid);
             (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
              ty::GenericPredicates::empty())