about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/borrowck/gather_loans/gather_moves.rs17
-rw-r--r--src/librustc/middle/borrowck/gather_loans/mod.rs54
-rw-r--r--src/librustc/middle/borrowck/mod.rs2
-rw-r--r--src/librustc/middle/borrowck/move_data.rs15
-rw-r--r--src/librustc/middle/liveness.rs62
-rw-r--r--src/test/compile-fail/asm-out-read-uninit.rs2
-rw-r--r--src/test/compile-fail/borrowck-and-init.rs (renamed from src/test/compile-fail/liveness-and-init.rs)0
-rw-r--r--src/test/compile-fail/borrowck-block-unint.rs (renamed from src/test/compile-fail/liveness-block-unint.rs)4
-rw-r--r--src/test/compile-fail/borrowck-break-uninit-2.rs (renamed from src/test/compile-fail/liveness-break-uninit-2.rs)0
-rw-r--r--src/test/compile-fail/borrowck-break-uninit.rs (renamed from src/test/compile-fail/liveness-break-uninit.rs)0
-rw-r--r--src/test/compile-fail/borrowck-if-no-else.rs (renamed from src/test/compile-fail/liveness-if-no-else.rs)0
-rw-r--r--src/test/compile-fail/borrowck-if-with-else.rs (renamed from src/test/compile-fail/liveness-if-with-else.rs)0
-rw-r--r--src/test/compile-fail/borrowck-init-in-called-fn-expr.rs (renamed from src/test/compile-fail/liveness-init-in-called-fn-expr.rs)0
-rw-r--r--src/test/compile-fail/borrowck-init-in-fn-expr.rs (renamed from src/test/compile-fail/liveness-init-in-fn-expr.rs)0
-rw-r--r--src/test/compile-fail/borrowck-init-in-fru.rs (renamed from src/test/compile-fail/liveness-init-in-fru.rs)0
-rw-r--r--src/test/compile-fail/borrowck-init-op-equal.rs (renamed from src/test/compile-fail/liveness-init-op-equal.rs)0
-rw-r--r--src/test/compile-fail/borrowck-init-plus-equal.rs (renamed from src/test/compile-fail/liveness-init-plus-equal.rs)0
-rw-r--r--src/test/compile-fail/borrowck-or-init.rs (renamed from src/test/compile-fail/liveness-or-init.rs)0
-rw-r--r--src/test/compile-fail/borrowck-return.rs (renamed from src/test/compile-fail/liveness-return.rs)0
-rw-r--r--src/test/compile-fail/borrowck-uninit-after-item.rs (renamed from src/test/compile-fail/liveness-uninit-after-item.rs)0
-rw-r--r--src/test/compile-fail/borrowck-uninit-in-assignop.rs44
-rw-r--r--src/test/compile-fail/borrowck-uninit.rs (renamed from src/test/compile-fail/liveness-uninit.rs)0
-rw-r--r--src/test/compile-fail/borrowck-use-in-index-lvalue.rs (renamed from src/test/compile-fail/liveness-use-in-index-lvalue.rs)4
-rw-r--r--src/test/compile-fail/borrowck-while-break.rs (renamed from src/test/compile-fail/liveness-while-break.rs)0
-rw-r--r--src/test/compile-fail/borrowck-while-cond.rs (renamed from src/test/compile-fail/liveness-while-cond.rs)0
-rw-r--r--src/test/compile-fail/borrowck-while.rs (renamed from src/test/compile-fail/liveness-while.rs)0
-rw-r--r--src/test/compile-fail/liveness-unused.rs5
27 files changed, 119 insertions, 90 deletions
diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs
index 7ec9f1f8f47..6dd7ae31c9d 100644
--- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs
+++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs
@@ -94,7 +94,22 @@ pub fn gather_assignment(bccx: &BorrowckCtxt,
                              assignee_loan_path,
                              assignment_id,
                              assignment_span,
-                             assignee_id);
+                             assignee_id,
+                             false);
+}
+
+pub fn gather_move_and_assignment(bccx: &BorrowckCtxt,
+                                  move_data: &MoveData,
+                                  assignment_id: ast::NodeId,
+                                  assignment_span: Span,
+                                  assignee_loan_path: @LoanPath,
+                                  assignee_id: ast::NodeId) {
+    move_data.add_assignment(bccx.tcx,
+                             assignee_loan_path,
+                             assignment_id,
+                             assignment_span,
+                             assignee_id,
+                             true);
 }
 
 fn check_is_legal_to_move_from(bccx: &BorrowckCtxt,
diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs
index d6666eb6293..e50d6da378a 100644
--- a/src/librustc/middle/borrowck/gather_loans/mod.rs
+++ b/src/librustc/middle/borrowck/gather_loans/mod.rs
@@ -214,20 +214,19 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
         visit::walk_expr(this, ex, ());
       }
 
