]> git.lizzy.rs Git - rust.git/commitdiff
Forbid blocks from deinitializing upvars
authorTim Chevalier <chevalier@alum.wellesley.edu>
Tue, 6 Sep 2011 22:26:57 +0000 (15:26 -0700)
committerTim Chevalier <chevalier@alum.wellesley.edu>
Tue, 6 Sep 2011 22:27:48 +0000 (15:27 -0700)
Move expressions where the RHS is an upvar are now forbidden within
block expressions.

src/comp/middle/tstate/states.rs
src/test/compile-fail/block-deinitializes-upvar.rs

index af14db2e9c878ba1beaa6b626a8e0b44698b8854..6537487b1bb5afda0ed112385433b71845b37d41 100644 (file)
@@ -17,6 +17,7 @@
 import bitvectors::*;
 import syntax::ast::*;
 import syntax::ast_util::*;
+import syntax::codemap::span;
 import middle::ty::expr_ty;
 import middle::ty::type_is_nil;
 import middle::ty::type_is_bot;
 import util::common::log_stmt_err;
 import util::common::log_expr_err;
 
+fn forbid_upvar(fcx: &fn_ctxt, rhs_id: &node_id, sp: &span,
+                t: oper_type) {
+    alt t {
+      oper_move. {
+        alt local_node_id_to_def(fcx, rhs_id) {
+          some(def_upvar(_,_,_)) {
+             fcx.ccx.tcx.sess.span_err(sp, "Tried to deinitialize a variable \
+              declared in a different scope");
+           }
+          _ {}
+        }
+      }
+      _ { /* do nothing */ }
+    }
+}
+
 fn handle_move_or_copy(fcx: &fn_ctxt, post: &poststate, rhs_path: &path,
                        rhs_id: &node_id, instlhs: &inst, init_op: &init_op) {
-    let rhs_d = local_node_id_to_def_id(fcx, rhs_id);
-    alt rhs_d {
+    forbid_upvar(fcx, rhs_id, rhs_path.span, op_to_oper_ty(init_op));
+
+    let rhs_d_id = local_node_id_to_def_id(fcx, rhs_id);
+    alt rhs_d_id {
       some(rhsid) {
         // RHS is a local var
         let instrhs =
@@ -110,6 +129,7 @@ fn find_pre_post_state_two(fcx: &fn_ctxt, pres: &prestate, lhs: &@expr,
     changed =
         find_pre_post_state_expr(fcx, expr_poststate(fcx.ccx, lhs), rhs) ||
             changed;
+    forbid_upvar(fcx, rhs.id, rhs.span, ty);
 
     let post = tritv_clone(expr_poststate(fcx.ccx, rhs));
 
index da5922036a7af27efb0f288c78d414d9ebb25d06..bc1292021a946ad0204d327e186c7c5d5ed082f4 100644 (file)
@@ -1,8 +1,11 @@
-// error-pattern:assigning to upvar
+// error-pattern:Tried to deinitialize a variable declared in a different
 fn force(f: &block() -> int) -> int { ret f(); }
 fn main() {
-    let x = 5;
-    let f = lambda () -> int { let y = 6; x <- y; ret 7 };
-    assert (force(f) == 7);
-    log x;
+    let x = @{x:17, y:2};
+    let y = @{x:5, y:5};
+
+    let f =  {|&i| log_err i; x <- y; ret 7; };
+    assert (f(5) == 7);
+    log_err x;
+    log_err y;
 }