X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=sidebyside;f=src%2Flibrustc%2Fmiddle%2Fliveness.rs;h=490e49d051ee58addee73a8e4b87546a665bafff;hb=814586be57b87a32414b4e3fecc150686513b80f;hp=982c1a945a31482d12857545cbd9abc5e6ab7427;hpb=5c192ae123bb4c6163df37334ad316f542dc39f3;p=rust.git diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 982c1a945a3..490e49d051e 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -103,7 +103,6 @@ */ use middle::def::*; -use middle::freevars; use middle::mem_categorization::Typer; use middle::pat_util; use middle::ty; @@ -116,6 +115,7 @@ use std::rc::Rc; use std::str; use std::uint; +use syntax::ast; use syntax::ast::*; use syntax::codemap::{BytePos, original_sp, Span}; use syntax::parse::token::special_idents; @@ -154,7 +154,7 @@ fn clone(&self) -> LiveNode { } } -#[deriving(PartialEq)] +#[deriving(PartialEq, Show)] enum LiveNodeKind { FreeVarNode(Span), ExprNode(Span), @@ -183,7 +183,7 @@ fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, n: NodeId) { visit_fn(self, fk, fd, b, s, n); } - fn visit_local(&mut self, l: &Local) { visit_local(self, l); } + fn visit_local(&mut self, l: &ast::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); } } @@ -240,11 +240,13 @@ struct CaptureInfo { var_nid: NodeId } +#[deriving(Show)] struct LocalInfo { id: NodeId, ident: Ident } +#[deriving(Show)] enum VarKind { Arg(NodeId, Ident), Local(LocalInfo), @@ -307,7 +309,7 @@ fn add_variable(&mut self, vk: VarKind) -> Variable { ImplicitRet => {} } - debug!("{} is {:?}", v.to_string(), vk); + debug!("{} is {}", v.to_string(), vk); v } @@ -346,7 +348,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Liveness<'a, 'tcx> { fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, n: NodeId) { check_fn(self, fk, fd, b, s, n); } - fn visit_local(&mut self, l: &Local) { + fn visit_local(&mut self, l: &ast::Local) { check_local(self, l); } fn visit_expr(&mut self, ex: &Expr) { @@ -408,7 +410,7 @@ fn visit_fn(ir: &mut IrMaps, lsets.warn_about_unused_args(decl, entry_ln); } -fn visit_local(ir: &mut IrMaps, local: &Local) { +fn visit_local(ir: &mut IrMaps, local: &ast::Local) { pat_util::pat_bindings(&ir.tcx.def_map, &*local.pat, |_, p_id, sp, path1| { debug!("adding local variable {}", p_id); let name = path1.node; @@ -424,7 +426,7 @@ fn visit_local(ir: &mut IrMaps, local: &Local) { fn visit_arm(ir: &mut IrMaps, arm: &Arm) { for pat in arm.pats.iter() { pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| { - debug!("adding local variable {} from match with bm {:?}", + debug!("adding local variable {} from match with bm {}", p_id, bm); let name = path1.node; ir.add_live_node_for_node(p_id, VarDefNode(sp)); @@ -442,7 +444,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { // live nodes required for uses or definitions of variables: ExprPath(_) => { let def = ir.tcx.def_map.borrow().get_copy(&expr.id); - debug!("expr {}: path that leads to {:?}", expr.id, def); + debug!("expr {}: path that leads to {}", expr.id, def); match def { DefLocal(..) => ir.add_live_node_for_node(expr.id, ExprNode(expr.span)), _ => {} @@ -481,9 +483,15 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); visit::walk_expr(ir, expr); } + ExprIfLet(..) => { + ir.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet"); + } + ExprWhileLet(..) => { + ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet"); + } ExprForLoop(ref pat, _, _, _) => { pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| { - debug!("adding local variable {} from for loop with bm {:?}", + debug!("adding local variable {} from for loop with bm {}", p_id, bm); let name = path1.node; ir.add_live_node_for_node(p_id, VarDefNode(sp)); @@ -502,7 +510,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { // otherwise, live nodes are not required: ExprIndex(..) | ExprField(..) | ExprTupField(..) | ExprVec(..) | - ExprCall(..) | ExprMethodCall(..) | ExprTup(..) | + ExprCall(..) | ExprMethodCall(..) | ExprTup(..) | ExprSlice(..) | ExprBinary(..) | ExprAddrOf(..) | ExprCast(..) | ExprUnary(..) | ExprBreak(_) | ExprAgain(_) | ExprLit(_) | ExprRet(..) | ExprBlock(..) | @@ -727,7 +735,7 @@ fn ln_str(&self, ln: LiveNode) -> String { let mut wr = io::MemWriter::new(); { let wr = &mut wr as &mut io::Writer; - write!(wr, "[ln({}) of kind {:?} reads", ln.get(), self.ir.lnk(ln)); + 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); @@ -904,7 +912,7 @@ fn propagate_through_decl(&mut self, decl: &Decl, succ: LiveNode) } } - fn propagate_through_local(&mut self, local: &Local, succ: LiveNode) + fn propagate_through_local(&mut self, local: &ast::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 @@ -1011,10 +1019,18 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode) self.propagate_through_expr(&**cond, ln) } + ExprIfLet(..) => { + self.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet"); + } + ExprWhile(ref cond, ref blk, _) => { self.propagate_through_loop(expr, WhileLoop(&**cond), &**blk, succ) } + ExprWhileLet(..) => { + self.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet"); + } + ExprForLoop(ref pat, ref head, ref blk, _) => { let ln = self.propagate_through_loop(expr, ForLoop(&**pat), &**blk, succ); self.propagate_through_expr(&**head, ln) @@ -1026,7 +1042,7 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode) self.propagate_through_loop(expr, LoopLoop, &**blk, succ) } - ExprMatch(ref e, ref arms) => { + ExprMatch(ref e, ref arms, _) => { // // (e) // | @@ -1175,6 +1191,12 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode) self.propagate_through_expr(&**l, r_succ) } + ExprSlice(ref e1, ref e2, ref e3, _) => { + let succ = e3.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ)); + let succ = e2.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ)); + self.propagate_through_expr(&**e1, succ) + } + ExprAddrOf(_, ref e) | ExprCast(ref e, _) | ExprUnary(_, ref e) | @@ -1393,7 +1415,7 @@ fn with_loop_nodes(&mut self, // _______________________________________________________________________ // Checking for error conditions -fn check_local(this: &mut Liveness, local: &Local) { +fn check_local(this: &mut Liveness, local: &ast::Local) { match local.init { Some(_) => { this.warn_about_unused_or_dead_vars_in_pat(&*local.pat); @@ -1451,6 +1473,8 @@ fn check_expr(this: &mut Liveness, expr: &Expr) { this.pat_bindings(&**pat, |this, ln, var, sp, id| { this.warn_about_unused(sp, id, ln, var); }); + + visit::walk_expr(this, expr); } // no correctness conditions related to liveness @@ -1458,12 +1482,18 @@ fn check_expr(this: &mut Liveness, expr: &Expr) { ExprWhile(..) | ExprLoop(..) | ExprIndex(..) | ExprField(..) | ExprTupField(..) | ExprVec(..) | ExprTup(..) | ExprBinary(..) | ExprCast(..) | ExprUnary(..) | ExprRet(..) | ExprBreak(..) | - ExprAgain(..) | ExprLit(_) | ExprBlock(..) | + ExprAgain(..) | ExprLit(_) | ExprBlock(..) | ExprSlice(..) | ExprMac(..) | ExprAddrOf(..) | ExprStruct(..) | ExprRepeat(..) | ExprParen(..) | ExprFnBlock(..) | ExprProc(..) | ExprUnboxedFn(..) | ExprPath(..) | ExprBox(..) => { visit::walk_expr(this, expr); } + ExprIfLet(..) => { + this.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet"); + } + ExprWhileLet(..) => { + this.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet"); + } } } @@ -1510,11 +1540,12 @@ fn check_ret(&self, sp, "not all control paths return a value"); if ends_with_stmt { let last_stmt = body.stmts.last().unwrap(); - let original_span = original_sp(last_stmt.span, sp); + let original_span = original_sp(self.ir.tcx.sess.codemap(), + last_stmt.span, sp); let span_semicolon = Span { lo: original_span.hi - BytePos(1), hi: original_span.hi, - expn_info: original_span.expn_info + expn_id: original_span.expn_id }; self.ir.tcx.sess.span_note( span_semicolon, "consider removing this semicolon:"); @@ -1600,11 +1631,11 @@ fn warn_about_unused(&self, }; if is_assigned { - self.ir.tcx.sess.add_lint(lint::builtin::UNUSED_VARIABLE, id, sp, + self.ir.tcx.sess.add_lint(lint::builtin::UNUSED_VARIABLES, id, sp, format!("variable `{}` is assigned to, but never used", *name)); } else { - self.ir.tcx.sess.add_lint(lint::builtin::UNUSED_VARIABLE, id, sp, + self.ir.tcx.sess.add_lint(lint::builtin::UNUSED_VARIABLES, id, sp, format!("unused variable: `{}`", *name)); } } @@ -1622,7 +1653,7 @@ fn warn_about_dead_assign(&self, if self.live_on_exit(ln, var).is_none() { let r = self.should_warn(var); for name in r.iter() { - self.ir.tcx.sess.add_lint(lint::builtin::DEAD_ASSIGNMENT, id, sp, + self.ir.tcx.sess.add_lint(lint::builtin::UNUSED_ASSIGNMENTS, id, sp, format!("value assigned to `{}` is never read", *name)); } }