-      ast::ExprAssign(l, _) | ast::ExprAssignOp(_, l, _) => {
-          let l_cmt = this.bccx.cat_expr(l);
-          match opt_loan_path(l_cmt) {
-              Some(l_lp) => {
-                  gather_moves::gather_assignment(this.bccx, &this.move_data,
-                                                  ex.id, ex.span,
-                                                  l_lp, l.id);
-              }
-              None => {
-                  // This can occur with e.g. `*foo() = 5`.  In such
-                  // cases, there is no need to check for conflicts
-                  // with moves etc, just ignore.
-              }
-          }
+      ast::ExprAssign(l, _) => {
+          with_assignee_loan_path(
+              this.bccx, l,
+              |lp| gather_moves::gather_assignment(this.bccx, &this.move_data,
+                                                   ex.id, ex.span, lp, l.id));
+          visit::walk_expr(this, ex, ());
+      }
+
+      ast::ExprAssignOp(_, l, _) => {
+          with_assignee_loan_path(
+              this.bccx, l,
+              |lp| gather_moves::gather_move_and_assignment(this.bccx, &this.move_data,
+                                                            ex.id, ex.span, lp, l.id));
           visit::walk_expr(this, ex, ());
       }
 
@@ -288,17 +287,10 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
 
       ast::ExprInlineAsm(ref ia) => {
           for &(_, out) in ia.outputs.iter() {
-              let out_cmt = this.bccx.cat_expr(out);
-              match opt_loan_path(out_cmt) {
-                  Some(out_lp) => {
-                      gather_moves::gather_assignment(this.bccx, &this.move_data,
-                                                      ex.id, ex.span,
-                                                      out_lp, out.id);
-                  }
-                  None => {
-                      // See the comment for ExprAssign.
-                  }
-              }
+              with_assignee_loan_path(
+                  this.bccx, out,
+                  |lp| gather_moves::gather_assignment(this.bccx, &this.move_data,
+                                                       ex.id, ex.span, lp, out.id));
           }
           visit::walk_expr(this, ex, ());
       }
@@ -309,6 +301,18 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
     }
 }
 
