]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/middle/liveness.rs
librustc: Remove all uses of {:?}.
[rust.git] / src / librustc / middle / liveness.rs
index fee6c77a79907a387a3bd9d6fde59f2c2a39696a..490e49d051ee58addee73a8e4b87546a665bafff 100644 (file)
  */
 
 use middle::def::*;
-use middle::freevars;
 use middle::mem_categorization::Typer;
 use middle::pat_util;
 use middle::ty;
 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));
@@ -437,24 +439,15 @@ fn visit_arm(ir: &mut IrMaps, arm: &Arm) {
     visit::walk_arm(ir, arm);
 }
 
-fn moved_variable_node_id_from_def(def: Def) -> Option<NodeId> {
-    match def {
-        DefBinding(nid, _) |
-        DefArg(nid, _) |
-        DefLocal(nid, _) => Some(nid),
-
-      _ => None
-    }
-}
-
 fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
     match expr.node {
       // 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);
-        if moved_variable_node_id_from_def(def).is_some() {
-            ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
+        debug!("expr {}: path that leads to {}", expr.id, def);
+        match def {
+            DefLocal(..) => ir.add_live_node_for_node(expr.id, ExprNode(expr.span)),
+            _ => {}
         }
         visit::walk_expr(ir, expr);
       }
@@ -468,15 +461,15 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
         // in better error messages than just pointing at the closure
         // construction site.
         let mut call_caps = Vec::new();
-        freevars::with_freevars(ir.tcx, expr.id, |freevars| {
+        ty::with_freevars(ir.tcx, expr.id, |freevars| {
             for fv in freevars.iter() {
-                match moved_variable_node_id_from_def(fv.def) {
-                    Some(rv) => {
+                match fv.def {
+                    DefLocal(rv) => {
                         let fv_ln = ir.add_live_node(FreeVarNode(fv.span));
                         call_caps.push(CaptureInfo {ln: fv_ln,
                                                     var_nid: rv});
                     }
-                    None => {}
+                    _ => {}
                 }
             }
         });
@@ -490,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));
@@ -511,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(..) |
@@ -736,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);
@@ -913,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
@@ -1020,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)
@@ -1035,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)
             //       |
@@ -1184,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) |
@@ -1296,9 +1309,8 @@ fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
 
     fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
                    -> LiveNode {
-        let def = self.ir.tcx.def_map.borrow().get_copy(&expr.id);
-        match moved_variable_node_id_from_def(def) {
-          Some(nid) => {
+        match self.ir.tcx.def_map.borrow().get_copy(&expr.id) {
+          DefLocal(nid) => {
             let ln = self.live_node(expr.id, expr.span);
             if acc != 0u {
                 self.init_from_succ(ln, succ);
@@ -1307,7 +1319,7 @@ fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
             }
             ln
           }
-          None => succ
+          _ => succ
         }
     }
 
@@ -1403,7 +1415,7 @@ fn with_loop_nodes<R>(&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);
@@ -1461,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
@@ -1468,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");
+      }
     }
 }
 
@@ -1520,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:");
@@ -1537,7 +1558,7 @@ fn check_lvalue(&mut self, expr: &Expr) {
         match expr.node {
           ExprPath(_) => {
             match self.ir.tcx.def_map.borrow().get_copy(&expr.id) {
-              DefLocal(nid, _) => {
+              DefLocal(nid) => {
                 // Assignment to an immutable variable or argument: only legal
                 // if there is no later assignment. If this local is actually
                 // mutable, then check for a reassignment to flag the mutability
@@ -1546,16 +1567,7 @@ fn check_lvalue(&mut self, expr: &Expr) {
                 let var = self.variable(nid, expr.span);
                 self.warn_about_dead_assign(expr.span, expr.id, ln, var);
               }
-              def => {
-                match moved_variable_node_id_from_def(def) {
-                  Some(nid) => {
-                    let ln = self.live_node(expr.id, expr.span);
-                    let var = self.variable(nid, expr.span);
-                    self.warn_about_dead_assign(expr.span, expr.id, ln, var);
-                  }
-                  None => {}
-                }
-              }
+              _ => {}
             }
           }
 
@@ -1619,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));
                 }
             }
@@ -1641,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));
             }
         }