about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Desaulniers <ndesaulniers@mozilla.com>2014-01-17 14:50:54 -0800
committerNick Desaulniers <ndesaulniers@mozilla.com>2014-01-27 17:06:11 -0800
commitea9db66c50f3e855f7c96e7ca244998e439c541f (patch)
tree3b37797fbb718fb1b00d9f8194841929881e790b
parent4176343073d0b28380b478fea941913567ebdd5c (diff)
downloadrust-ea9db66c50f3e855f7c96e7ca244998e439c541f.tar.gz
rust-ea9db66c50f3e855f7c96e7ca244998e439c541f.zip
can borrow mut in proc Fixes #10617
-rw-r--r--src/librustc/middle/kind.rs22
-rw-r--r--src/test/run-pass/kindck-implicit-close-over-mut-var.rs (renamed from src/test/compile-fail/kindck-implicit-close-over-mut-var.rs)31
2 files changed, 18 insertions, 35 deletions
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index 81a00e27fa0..880074256c0 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// 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.
 //
@@ -184,9 +184,6 @@ fn with_appropriate_checker(cx: &Context,
         let id = ast_util::def_id_of_def(fv.def).node;
         let var_t = ty::node_id_to_type(cx.tcx, id);
 
-        // check that only immutable variables are implicitly copied in
-        check_imm_free_var(cx, fv.def, fv.span);
-
         check_freevar_bounds(cx, fv.span, var_t, bounds, None);
     }
 
@@ -447,23 +444,6 @@ pub fn check_trait_cast_bounds(cx: &Context, sp: Span, ty: ty::t,
     });
 }
 
-fn check_imm_free_var(cx: &Context, def: Def, sp: Span) {
-    match def {
-        DefLocal(_, BindByValue(MutMutable)) => {
-            cx.tcx.sess.span_err(
-                sp,
-                "mutable variables cannot be implicitly captured");
-        }
-        DefLocal(..) | DefArg(..) | DefBinding(..) => { /* ok */ }
-        DefUpvar(_, def1, _, _) => { check_imm_free_var(cx, *def1, sp); }
-        _ => {
-            cx.tcx.sess.span_bug(
-                sp,
-                format!("unknown def for free variable: {:?}", def));
-        }
-    }
-}
-
 fn check_copy(cx: &Context, ty: ty::t, sp: Span, reason: &str) {
     debug!("type_contents({})={}",
            ty_to_str(cx.tcx, ty),
diff --git a/src/test/compile-fail/kindck-implicit-close-over-mut-var.rs b/src/test/run-pass/kindck-implicit-close-over-mut-var.rs
index b21063361ab..e0c1d35b3bc 100644
--- a/src/test/compile-fail/kindck-implicit-close-over-mut-var.rs
+++ b/src/test/run-pass/kindck-implicit-close-over-mut-var.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// 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.
 //
@@ -13,38 +13,41 @@ use std::task;
 fn user(_i: int) {}
 
 fn foo() {
-    // Here, i is *moved* into the closure: Not actually OK
+    // Here, i is *copied* into the proc (heap closure).
+    // Requires allocation.  The proc's copy is not mutable.
     let mut i = 0;
     do task::spawn {
-        user(i); //~ ERROR mutable variables cannot be implicitly captured
+        user(i);
+        println!("spawned {}", i)
     }
+    i += 1;
+    println!("original {}", i)
 }
 
 fn bar() {
-    // Here, i would be implicitly *copied* but it
-    // is mutable: bad
+    // Here, the original i has not been moved, only copied, so is still
+    // mutable outside of the proc.
     let mut i = 0;
     while i < 10 {
         do task::spawn {
-            user(i); //~ ERROR mutable variables cannot be implicitly captured
+            user(i);
         }
         i += 1;
     }
 }
 
 fn car() {
-    // Here, i is mutable, but *explicitly* shadowed copied:
+    // Here, i must be shadowed in the proc to be mutable.
     let mut i = 0;
     while i < 10 {
-        {
-            let i = i;
-            do task::spawn {
-                user(i);
-            }
+        do task::spawn {
+            let mut i = i;
+            i += 1;
+            user(i);
         }
         i += 1;
     }
 }
 
-fn main() {
-}
+pub fn main() {}
+