From: Niko Matsakis Date: Tue, 18 Aug 2015 21:54:56 +0000 (-0400) Subject: track, for each upvar, its index in list of upvars X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=004d70212ab40b35bcbe87df272b91fde10513b2;p=rust.git track, for each upvar, its index in list of upvars --- 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 @@ fn tr(&self, dcx: &DecodeContext) -> 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 @@ pub fn def_id(&self) -> DefId { 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 @@ pub fn cat_def(&self, })) } - 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::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::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, - freevars_seen: RefCell>, + freevars_seen: RefCell>>, export_map: ExportMap, trait_map: TraitMap, external_exports: ExternalExports, @@ -1992,21 +1991,21 @@ fn upvarify(&self, } 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())