diff options
| author | Eduard Burtescu <edy.burt@gmail.com> | 2014-03-06 15:46:26 +0200 |
|---|---|---|
| committer | Eduard Burtescu <edy.burt@gmail.com> | 2014-03-17 09:53:06 +0200 |
| commit | 6879916a060218cbbec69a235efd7b6da9b32021 (patch) | |
| tree | ff2cf2afe890d0b52ab6b97ee931f3fde8ae50b3 | |
| parent | 0ba5f1b8f42b25e213b67305cdbea798abec7a81 (diff) | |
| download | rust-6879916a060218cbbec69a235efd7b6da9b32021.tar.gz rust-6879916a060218cbbec69a235efd7b6da9b32021.zip | |
De-@ liveness.
| -rw-r--r-- | src/librustc/middle/liveness.rs | 722 |
1 files changed, 307 insertions, 415 deletions
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index b0fe9e8c91d..7b08949fe02 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -111,9 +111,9 @@ use middle::moves; use util::nodemap::NodeMap; use std::cast::transmute; -use std::cell::{Cell, RefCell}; use std::fmt; use std::io; +use std::rc::Rc; use std::str; use std::uint; use std::vec_ng::Vec; @@ -126,9 +126,9 @@ use syntax::{visit, ast_util}; use syntax::visit::{Visitor, FnKind}; #[deriving(Eq)] -pub struct Variable(uint); +struct Variable(uint); #[deriving(Eq)] -pub struct LiveNode(uint); +struct LiveNode(uint); impl Variable { fn get(&self) -> uint { let Variable(v) = *self; v } @@ -145,7 +145,7 @@ impl Clone for LiveNode { } #[deriving(Eq)] -pub enum LiveNodeKind { +enum LiveNodeKind { FreeVarNode(Span), ExprNode(Span), VarDefNode(Span), @@ -162,25 +162,20 @@ fn live_node_kind_to_str(lnk: LiveNodeKind, cx: &ty::ctxt) -> ~str { } } -struct LivenessVisitor; - -impl<'a> Visitor<@IrMaps<'a>> for LivenessVisitor { - fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, n: NodeId, e: @IrMaps) { - visit_fn(self, fk, fd, b, s, n, e); +impl<'a> Visitor<()> for IrMaps<'a> { + fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, n: NodeId, _: ()) { + visit_fn(self, fk, fd, b, s, n); } - fn visit_local(&mut self, l: &Local, e: @IrMaps) { visit_local(self, l, e); } - fn visit_expr(&mut self, ex: &Expr, e: @IrMaps) { visit_expr(self, ex, e); } - fn visit_arm(&mut self, a: &Arm, e: @IrMaps) { visit_arm(self, a, e); } + fn visit_local(&mut self, l: &Local, _: ()) { visit_local(self, l); } + fn visit_expr(&mut self, ex: &Expr, _: ()) { visit_expr(self, ex); } + fn visit_arm(&mut self, a: &Arm, _: ()) { visit_arm(self, a); } } pub fn check_crate(tcx: &ty::ctxt, method_map: typeck::MethodMap, capture_map: moves::CaptureMap, krate: &Crate) { - let mut visitor = LivenessVisitor; - - let initial_maps = @IrMaps(tcx, method_map, capture_map); - visit::walk_crate(&mut visitor, krate, initial_maps); + visit::walk_crate(&mut IrMaps(tcx, method_map, capture_map), krate, ()); tcx.sess.abort_if_errors(); } @@ -219,50 +214,50 @@ impl fmt::Show for Variable { // assignment. And so forth. impl LiveNode { - pub fn is_valid(&self) -> bool { + fn is_valid(&self) -> bool { self.get() != uint::MAX } } fn invalid_node() -> LiveNode { LiveNode(uint::MAX) } -pub struct CaptureInfo { +struct CaptureInfo { ln: LiveNode, is_move: bool, var_nid: NodeId } -pub enum LocalKind { +enum LocalKind { FromMatch(BindingMode), FromLetWithInitializer, FromLetNoInitializer } -pub struct LocalInfo { +struct LocalInfo { id: NodeId, ident: Ident, is_mutbl: bool, kind: LocalKind, } -pub enum VarKind { +enum VarKind { Arg(NodeId, Ident), Local(LocalInfo), ImplicitRet } -pub struct IrMaps<'a> { +struct IrMaps<'a> { tcx: &'a ty::ctxt, method_map: typeck::MethodMap, capture_map: moves::CaptureMap, - num_live_nodes: Cell<uint>, - num_vars: Cell<uint>, - live_node_map: RefCell<NodeMap<LiveNode>>, - variable_map: RefCell<NodeMap<Variable>>, - capture_info_map: RefCell<NodeMap<@Vec<CaptureInfo> >>, - var_kinds: RefCell<Vec<VarKind> >, - lnks: RefCell<Vec<LiveNodeKind> >, + num_live_nodes: uint, + num_vars: uint, + live_node_map: NodeMap<LiveNode>, + variable_map: NodeMap<Variable>, + capture_info_map: NodeMap<Rc<Vec<CaptureInfo>>>, + var_kinds: Vec<VarKind>, + lnks: Vec<LiveNodeKind>, } fn IrMaps<'a>(tcx: &'a ty::ctxt, @@ -273,23 +268,21 @@ fn IrMaps<'a>(tcx: &'a ty::ctxt, tcx: tcx, method_map: method_map, capture_map: capture_map, - num_live_nodes: Cell::new(0), - num_vars: Cell::new(0), - live_node_map: RefCell::new(NodeMap::new()), - variable_map: RefCell::new(NodeMap::new()), - capture_info_map: RefCell::new(NodeMap::new()), - var_kinds: RefCell::new(Vec::new()), - lnks: RefCell::new(Vec::new()), + num_live_nodes: 0, + num_vars: 0, + live_node_map: NodeMap::new(), + variable_map: NodeMap::new(), + capture_info_map: NodeMap::new(), + var_kinds: Vec::new(), + lnks: Vec::new(), } } impl<'a> IrMaps<'a> { - pub fn add_live_node(&self, lnk: LiveNodeKind) -> LiveNode { - let num_live_nodes = self.num_live_nodes.get(); - let ln = LiveNode(num_live_nodes); - let mut lnks = self.lnks.borrow_mut(); - lnks.get().push(lnk); - self.num_live_nodes.set(num_live_nodes + 1); + fn add_live_node(&mut self, lnk: LiveNodeKind) -> LiveNode { + let ln = LiveNode(self.num_live_nodes); + self.lnks.push(lnk); + self.num_live_nodes += 1; debug!("{} is of kind {}", ln.to_str(), live_node_kind_to_str(lnk, self.tcx)); @@ -297,26 +290,21 @@ impl<'a> IrMaps<'a> { ln } - pub fn add_live_node_for_node(&self, node_id: NodeId, lnk: LiveNodeKind) { + fn add_live_node_for_node(&mut self, node_id: NodeId, lnk: LiveNodeKind) { let ln = self.add_live_node(lnk); - let mut live_node_map = self.live_node_map.borrow_mut(); - live_node_map.get().insert(node_id, ln); + self.live_node_map.insert(node_id, ln); debug!("{} is node {}", ln.to_str(), node_id); } - pub fn add_variable(&self, vk: VarKind) -> Variable { - let v = Variable(self.num_vars.get()); - { - let mut var_kinds = self.var_kinds.borrow_mut(); - var_kinds.get().push(vk); - } - self.num_vars.set(self.num_vars.get() + 1); + fn add_variable(&mut self, vk: VarKind) -> Variable { + let v = Variable(self.num_vars); + self.var_kinds.push(vk); + self.num_vars += 1; match vk { Local(LocalInfo { id: node_id, .. }) | Arg(node_id, _) => { - let mut variable_map = self.variable_map.borrow_mut(); - variable_map.get().insert(node_id, v); + self.variable_map.insert(node_id, v); }, ImplicitRet => {} } @@ -326,9 +314,8 @@ impl<'a> IrMaps<'a> { v } - pub fn variable(&self, node_id: NodeId, span: Span) -> Variable { - let variable_map = self.variable_map.borrow(); - match variable_map.get().find(&node_id) { + fn variable(&self, node_id: NodeId, span: Span) -> Variable { + match self.variable_map.find(&node_id) { Some(&var) => var, None => { self.tcx.sess.span_bug( @@ -337,9 +324,8 @@ impl<'a> IrMaps<'a> { } } - pub fn variable_name(&self, var: Variable) -> ~str { - let var_kinds = self.var_kinds.borrow(); - match var_kinds.get().get(var.get()) { + fn variable_name(&self, var: Variable) -> ~str { + match self.var_kinds.get(var.get()) { &Local(LocalInfo { ident: nm, .. }) | &Arg(_, nm) => { token::get_ident(nm).get().to_str() }, @@ -347,24 +333,12 @@ impl<'a> IrMaps<'a> { } } - pub fn set_captures(&self, node_id: NodeId, cs: Vec<CaptureInfo> ) { - let mut capture_info_map = self.capture_info_map.borrow_mut(); - capture_info_map.get().insert(node_id, @cs); + fn set_captures(&mut self, node_id: NodeId, cs: Vec<CaptureInfo>) { + self.capture_info_map.insert(node_id, Rc::new(cs)); } - pub fn captures(&self, expr: &Expr) -> @Vec<CaptureInfo> { - let capture_info_map = self.capture_info_map.borrow(); - match capture_info_map.get().find(&expr.id) { - Some(&caps) => caps, - None => { - self.tcx.sess.span_bug(expr.span, "no registered caps"); - } - } - } - - pub fn lnk(&self, ln: LiveNode) -> LiveNodeKind { - let lnks = self.lnks.borrow(); - *lnks.get().get(ln.get()) + fn lnk(&self, ln: LiveNode) -> LiveNodeKind { + *self.lnks.get(ln.get()) } } @@ -383,25 +357,24 @@ impl<'a> Visitor<()> for Liveness<'a> { } } -fn visit_fn(v: &mut LivenessVisitor, +fn visit_fn(ir: &mut IrMaps, fk: &FnKind, decl: &FnDecl, body: &Block, sp: Span, - id: NodeId, - this: @IrMaps) { + id: NodeId) { debug!("visit_fn: id={}", id); let _i = ::util::common::indenter(); // swap in a new set of IR maps for this function body: - let fn_maps = @IrMaps(this.tcx, this.method_map, this.capture_map); + let mut fn_maps = IrMaps(ir.tcx, ir.method_map, ir.capture_map); unsafe { - debug!("creating fn_maps: {}", transmute::<&IrMaps, *IrMaps>(fn_maps)); + debug!("creating fn_maps: {}", transmute::<&IrMaps, *IrMaps>(&fn_maps)); } for arg in decl.inputs.iter() { - pat_util::pat_bindings(this.tcx.def_map, + pat_util::pat_bindings(ir.tcx.def_map, arg.pat, |_bm, arg_id, _x, path| { debug!("adding argument {}", arg_id); @@ -412,7 +385,7 @@ fn visit_fn(v: &mut LivenessVisitor, // gather up the various local variables, significant expressions, // and so forth: - visit::walk_fn(v, fk, decl, body, sp, id, fn_maps); + visit::walk_fn(&mut fn_maps, fk, decl, body, sp, id, ()); // Special nodes and variables: // - exit_ln represents the end of the fn, either by return or fail @@ -425,7 +398,7 @@ fn visit_fn(v: &mut LivenessVisitor, }; // compute liveness - let mut lsets = Liveness(fn_maps, specials); + let mut lsets = Liveness(&mut fn_maps, specials); let entry_ln = lsets.compute(decl, body); // check for various error conditions @@ -434,12 +407,11 @@ fn visit_fn(v: &mut LivenessVisitor, lsets.warn_about_unused_args(decl, entry_ln); } -fn visit_local(v: &mut LivenessVisitor, local: &Local, this: @IrMaps) { - let def_map = this.tcx.def_map; - pat_util::pat_bindings(def_map, local.pat, |bm, p_id, sp, path| { +fn visit_local(ir: &mut IrMaps, local: &Local) { + pat_util::pat_bindings(ir.tcx.def_map, local.pat, |bm, p_id, sp, path| { debug!("adding local variable {}", p_id); let name = ast_util::path_to_ident(path); - this.add_live_node_for_node(p_id, VarDefNode(sp)); + ir.add_live_node_for_node(p_id, VarDefNode(sp)); let kind = match local.init { Some(_) => FromLetWithInitializer, None => FromLetNoInitializer @@ -448,20 +420,19 @@ fn visit_local(v: &mut LivenessVisitor, local: &Local, this: @IrMaps) { BindByValue(MutMutable) => true, _ => false }; - this.add_variable(Local(LocalInfo { + ir.add_variable(Local(LocalInfo { id: p_id, ident: name, is_mutbl: mutbl, kind: kind })); }); - visit::walk_local(v, local, this); + visit::walk_local(ir, local, ()); } -fn visit_arm(v: &mut LivenessVisitor, arm: &Arm, this: @IrMaps) { - let def_map = this.tcx.def_map; +fn visit_arm(ir: &mut IrMaps, arm: &Arm) { for pat in arm.pats.iter() { - pat_util::pat_bindings(def_map, *pat, |bm, p_id, sp, path| { + pat_util::pat_bindings(ir.tcx.def_map, *pat, |bm, p_id, sp, path| { debug!("adding local variable {} from match with bm {:?}", p_id, bm); let name = ast_util::path_to_ident(path); @@ -469,8 +440,8 @@ fn visit_arm(v: &mut LivenessVisitor, arm: &Arm, this: @IrMaps) { BindByValue(MutMutable) => true, _ => false }; - this.add_live_node_for_node(p_id, VarDefNode(sp)); - this.add_variable(Local(LocalInfo { + ir.add_live_node_for_node(p_id, VarDefNode(sp)); + ir.add_variable(Local(LocalInfo { id: p_id, ident: name, is_mutbl: mutbl, @@ -478,37 +449,34 @@ fn visit_arm(v: &mut LivenessVisitor, arm: &Arm, this: @IrMaps) { })); }) } - visit::walk_arm(v, arm, this); + visit::walk_arm(ir, arm, ()); } -fn visit_expr(v: &mut LivenessVisitor, expr: &Expr, this: @IrMaps) { +fn visit_expr(ir: &mut IrMaps, expr: &Expr) { match expr.node { // live nodes required for uses or definitions of variables: ExprPath(_) => { - let def_map = this.tcx.def_map.borrow(); - let def = def_map.get().get_copy(&expr.id); + let def = ir.tcx.def_map.borrow().get().get_copy(&expr.id); debug!("expr {}: path that leads to {:?}", expr.id, def); if moves::moved_variable_node_id_from_def(def).is_some() { - this.add_live_node_for_node(expr.id, ExprNode(expr.span)); + ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); } - visit::walk_expr(v, expr, this); + visit::walk_expr(ir, expr, ()); } ExprFnBlock(..) | ExprProc(..) => { // Interesting control flow (for loops can contain labeled // breaks or continues) - this.add_live_node_for_node(expr.id, ExprNode(expr.span)); + ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); // Make a live_node for each captured variable, with the span // being the location that the variable is used. This results // in better error messages than just pointing at the closure // construction site. - let capture_map = this.capture_map.borrow(); - let cvs = capture_map.get().get(&expr.id); let mut call_caps = Vec::new(); - for cv in cvs.deref().iter() { + for cv in ir.capture_map.borrow().get().get(&expr.id).deref().iter() { match moves::moved_variable_node_id_from_def(cv.def) { Some(rv) => { - let cv_ln = this.add_live_node(FreeVarNode(cv.span)); + let cv_ln = ir.add_live_node(FreeVarNode(cv.span)); let is_move = match cv.mode { // var must be dead afterwards moves::CapMove => true, @@ -523,20 +491,20 @@ fn visit_expr(v: &mut LivenessVisitor, expr: &Expr, this: @IrMaps) { None => {} } } - this.set_captures(expr.id, call_caps); + ir.set_captures(expr.id, call_caps); - visit::walk_expr(v, expr, this); + visit::walk_expr(ir, expr, ()); } // live nodes required for interesting control flow: ExprIf(..) | ExprMatch(..) | ExprWhile(..) | ExprLoop(..) => { - this.add_live_node_for_node(expr.id, ExprNode(expr.span)); - visit::walk_expr(v, expr, this); + ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); + visit::walk_expr(ir, expr, ()); } ExprForLoop(..) => fail!("non-desugared expr_for_loop"), ExprBinary(op, _, _) if ast_util::lazy_binop(op) => { - this.add_live_node_for_node(expr.id, ExprNode(expr.span)); - visit::walk_expr(v, expr, this); + ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); + visit::walk_expr(ir, expr, ()); } // otherwise, live nodes are not required: @@ -548,7 +516,7 @@ fn visit_expr(v: &mut LivenessVisitor, expr: &Expr, this: @IrMaps) { ExprAssign(..) | ExprAssignOp(..) | ExprMac(..) | ExprStruct(..) | ExprRepeat(..) | ExprParen(..) | ExprInlineAsm(..) | ExprBox(..) => { - visit::walk_expr(v, expr, this); + visit::walk_expr(ir, expr, ()); } } } @@ -560,7 +528,7 @@ fn visit_expr(v: &mut LivenessVisitor, expr: &Expr, this: @IrMaps) { // the same basic propagation framework in all cases. #[deriving(Clone)] -pub struct Users { +struct Users { reader: LiveNode, writer: LiveNode, used: bool @@ -574,7 +542,7 @@ fn invalid_users() -> Users { } } -pub struct Specials { +struct Specials { exit_ln: LiveNode, fallthrough_ln: LiveNode, no_ret_var: Variable @@ -584,76 +552,66 @@ static ACC_READ: uint = 1u; static ACC_WRITE: uint = 2u; static ACC_USE: uint = 4u; -pub type LiveNodeMap = @RefCell<NodeMap<LiveNode>>; - -pub struct Liveness<'a> { - tcx: &'a ty::ctxt, - ir: @IrMaps<'a>, +struct Liveness<'a> { + ir: &'a mut IrMaps<'a>, s: Specials, - successors: @RefCell<Vec<LiveNode> >, - users: @RefCell<Vec<Users> >, + successors: Vec<LiveNode>, + users: Vec<Users>, // The list of node IDs for the nested loop scopes // we're in. - loop_scope: @RefCell<Vec<NodeId> >, + loop_scope: Vec<NodeId>, // mappings from loop node ID to LiveNode // ("break" label should map to loop node ID, // it probably doesn't now) - break_ln: LiveNodeMap, - cont_ln: LiveNodeMap + break_ln: NodeMap<LiveNode>, + cont_ln: NodeMap<LiveNode> } -fn Liveness<'a>(ir: @IrMaps<'a>, specials: Specials) -> Liveness<'a> { +fn Liveness<'a>(ir: &'a mut IrMaps<'a>, specials: Specials) -> Liveness<'a> { Liveness { ir: ir, - tcx: ir.tcx, s: specials, - successors: @RefCell::new(Vec::from_elem(ir.num_live_nodes.get(), - invalid_node())), - users: @RefCell::new(Vec::from_elem(ir.num_live_nodes.get() * - ir.num_vars.get(), - invalid_users())), - loop_scope: @RefCell::new(Vec::new()), - break_ln: @RefCell::new(NodeMap::new()), - cont_ln: @RefCell::new(NodeMap::new()), + successors: Vec::from_elem(ir.num_live_nodes, invalid_node()), + users: Vec::from_elem(ir.num_live_nodes * ir.num_vars, invalid_users()), + loop_scope: Vec::new(), + break_ln: NodeMap::new(), + cont_ln: NodeMap::new(), } } impl<'a> Liveness<'a> { - pub fn live_node(&self, node_id: NodeId, span: Span) -> LiveNode { - let ir: &IrMaps = self.ir; - let live_node_map = ir.live_node_map.borrow(); - match live_node_map.get().find(&node_id) { + fn live_node(&self, node_id: NodeId, span: Span) -> LiveNode { + match self.ir.live_node_map.find(&node_id) { Some(&ln) => ln, None => { // This must be a mismatch between the ir_map construction // above and the propagation code below; the two sets of // code have to agree about which AST nodes are worth // creating liveness nodes for. - self.tcx.sess.span_bug( + self.ir.tcx.sess.span_bug( span, format!("no live node registered for node {}", node_id)); } } } - pub fn variable(&self, node_id: NodeId, span: Span) -> Variable { + fn variable(&self, node_id: NodeId, span: Span) -> Variable { self.ir.variable(node_id, span) } - pub fn pat_bindings(&self, - pat: @Pat, - f: |LiveNode, Variable, Span, NodeId|) { - let def_map = self.tcx.def_map; - pat_util::pat_bindings(def_map, pat, |_bm, p_id, sp, _n| { + fn pat_bindings(&mut self, + pat: &Pat, + f: |&mut Liveness<'a>, LiveNode, Variable, Span, NodeId|) { + pat_util::pat_bindings(self.ir.tcx.def_map, pat, |_bm, p_id, sp, _n| { let ln = self.live_node(p_id, sp); let var = self.variable(p_id, sp); - f(ln, var, sp, p_id); + f(self, ln, var, sp, p_id); }) } - pub fn arm_pats_bindings(&self, - pats: &[@Pat], - f: |LiveNode, Variable, Span, NodeId|) { + fn arm_pats_bindings(&mut self, + pats: &[@Pat], + f: |&mut Liveness<'a>, LiveNode, Variable, Span, NodeId|) { // only consider the first pattern; any later patterns must have // the same bindings, and we also consider the first pattern to be // the "authoratative" set of ids @@ -662,86 +620,77 @@ impl<'a> Liveness<'a> { } } - pub fn define_bindings_in_pat(&self, pat: @Pat, succ: LiveNode) - -> LiveNode { + fn define_bindings_in_pat(&mut self, pat: @Pat, succ: LiveNode) + -> LiveNode { self.define_bindings_in_arm_pats([pat], succ) } - pub fn define_bindings_in_arm_pats(&self, pats: &[@Pat], succ: LiveNode) - -> LiveNode { + fn define_bindings_in_arm_pats(&mut self, pats: &[@Pat], succ: LiveNode) + -> LiveNode { let mut succ = succ; - self.arm_pats_bindings(pats, |ln, var, _sp, _id| { - self.init_from_succ(ln, succ); - self.define(ln, var); + self.arm_pats_bindings(pats, |this, ln, var, _sp, _id| { + this.init_from_succ(ln, succ); + this.define(ln, var); succ = ln; }); succ } - pub fn idx(&self, ln: LiveNode, var: Variable) -> uint { - ln.get() * self.ir.num_vars.get() + var.get() + fn idx(&self, ln: LiveNode, var: Variable) -> uint { + ln.get() * self.ir.num_vars + var.get() } - pub fn live_on_entry(&self, ln: LiveNode, var: Variable) - -> Option<LiveNodeKind> { + fn live_on_entry(&self, ln: LiveNode, var: Variable) + -> Option<LiveNodeKind> { assert!(ln.is_valid()); - let users = self.users.borrow(); - let reader = users.get().get(self.idx(ln, var)).reader; + let reader = self.users.get(self.idx(ln, var)).reader; if reader.is_valid() {Some(self.ir.lnk(reader))} else {None} } /* Is this variable live on entry to any of its successor nodes? */ - pub fn live_on_exit(&self, ln: LiveNode, var: Variable) - -> Option<LiveNodeKind> { - let successor = { - let successors = self.successors.borrow(); - *successors.get().get(ln.get()) - }; + fn live_on_exit(&self, ln: LiveNode, var: Variable) + -> Option<LiveNodeKind> { + let successor = *self.successors.get(ln.get()); self.live_on_entry(successor, var) } - pub fn used_on_entry(&self, ln: LiveNode, var: Variable) -> bool { + fn used_on_entry(&self, ln: LiveNode, var: Variable) -> bool { assert!(ln.is_valid()); - let users = self.users.borrow(); - users.get().get(self.idx(ln, var)).used + self.users.get(self.idx(ln, var)).used } - pub fn assigned_on_entry(&self, ln: LiveNode, var: Variable) - -> Option<LiveNodeKind> { + fn assigned_on_entry(&self, ln: LiveNode, var: Variable) + -> Option<LiveNodeKind> { assert!(ln.is_valid()); - let users = self.users.borrow(); - let writer = users.get().get(self.idx(ln, var)).writer; + let writer = self.users.get(self.idx(ln, var)).writer; if writer.is_valid() {Some(self.ir.lnk(writer))} else {None} } - pub fn assigned_on_exit(&self, ln: LiveNode, var: Variable) - -> Option<LiveNodeKind> { - let successor = { - let successors = self.successors.borrow(); - *successors.get().get(ln.get()) - }; + fn assigned_on_exit(&self, ln: LiveNode, var: Variable) + -> Option<LiveNodeKind> { + let successor = *self.successors.get(ln.get()); self.assigned_on_entry(successor, var) } - pub fn indices2(&self, - ln: LiveNode, - succ_ln: LiveNode, - op: |uint, uint|) { + fn indices2(&mut self, + ln: LiveNode, + succ_ln: LiveNode, + op: |&mut Liveness<'a>, uint, uint|) { let node_base_idx = self.idx(ln, Variable(0u)); let succ_base_idx = self.idx(succ_ln, Variable(0u)); - for var_idx in range(0u, self.ir.num_vars.get()) { - op(node_base_idx + var_idx, succ_base_idx + var_idx); + for var_idx in range(0u, self.ir.num_vars) { + op(self, node_base_idx + var_idx, succ_base_idx + var_idx); } } - pub fn write_vars(&self, - wr: &mut io::Writer, - ln: LiveNode, - test: |uint| -> LiveNode) -> io::IoResult<()> { + fn write_vars(&self, + wr: &mut io::Writer, + ln: LiveNode, + test: |uint| -> LiveNode) -> io::IoResult<()> { let node_base_idx = self.idx(ln, Variable(0)); - for var_idx in range(0u, self.ir.num_vars.get()) { + for var_idx in range(0u, self.ir.num_vars) { let idx = node_base_idx + var_idx; if test(idx).is_valid() { try!(write!(wr, " {}", Variable(var_idx).to_str())); @@ -750,28 +699,26 @@ impl<'a> Liveness<'a> { Ok(()) } - pub fn find_loop_scope(&self, - opt_label: Option<Ident>, - id: NodeId, - sp: Span) - -> NodeId { + fn find_loop_scope(&self, + opt_label: Option<Ident>, + id: NodeId, + sp: Span) + -> NodeId { match opt_label { Some(_) => { // Refers to a labeled loop. Use the results of resolve // to find with one - let def_map = self.tcx.def_map.borrow(); - match def_map.get().find(&id) { + match self.ir.tcx.def_map.borrow().get().find(&id) { Some(&DefLabel(loop_id)) => loop_id, - _ => self.tcx.sess.span_bug(sp, "label on break/loop \ - doesn't refer to a loop") + _ => self.ir.tcx.sess.span_bug(sp, "label on break/loop \ + doesn't refer to a loop") } } None => { // Vanilla 'break' or 'loop', so use the enclosing // loop scope - let loop_scope = self.loop_scope.borrow(); - if loop_scope.get().len() == 0 { - self.tcx.sess.span_bug(sp, "break outside loop"); + if self.loop_scope.len() == 0 { + self.ir.tcx.sess.span_bug(sp, "break outside loop"); } else { // FIXME(#5275): this shouldn't have to be a method... self.last_loop_scope() @@ -780,54 +727,26 @@ impl<'a> Liveness<'a> { } } - pub fn last_loop_scope(&self) -> NodeId { - let loop_scope = self.loop_scope.borrow(); - *loop_scope.get().last().unwrap() + fn last_loop_scope(&self) -> NodeId { + *self.loop_scope.last().unwrap() } #[allow(unused_must_use)] - pub fn ln_str(&self, ln: LiveNode) -> ~str { + fn ln_str(&self, ln: LiveNode) -> ~str { let mut wr = io::MemWriter::new(); { let wr = &mut wr as &mut io::Writer; - { - let lnks = self.ir.lnks.try_borrow(); - write!(wr, - "[ln({}) of kind {:?} reads", - ln.get(), - lnks.and_then(|lnks| Some(*lnks.get().get(ln.get())))); - } - let users = self.users.try_borrow(); - match users { - Some(users) => { - self.write_vars(wr, ln, |idx| users.get().get(idx).reader); - write!(wr, " writes"); - self.write_vars(wr, ln, |idx| users.get().get(idx).writer); - } - None => { - write!(wr, " (users borrowed)"); - } - } - let successors = self.successors.try_borrow(); - match successors { - Some(successors) => { - write!(wr, - " precedes {}]", - successors.get().get(ln.get()).to_str()); - } - None => { - write!(wr, " precedes (successors borrowed)]"); - } - } + write!(wr, "[ln({}) of kind {:?} reads", ln.get(), self.ir.lnk(ln)); + self.write_vars(wr, ln, |idx| self.users.get(idx).reader); + write!(wr, " writes"); + self.write_vars(wr, ln, |idx| self.users.get(idx).writer); + write!(wr, " precedes {}]", self.successors.get(ln.get()).to_str()); } str::from_utf8_owned(wr.unwrap()).unwrap() } - pub fn init_empty(&self, ln: LiveNode, succ_ln: LiveNode) { - { - let mut successors = self.successors.borrow_mut(); - *successors.get().get_mut(ln.get()) = succ_ln; - } + fn init_empty(&mut self, ln: LiveNode, succ_ln: LiveNode) { + *self.successors.get_mut(ln.get()) = succ_ln; // It is not necessary to initialize the // values to empty because this is the value @@ -839,37 +758,32 @@ impl<'a> Liveness<'a> { // } } - pub fn init_from_succ(&self, ln: LiveNode, succ_ln: LiveNode) { + fn init_from_succ(&mut self, ln: LiveNode, succ_ln: LiveNode) { // more efficient version of init_empty() / merge_from_succ() - { - let mut successors = self.successors.borrow_mut(); - *successors.get().get_mut(ln.get()) = succ_ln; - } + *self.successors.get_mut(ln.get()) = succ_ln; - self.indices2(ln, succ_ln, |idx, succ_idx| { - let mut users = self.users.borrow_mut(); - *users.get().get_mut(idx) = *users.get().get(succ_idx) + self.indices2(ln, succ_ln, |this, idx, succ_idx| { + *this.users.get_mut(idx) = *this.users.get(succ_idx) }); debug!("init_from_succ(ln={}, succ={})", self.ln_str(ln), self.ln_str(succ_ln)); } - pub fn merge_from_succ(&self, - ln: LiveNode, - succ_ln: LiveNode, - first_merge: bool) - -> bool { + fn merge_from_succ(&mut self, + ln: LiveNode, + succ_ln: LiveNode, + first_merge: bool) + -> bool { if ln == succ_ln { return false; } let mut changed = false; - self.indices2(ln, succ_ln, |idx, succ_idx| { - let mut users = self.users.borrow_mut(); - changed |= copy_if_invalid(users.get().get(succ_idx).reader, - &mut users.get().get_mut(idx).reader); - changed |= copy_if_invalid(users.get().get(succ_idx).writer, - &mut users.get().get_mut(idx).writer); - if users.get().get(succ_idx).used && !users.get().get(idx).used { - users.get().get_mut(idx).used = true; + self.indices2(ln, succ_ln, |this, idx, succ_idx| { + changed |= copy_if_invalid(this.users.get(succ_idx).reader, + &mut this.users.get_mut(idx).reader); + changed |= copy_if_invalid(this.users.get(succ_idx).writer, + &mut this.users.get_mut(idx).writer); + if this.users.get(succ_idx).used && !this.users.get(idx).used { + this.users.get_mut(idx).used = true; changed = true; } }); @@ -879,34 +793,34 @@ impl<'a> Liveness<'a> { return changed; fn copy_if_invalid(src: LiveNode, dst: &mut LiveNode) -> bool { - if src.is_valid() { - if !dst.is_valid() { - *dst = src; - return true; - } + if src.is_valid() && !dst.is_valid() { + *dst = src; + true + } else { + false } - return false; } } // Indicates that a local variable was *defined*; we know that no // uses of the variable can precede the definition (resolve checks // this) so we just clear out all the data. - pub fn define(&self, writer: LiveNode, var: Variable) { + fn define(&mut self, writer: LiveNode, var: Variable) { let idx = self.idx(writer, var); - let mut users = self.users.borrow_mut(); - users.get().get_mut(idx).reader = invalid_node(); - users.get().get_mut(idx).writer = invalid_node(); + self.users.get_mut(idx).reader = invalid_node(); + self.users.get_mut(idx).writer = invalid_node(); debug!("{} defines {} (idx={}): {}", writer.to_str(), var.to_str(), idx, self.ln_str(writer)); } // Either read, write, or both depending on the acc bitset - pub fn acc(&self, ln: LiveNode, var: Variable, acc: uint) { + fn acc(&mut self, ln: LiveNode, var: Variable, acc: uint) { + debug!("{} accesses[{:x}] {}: {}", + ln.to_str(), acc, var.to_str(), self.ln_str(ln)); + let idx = self.idx(ln, var); - let mut users = self.users.borrow_mut(); - let user = users.get().get_mut(idx); + let user = self.users.get_mut(idx); if (acc & ACC_WRITE) != 0 { user.reader = invalid_node(); @@ -922,14 +836,11 @@ impl<'a> Liveness<'a> { if (acc & ACC_USE) != 0 { user.used = true; } - - debug!("{} accesses[{:x}] {}: {}", - ln.to_str(), acc, var.to_str(), self.ln_str(ln)); } // _______________________________________________________________________ - pub fn compute(&self, decl: &FnDecl, body: &Block) -> LiveNode { + fn compute(&mut self, decl: &FnDecl, body: &Block) -> LiveNode { // if there is a `break` or `again` at the top level, then it's // effectively a return---this only occurs in `for` loops, // where the body is really a closure. @@ -938,12 +849,12 @@ impl<'a> Liveness<'a> { let entry_ln: LiveNode = self.with_loop_nodes(body.id, self.s.exit_ln, self.s.exit_ln, - || { self.propagate_through_fn_block(decl, body) }); + |this| this.propagate_through_fn_block(decl, body)); // hack to skip the loop unless debug! is enabled: debug!("^^ liveness computation results for body {} (entry={})", { - for ln_idx in range(0u, self.ir.num_live_nodes.get()) { + for ln_idx in range(0u, self.ir.num_live_nodes) { debug!("{}", self.ln_str(LiveNode(ln_idx))); } body.id @@ -953,8 +864,8 @@ impl<'a> Liveness<'a> { entry_ln } - pub fn propagate_through_fn_block(&self, _: &FnDecl, blk: &Block) - -> LiveNode { + fn propagate_through_fn_block(&mut self, _: &FnDecl, blk: &Block) + -> LiveNode { // the fallthrough exit is only for those cases where we do not // explicitly return: self.init_from_succ(self.s.fallthrough_ln, self.s.exit_ln); @@ -965,33 +876,33 @@ impl<'a> Liveness<'a> { self.propagate_through_block(blk, self.s.fallthrough_ln) } - pub fn propagate_through_block(&self, blk: &Block, succ: LiveNode) - -> LiveNode { + fn propagate_through_block(&mut self, blk: &Block, succ: LiveNode) + -> LiveNode { let succ = self.propagate_through_opt_expr(blk.expr, succ); blk.stmts.rev_iter().fold(succ, |succ, stmt| { self.propagate_through_stmt(*stmt, succ) }) } - pub fn propagate_through_stmt(&self, stmt: &Stmt, succ: LiveNode) - -> LiveNode { + fn propagate_through_stmt(&mut self, stmt: &Stmt, succ: LiveNode) + -> LiveNode { match stmt.node { - StmtDecl(decl, _) => { - return self.propagate_through_decl(decl, succ); - } + StmtDecl(decl, _) => { + self.propagate_through_decl(decl, succ) + } - StmtExpr(expr, _) | StmtSemi(expr, _) => { - return self.propagate_through_expr(expr, succ); - } + StmtExpr(expr, _) | StmtSemi(expr, _) => { + self.propagate_through_expr(expr, succ) + } - StmtMac(..) => { - self.tcx.sess.span_bug(stmt.span, "unexpanded macro"); - } + StmtMac(..) => { + self.ir.tcx.sess.span_bug(stmt.span, "unexpanded macro"); + } } } - pub fn propagate_through_decl(&self, decl: &Decl, succ: LiveNode) - -> LiveNode { + fn propagate_through_decl(&mut self, decl: &Decl, succ: LiveNode) + -> LiveNode { match decl.node { DeclLocal(ref local) => { self.propagate_through_local(*local, succ) @@ -1000,8 +911,8 @@ impl<'a> Liveness<'a> { } } - pub fn propagate_through_local(&self, local: &Local, succ: LiveNode) - -> LiveNode { + fn propagate_through_local(&mut self, local: &Local, succ: LiveNode) + -> LiveNode { // Note: we mark the variable as defined regardless of whether // there is an initializer. Initially I had thought to only mark // the live variable as defined if it was initialized, and then we @@ -1020,24 +931,24 @@ impl<'a> Liveness<'a> { self.define_bindings_in_pat(local.pat, succ) } - pub fn propagate_through_exprs(&self, exprs: &[@Expr], succ: LiveNode) - -> LiveNode { + fn propagate_through_exprs(&mut self, exprs: &[@Expr], succ: LiveNode) + -> LiveNode { exprs.rev_iter().fold(succ, |succ, expr| { self.propagate_through_expr(*expr, succ) }) } - pub fn propagate_through_opt_expr(&self, - opt_expr: Option<@Expr>, - succ: LiveNode) - -> LiveNode { + fn propagate_through_opt_expr(&mut self, + opt_expr: Option<@Expr>, + succ: LiveNode) + -> LiveNode { opt_expr.iter().fold(succ, |succ, expr| { self.propagate_through_expr(*expr, succ) }) } - pub fn propagate_through_expr(&self, expr: @Expr, succ: LiveNode) - -> LiveNode { + fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode) + -> LiveNode { debug!("propagate_through_expr: {}", expr_to_str(expr)); match expr.node { @@ -1058,16 +969,21 @@ impl<'a> Liveness<'a> { The next-node for a break is the successor of the entire loop. The next-node for a continue is the top of this loop. */ - self.with_loop_nodes(blk.id, succ, - self.live_node(expr.id, expr.span), || { + let node = self.live_node(expr.id, expr.span); + self.with_loop_nodes(blk.id, succ, node, |this| { // the construction of a closure itself is not important, // but we have to consider the closed over variables. - let caps = self.ir.captures(expr); - caps.rev_iter().fold(succ, |succ, cap| { - self.init_from_succ(cap.ln, succ); - let var = self.variable(cap.var_nid, expr.span); - self.acc(cap.ln, var, ACC_READ | ACC_USE); + let caps = match this.ir.capture_info_map.find(&expr.id) { + Some(caps) => caps.clone(), + None => { + this.ir.tcx.sess.span_bug(expr.span, "no registered caps"); + } + }; + caps.deref().rev_iter().fold(succ, |succ, cap| { + this.init_from_succ(cap.ln, succ); + let var = this.variable(cap.var_nid, expr.span); + this.acc(cap.ln, var, ACC_READ | ACC_USE); cap.ln }) }) @@ -1151,11 +1067,10 @@ impl<'a> Liveness<'a> { // Now that we know the label we're going to, // look it up in the break loop nodes table - let break_ln = self.break_ln.borrow(); - match break_ln.get().find(&sc) { + match self.break_ln.find(&sc) { Some(&b) => b, - None => self.tcx.sess.span_bug(expr.span, - "break to unknown label") + None => self.ir.tcx.sess.span_bug(expr.span, + "break to unknown label") } } @@ -1166,11 +1081,10 @@ impl<'a> Liveness<'a> { // Now that we know the label we're going to, // look it up in the continue loop nodes table - let cont_ln = self.cont_ln.borrow(); - match cont_ln.get().find(&sc) { + match self.cont_ln.find(&sc) { Some(&b) => b, - None => self.tcx.sess.span_bug(expr.span, - "loop to unknown label") + None => self.ir.tcx.sess.span_bug(expr.span, + "loop to unknown label") } } @@ -1215,7 +1129,7 @@ impl<'a> Liveness<'a> { ExprCall(f, ref args) => { // calling a fn with bot return type means that the fn // will fail, and hence the successors can be ignored - let t_ret = ty::ty_fn_ret(ty::expr_ty(self.tcx, f)); + let t_ret = ty::ty_fn_ret(ty::expr_ty(self.ir.tcx, f)); let succ = if ty::type_is_bot(t_ret) {self.s.exit_ln} else {succ}; let succ = self.propagate_through_exprs(args.as_slice(), succ); @@ -1225,7 +1139,7 @@ impl<'a> Liveness<'a> { ExprMethodCall(_, _, ref args) => { // calling a method with bot return type means that the method // will fail, and hence the successors can be ignored - let t_ret = ty::node_id_to_type(self.tcx, expr.id); + let t_ret = ty::node_id_to_type(self.ir.tcx, expr.id); let succ = if ty::type_is_bot(t_ret) {self.s.exit_ln} else {succ}; self.propagate_through_exprs(args.as_slice(), succ) @@ -1280,15 +1194,15 @@ impl<'a> Liveness<'a> { } ExprMac(..) => { - self.tcx.sess.span_bug(expr.span, "unexpanded macro"); + self.ir.tcx.sess.span_bug(expr.span, "unexpanded macro"); } } } - pub fn propagate_through_lvalue_components(&self, - expr: @Expr, - succ: LiveNode) - -> LiveNode { + fn propagate_through_lvalue_components(&mut self, + expr: &Expr, + succ: LiveNode) + -> LiveNode { // # Lvalues // // In general, the full flow graph structure for an @@ -1346,8 +1260,8 @@ impl<'a> Liveness<'a> { } // see comment on propagate_through_lvalue() - pub fn write_lvalue(&self, expr: &Expr, succ: LiveNode, acc: uint) - -> LiveNode { + fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: uint) + -> LiveNode { match expr.node { ExprPath(_) => self.access_path(expr, succ, acc), @@ -1359,10 +1273,9 @@ impl<'a> Liveness<'a> { } } - pub fn access_path(&self, expr: &Expr, succ: LiveNode, acc: uint) - -> LiveNode { - let def_map = self.tcx.def_map.borrow(); - let def = def_map.get().get_copy(&expr.id); + fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: uint) + -> LiveNode { + let def = self.ir.tcx.def_map.borrow().get().get_copy(&expr.id); match moves::moved_variable_node_id_from_def(def) { Some(nid) => { let ln = self.live_node(expr.id, expr.span); @@ -1377,12 +1290,12 @@ impl<'a> Liveness<'a> { } } - pub fn propagate_through_loop(&self, - expr: &Expr, - cond: Option<@Expr>, - body: &Block, - succ: LiveNode) - -> LiveNode { + fn propagate_through_loop(&mut self, + expr: &Expr, + cond: Option<@Expr>, + body: &Block, + succ: LiveNode) + -> LiveNode { /* @@ -1418,8 +1331,8 @@ impl<'a> Liveness<'a> { expr.id, block_to_str(body)); let cond_ln = self.propagate_through_opt_expr(cond, ln); - let body_ln = self.with_loop_nodes(expr.id, succ, ln, || { - self.propagate_through_block(body, cond_ln) + let body_ln = self.with_loop_nodes(expr.id, succ, ln, |this| { + this.propagate_through_block(body, cond_ln) }); // repeat until fixed point is reached: @@ -1428,37 +1341,24 @@ impl<'a> Liveness<'a> { assert!(cond_ln == self.propagate_through_opt_expr(cond, ln)); assert!(body_ln == self.with_loop_nodes(expr.id, succ, ln, - || { - self.propagate_through_block(body, cond_ln) - })); + |this| this.propagate_through_block(body, cond_ln))); } cond_ln } - pub fn with_loop_nodes<R>( - &self, - loop_node_id: NodeId, - break_ln: LiveNode, - cont_ln: LiveNode, - f: || -> R) - -> R { + fn with_loop_nodes<R>(&mut self, + loop_node_id: NodeId, + break_ln: LiveNode, + cont_ln: LiveNode, + f: |&mut Liveness<'a>| -> R) + -> R { debug!("with_loop_nodes: {} {}", loop_node_id, break_ln.get()); - { - let mut loop_scope = self.loop_scope.borrow_mut(); - loop_scope.get().push(loop_node_id); - } - { - let mut this_break_ln = self.break_ln.borrow_mut(); - let mut this_cont_ln = self.cont_ln.borrow_mut(); - this_break_ln.get().insert(loop_node_id, break_ln); - this_cont_ln.get().insert(loop_node_id, cont_ln); - } - let r = f(); - { - let mut loop_scope = self.loop_scope.borrow_mut(); - loop_scope.get().pop(); - } + self.loop_scope.push(loop_node_id); + self.break_ln.insert(loop_node_id, break_ln); + self.cont_ln.insert(loop_node_id, cont_ln); + let r = f(self); + self.loop_scope.pop(); r } } @@ -1472,7 +1372,7 @@ fn check_local(this: &mut Liveness, local: &Local) { this.warn_about_unused_or_dead_vars_in_pat(local.pat); }, None => { - this.pat_bindings(local.pat, |ln, var, sp, id| { + this.pat_bindings(local.pat, |this, ln, var, sp, id| { this.warn_about_unused(sp, id, ln, var); }) } @@ -1482,7 +1382,7 @@ fn check_local(this: &mut Liveness, local: &Local) { } fn check_arm(this: &mut Liveness, arm: &Arm) { - this.arm_pats_bindings(arm.pats.as_slice(), |ln, var, sp, id| { + this.arm_pats_bindings(arm.pats.as_slice(), |this, ln, var, sp, id| { this.warn_about_unused(sp, id, ln, var); }); visit::walk_arm(this, arm, ()); @@ -1542,37 +1442,30 @@ fn check_fn(_v: &Liveness, // do not check contents of nested fns } -pub enum ReadKind { - PossiblyUninitializedVariable, - PossiblyUninitializedField, - MovedValue, - PartiallyMovedValue -} - impl<'a> Liveness<'a> { - pub fn check_ret(&self, - id: NodeId, - sp: Span, - _fk: &FnKind, - entry_ln: LiveNode, - body: &Block) { + fn check_ret(&self, + id: NodeId, + sp: Span, + _fk: &FnKind, + entry_ln: LiveNode, + body: &Block) { if self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() { // if no_ret_var is live, then we fall off the end of the // function without any kind of return expression: - let t_ret = ty::ty_fn_ret(ty::node_id_to_type(self.tcx, id)); + let t_ret = ty::ty_fn_ret(ty::node_id_to_type(self.ir.tcx, id)); if ty::type_is_nil(t_ret) { // for nil return types, it is ok to not return a value expl. } else if ty::type_is_bot(t_ret) { // for bot return types, not ok. Function should fail. - self.tcx.sess.span_err( + self.ir.tcx.sess.span_err( sp, "some control paths may return"); } else { let ends_with_stmt = match body.expr { None if body.stmts.len() > 0 => match body.stmts.last().unwrap().node { StmtSemi(e, _) => { - let t_stmt = ty::expr_ty(self.tcx, e); + let t_stmt = ty::expr_ty(self.ir.tcx, e); ty::get(t_stmt).sty == ty::get(t_ret).sty }, _ => false @@ -1586,20 +1479,19 @@ impl<'a> Liveness<'a> { hi: last_stmt.span.hi, expn_info: last_stmt.span.expn_info }; - self.tcx.sess.span_note( + self.ir.tcx.sess.span_note( span_semicolon, "consider removing this semicolon:"); } - self.tcx.sess.span_err( + self.ir.tcx.sess.span_err( sp, "not all control paths return a value"); } } } - pub fn check_lvalue(&mut self, expr: @Expr) { + fn check_lvalue(&mut self, expr: &Expr) { match expr.node { ExprPath(_) => { - let def_map = self.tcx.def_map.borrow(); - match def_map.get().get_copy(&expr.id) { + match self.ir.tcx.def_map.borrow().get().get_copy(&expr.id) { DefLocal(nid, _) => { // Assignment to an immutable variable or argument: only legal // if there is no later assignment. If this local is actually @@ -1630,14 +1522,14 @@ impl<'a> Liveness<'a> { } } - pub fn should_warn(&self, var: Variable) -> Option<~str> { + fn should_warn(&self, var: Variable) -> Option<~str> { let name = self.ir.variable_name(var); if name.len() == 0 || name[0] == ('_' as u8) { None } else { Some(name) } } - pub fn warn_about_unused_args(&self, decl: &FnDecl, entry_ln: LiveNode) { + fn warn_about_unused_args(&self, decl: &FnDecl, entry_ln: LiveNode) { for arg in decl.inputs.iter() { - pat_util::pat_bindings(self.tcx.def_map, + pat_util::pat_bindings(self.ir.tcx.def_map, arg.pat, |_bm, p_id, sp, path| { let var = self.variable(p_id, sp); @@ -1650,20 +1542,20 @@ impl<'a> Liveness<'a> { } } - pub fn warn_about_unused_or_dead_vars_in_pat(&self, pat: @Pat) { - self.pat_bindings(pat, |ln, var, sp, id| { - if !self.warn_about_unused(sp, id, ln, var) { - self.warn_about_dead_assign(sp, id, ln, var); + fn warn_about_unused_or_dead_vars_in_pat(&mut self, pat: &Pat) { + self.pat_bindings(pat, |this, ln, var, sp, id| { + if !this.warn_about_unused(sp, id, ln, var) { + this.warn_about_dead_assign(sp, id, ln, var); } }) } - pub fn warn_about_unused(&self, - sp: Span, - id: NodeId, - ln: LiveNode, - var: Variable) - -> bool { + fn warn_about_unused(&self, + sp: Span, + id: NodeId, + ln: LiveNode, + var: Variable) + -> bool { if !self.used_on_entry(ln, var) { let r = self.should_warn(var); for name in r.iter() { @@ -1678,11 +1570,11 @@ impl<'a> Liveness<'a> { }; if is_assigned { - self.tcx.sess.add_lint(UnusedVariable, id, sp, + self.ir.tcx.sess.add_lint(UnusedVariable, id, sp, format!("variable `{}` is assigned to, \ but never used", *name)); } else { - self.tcx.sess.add_lint(UnusedVariable, id, sp, + self.ir.tcx.sess.add_lint(UnusedVariable, id, sp, format!("unused variable: `{}`", *name)); } } @@ -1692,15 +1584,15 @@ impl<'a> Liveness<'a> { } } - pub fn warn_about_dead_assign(&self, - sp: Span, - id: NodeId, - ln: LiveNode, - var: Variable) { + fn warn_about_dead_assign(&self, + sp: Span, + id: NodeId, + ln: LiveNode, + var: Variable) { if self.live_on_exit(ln, var).is_none() { let r = self.should_warn(var); for name in r.iter() { - self.tcx.sess.add_lint(DeadAssignment, id, sp, + self.ir.tcx.sess.add_lint(DeadAssignment, id, sp, format!("value assigned to `{}` is never read", *name)); } } |
