]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Prevent repeated moves out of proc upvars
authorAlex Crichton <alex@alexcrichton.com>
Tue, 8 Apr 2014 23:59:18 +0000 (16:59 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Wed, 9 Apr 2014 00:10:47 +0000 (17:10 -0700)
This fixes the categorization of the upvars of procs (represented internally
as once fns) to consider usage to require a loan. In doing so, upvars are no
longer allowed to be moved out of repeatedly in loops and such.

Closes #10398
Closes #12041
Closes #12127

src/librustc/middle/borrowck/mod.rs
src/test/compile-fail/issue-10398.rs [new file with mode: 0644]
src/test/compile-fail/issue-11925.rs
src/test/compile-fail/issue-12041.rs [new file with mode: 0644]
src/test/compile-fail/issue-12127.rs [new file with mode: 0644]

index 6f4f2f6345eb48fa0fe161caa0bfab9d08a8accf..cf558c6afe39626fe6f1bd2d7ba82be060e25de7 100644 (file)
@@ -274,12 +274,13 @@ pub fn opt_loan_path(cmt: mc::cmt) -> Option<@LoanPath> {
     match cmt.cat {
         mc::cat_rvalue(..) |
         mc::cat_static_item |
-        mc::cat_copied_upvar(_) => {
+        mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, .. }) => {
             None
         }
 
         mc::cat_local(id) |
         mc::cat_arg(id) |
+        mc::cat_copied_upvar(mc::CopiedUpvar { upvar_id: id, .. }) |
         mc::cat_upvar(ty::UpvarId {var_id: id, ..}, _) => {
             Some(@LpVar(id))
         }
diff --git a/src/test/compile-fail/issue-10398.rs b/src/test/compile-fail/issue-10398.rs
new file mode 100644 (file)
index 0000000..a58c887
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 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.
+
+fn main() {
+    let x = ~1;
+    let f: proc() = proc() {
+        let _a = x;
+        drop(x);
+        //~^ ERROR: use of moved value: `x`
+    };
+    f();
+}
index 06a976ecf3d3029ee2042441e95c7be4925d036b..0b8eaa5b831c00788902f990cb8d3b7fe75c0a75 100644 (file)
@@ -11,7 +11,7 @@
 fn main() {
     let r = {
         let x = ~42;
-        let f = proc() &x; //~ ERROR: borrowed value does not live long enough
+        let f = proc() &x; //~ ERROR: `x` does not live long enough
         f()
     };
 
diff --git a/src/test/compile-fail/issue-12041.rs b/src/test/compile-fail/issue-12041.rs
new file mode 100644 (file)
index 0000000..9ad5936
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 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.
+
+fn main() {
+    let (tx, rx) = channel();
+    spawn(proc() {
+        loop {
+            let tx = tx;
+            //~^ ERROR: use of moved value: `tx`
+            tx.send(1);
+        }
+    });
+}
+
diff --git a/src/test/compile-fail/issue-12127.rs b/src/test/compile-fail/issue-12127.rs
new file mode 100644 (file)
index 0000000..7889242
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 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.
+
+fn main() {
+    let f = proc() {};
+    (proc() {
+        f();
+        f();
+        //~^ ERROR: use of moved value: `f`
+    })()
+}