+fn with_assignee_loan_path(bccx: &BorrowckCtxt, expr: &ast::Expr, op: |@LoanPath|) {
+    let cmt = bccx.cat_expr(expr);
+    match opt_loan_path(cmt) {
+        Some(lp) => op(lp),
+        None => {
+            // This can occur with e.g. `*foo() = 5`.  In such
+            // cases, there is no need to check for conflicts
+            // with moves etc, just ignore.
+        }
+    }
+}
+
 impl<'a> GatherLoanCtxt<'a> {
     pub fn tcx(&self) -> ty::ctxt { self.bccx.tcx }
 
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index 9767b50ae96..654203bf077 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -535,7 +535,7 @@ impl BorrowckCtxt {
             move_data::Declared => {
                 self.tcx.sess.span_err(
                     use_span,
-                    format!("{} of possibly uninitialized value: `{}`",
+                    format!("{} of possibly uninitialized variable: `{}`",
                          verb,
                          self.loan_path_to_str(lp)));
             }
diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs
index e1434a8ac4e..5f4d5b43231 100644
--- a/src/librustc/middle/borrowck/move_data.rs
+++ b/src/librustc/middle/borrowck/move_data.rs
@@ -33,23 +33,25 @@ use util::ppaux::Repr;
 
 pub struct MoveData {
     /// Move paths. See section "Move paths" in `doc.rs`.
-    paths: RefCell<Vec<MovePath> >,
+    paths: RefCell<Vec<MovePath>>,
 
     /// Cache of loan path to move path index, for easy lookup.
     path_map: RefCell<HashMap<@LoanPath, MovePathIndex>>,
 
     /// Each move or uninitialized variable gets an entry here.
-    moves: RefCell<Vec<Move> >,
+    moves: RefCell<Vec<Move>>,
 
     /// Assignments to a variable, like `x = foo`. These are assigned
     /// bits for dataflow, since we must track them to ensure that
     /// immutable variables are assigned at most once along each path.
-    var_assignments: RefCell<Vec<Assignment> >,
+    var_assignments: RefCell<Vec<Assignment>>,
 
     /// Assignments to a path, like `x.f = foo`. These are not
     /// assigned dataflow bits, but we track them because they still
     /// kill move bits.
-    path_assignments: RefCell<Vec<Assignment> >,
+    path_assignments: RefCell<Vec<Assignment>>,
+
+    /// Assignments to a variable or path, like `x = foo`, but not `x += foo`.
     assignee_ids: RefCell<HashSet<ast::NodeId>>,
 }
 
@@ -392,7 +394,8 @@ impl MoveData {
                           lp: @LoanPath,
                           assign_id: ast::NodeId,
                           span: Span,
-                          assignee_id: ast::NodeId) {
+                          assignee_id: ast::NodeId,
+                          is_also_move: bool) {
         /*!
          * Adds a new record for an assignment to `lp` that occurs at
          * location `id` with the given `span`.
@@ -403,7 +406,7 @@ impl MoveData {
 
         let path_index = self.move_path(tcx, lp);
 
-        {
+        if !is_also_move {
             let mut assignee_ids = self.assignee_ids.borrow_mut();
             assignee_ids.get().insert(assignee_id);
         }
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 04f2b2f2823..02a947a0ddc 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -1468,28 +1468,14 @@ impl Liveness {
 
 fn check_local(this: &mut Liveness, local: &Local) {
     match local.init {
-      Some(_) => {
-        this.warn_about_unused_or_dead_vars_in_pat(local.pat);
-      }
-      None => {
-
-        // No initializer: the variable might be unused; if not, it
-        // should not be live at this point.
-
-        debug!("check_local() with no initializer");
-        this.pat_bindings(local.pat, |ln, var, sp, id| {
-            if !this.warn_about_unused(sp, id, ln, var) {
-                match this.live_on_exit(ln, var) {
-                  None => { /* not live: good */ }
-                  Some(lnk) => {
-                    this.report_illegal_read(
-                        local.span, lnk, var,
-                        PossiblyUninitializedVariable);
-                  }
-                }
-            }
-        })
-      }
+        Some(_) => {
+            this.warn_about_unused_or_dead_vars_in_pat(local.pat);
+        },
+        None => {
+            this.pat_bindings(local.pat, |ln, var, sp, id| {
+                this.warn_about_unused(sp, id, ln, var);
+            })
+        }
     }
 
     visit::walk_local(this, local, ());
@@ -1644,38 +1630,6 @@ impl Liveness {
        }
     }
 
-    pub fn report_illegal_read(&self,
-                               chk_span: Span,
-                               lnk: LiveNodeKind,
-                               var: Variable,
-                               rk: ReadKind) {
-        let msg = match rk {
-            PossiblyUninitializedVariable => "possibly uninitialized \
-                                              variable",
-            PossiblyUninitializedField => "possibly uninitialized field",
-            MovedValue => "moved value",
-            PartiallyMovedValue => "partially moved value"
-        };
-        let name = self.ir.variable_name(var);
-        match lnk {
-          FreeVarNode(span) => {
-            self.tcx.sess.span_err(
-                span,
-                format!("capture of {}: `{}`", msg, name));
-          }
-          ExprNode(span) => {
-            self.tcx.sess.span_err(
-                span,
-                format!("use of {}: `{}`", msg, name));
-          }
-          ExitNode | VarDefNode(_) => {
-            self.tcx.sess.span_bug(
-                chk_span,
-                format!("illegal reader: {:?}", lnk));
-          }
-        }
-    }
-
     pub 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) }
diff --git a/src/test/compile-fail/asm-out-read-uninit.rs b/src/test/compile-fail/asm-out-read-uninit.rs
index b63865921c6..65750eb926b 100644
--- a/src/test/compile-fail/asm-out-read-uninit.rs
+++ b/src/test/compile-fail/asm-out-read-uninit.rs
@@ -19,7 +19,7 @@ fn foo(x: int) { info!("{}", x); }
 pub fn main() {
     let x: int;
     unsafe {
-        asm!("mov $1, $0" : "=r"(x) : "r"(x)); //~ ERROR use of possibly uninitialized value: `x`
+        asm!("mov $1, $0" : "=r"(x) : "r"(x)); //~ ERROR use of possibly uninitialized variable: `x`
     }
     foo(x);
 }
diff --git a/src/test/compile-fail/liveness-and-init.rs b/src/test/compile-fail/borrowck-and-init.rs
index 134390d0b59..134390d0b59 100644
--- a/src/test/compile-fail/liveness-and-init.rs
+++ b/src/test/compile-fail/borrowck-and-init.rs
diff --git a/src/test/compile-fail/liveness-block-unint.rs b/src/test/compile-fail/borrowck-block-unint.rs
index c46b9013a06..fc865e271e3 100644
--- a/src/test/compile-fail/liveness-block-unint.rs
+++ b/src/test/compile-fail/borrowck-block-unint.rs
@@ -11,7 +11,7 @@
 fn force(f: ||) { f(); }
 fn main() {
     let x: int;
-    force(|| {
-        info!("{}", x); //~ ERROR capture of possibly uninitialized variable: `x`
+    force(|| {  //~ ERROR capture of possibly uninitialized variable: `x`
+        info!("{}", x);
     });
 }
diff --git a/src/test/compile-fail/liveness-break-uninit-2.rs b/src/test/compile-fail/borrowck-break-uninit-2.rs
index accb9076974..accb9076974 100644
--- a/src/test/compile-fail/liveness-break-uninit-2.rs
+++ b/src/test/compile-fail/borrowck-break-uninit-2.rs
diff --git a/src/test/compile-fail/liveness-break-uninit.rs b/src/test/compile-fail/borrowck-break-uninit.rs
index d49e79d2c64..d49e79d2c64 100644
--- a/src/test/compile-fail/liveness-break-uninit.rs
+++ b/src/test/compile-fail/borrowck-break-uninit.rs
diff --git a/src/test/compile-fail/liveness-if-no-else.rs b/src/test/compile-fail/borrowck-if-no-else.rs
index 8dc590b47f0..8dc590b47f0 100644
--- a/src/test/compile-fail/liveness-if-no-else.rs
+++ b/src/test/compile-fail/borrowck-if-no-else.rs
diff --git a/src/test/compile-fail/liveness-if-with-else.rs b/src/test/compile-fail/borrowck-if-with-else.rs
index 55fb8222634..55fb8222634 100644
--- a/src/test/compile-fail/liveness-if-with-else.rs
+++ b/src/test/compile-fail/borrowck-if-with-else.rs
diff --git a/src/test/compile-fail/liveness-init-in-called-fn-expr.rs b/src/test/compile-fail/borrowck-init-in-called-fn-expr.rs
index d759a5738bd..d759a5738bd 100644
--- a/src/test/compile-fail/liveness-init-in-called-fn-expr.rs
+++ b/src/test/compile-fail/borrowck-init-in-called-fn-expr.rs
diff --git a/src/test/compile-fail/liveness-init-in-fn-expr.rs b/src/test/compile-fail/borrowck-init-in-fn-expr.rs
index f6bb2f54283..f6bb2f54283 100644
--- a/src/test/compile-fail/liveness-init-in-fn-expr.rs
+++ b/src/test/compile-fail/borrowck-init-in-fn-expr.rs
diff --git a/src/test/compile-fail/liveness-init-in-fru.rs b/src/test/compile-fail/borrowck-init-in-fru.rs
index 97fc2b4d44c..97fc2b4d44c 100644
--- a/src/test/compile-fail/liveness-init-in-fru.rs
+++ b/src/test/compile-fail/borrowck-init-in-fru.rs
diff --git a/src/test/compile-fail/liveness-init-op-equal.rs b/src/test/compile-fail/borrowck-init-op-equal.rs
index cbe805551c2..cbe805551c2 100644
--- a/src/test/compile-fail/liveness-init-op-equal.rs
+++ b/src/test/compile-fail/borrowck-init-op-equal.rs
diff --git a/src/test/compile-fail/liveness-init-plus-equal.rs b/src/test/compile-fail/borrowck-init-plus-equal.rs
index 6e813809f03..6e813809f03 100644
--- a/src/test/compile-fail/liveness-init-plus-equal.rs
+++ b/src/test/compile-fail/borrowck-init-plus-equal.rs
diff --git a/src/test/compile-fail/liveness-or-init.rs b/src/test/compile-fail/borrowck-or-init.rs
index f878afce969..f878afce969 100644
--- a/src/test/compile-fail/liveness-or-init.rs
+++ b/src/test/compile-fail/borrowck-or-init.rs
diff --git a/src/test/compile-fail/liveness-return.rs b/src/test/compile-fail/borrowck-return.rs
index 6558bc57968..6558bc57968 100644
--- a/src/test/compile-fail/liveness-return.rs
+++ b/src/test/compile-fail/borrowck-return.rs
diff --git a/src/test/compile-fail/liveness-uninit-after-item.rs b/src/test/compile-fail/borrowck-uninit-after-item.rs
index a828b1d6b9f..a828b1d6b9f 100644
--- a/src/test/compile-fail/liveness-uninit-after-item.rs
+++ b/src/test/compile-fail/borrowck-uninit-after-item.rs
diff --git a/src/test/compile-fail/borrowck-uninit-in-assignop.rs b/src/test/compile-fail/borrowck-uninit-in-assignop.rs
new file mode 100644
index 00000000000..b5e462e592a
--- /dev/null
+++ b/src/test/compile-fail/borrowck-uninit-in-assignop.rs
@@ -0,0 +1,44 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tests that the use of uninitialized variable in assignment operator
+// expression is detected.
+
+pub fn main() {
+    let x: int;
+    x += 1; //~ ERROR use of possibly uninitialized variable: `x`
+
+    let x: int;
+    x -= 1; //~ ERROR use of possibly uninitialized variable: `x`
+
+    let x: int;
+    x *= 1; //~ ERROR use of possibly uninitialized variable: `x`
+
+    let x: int;
+    x /= 1; //~ ERROR use of possibly uninitialized variable: `x`
+
+    let x: int;
+    x %= 1; //~ ERROR use of possibly uninitialized variable: `x`
+
+    let x: int;
+    x ^= 1; //~ ERROR use of possibly uninitialized variable: `x`
+
+    let x: int;
+    x &= 1; //~ ERROR use of possibly uninitialized variable: `x`
+
+    let x: int;
+    x |= 1; //~ ERROR use of possibly uninitialized variable: `x`
+
+    let x: int;
+    x <<= 1;    //~ ERROR use of possibly uninitialized variable: `x`
+
+    let x: int;
+    x >>= 1;    //~ ERROR use of possibly uninitialized variable: `x`
+}
diff --git a/src/test/compile-fail/liveness-uninit.rs b/src/test/compile-fail/borrowck-uninit.rs
index a6ce736c89b..a6ce736c89b 100644
--- a/src/test/compile-fail/liveness-uninit.rs
+++ b/src/test/compile-fail/borrowck-uninit.rs
diff --git a/src/test/compile-fail/liveness-use-in-index-lvalue.rs b/src/test/compile-fail/borrowck-use-in-index-lvalue.rs
index 7ec0607fc97..3ced9859240 100644
--- a/src/test/compile-fail/liveness-use-in-index-lvalue.rs
+++ b/src/test/compile-fail/borrowck-use-in-index-lvalue.rs
@@ -11,6 +11,10 @@
 fn test() {
     let w: ~[int];
     w[5] = 0; //~ ERROR use of possibly uninitialized variable: `w`
+              //~^ ERROR cannot assign to immutable vec content `w[..]`
+
+    let mut w: ~[int];
+    w[5] = 0; //~ ERROR use of possibly uninitialized variable: `w`
 }
 
 fn main() { test(); }
diff --git a/src/test/compile-fail/liveness-while-break.rs b/src/test/compile-fail/borrowck-while-break.rs
index e5d4b6ef48c..e5d4b6ef48c 100644
--- a/src/test/compile-fail/liveness-while-break.rs
+++ b/src/test/compile-fail/borrowck-while-break.rs
diff --git a/src/test/compile-fail/liveness-while-cond.rs b/src/test/compile-fail/borrowck-while-cond.rs
index 27d42d666ea..27d42d666ea 100644
--- a/src/test/compile-fail/liveness-while-cond.rs
+++ b/src/test/compile-fail/borrowck-while-cond.rs
diff --git a/src/test/compile-fail/liveness-while.rs b/src/test/compile-fail/borrowck-while.rs
index b904fd53d72..b904fd53d72 100644
--- a/src/test/compile-fail/liveness-while.rs
+++ b/src/test/compile-fail/borrowck-while.rs
diff --git a/src/test/compile-fail/liveness-unused.rs b/src/test/compile-fail/liveness-unused.rs
index 83c911d916e..33fc094abbe 100644
--- a/src/test/compile-fail/liveness-unused.rs
+++ b/src/test/compile-fail/liveness-unused.rs
@@ -23,6 +23,11 @@ fn f1b(x: &mut int) {
 #[allow(unused_variable)]
 fn f1c(x: int) {}
 
+fn f1d() {
+    let x: int;
+    //~^ ERROR unused variable: `x`
+}
+
 fn f2() {
     let x = 3;
     //~^ ERROR unused variable: `x`