about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-02-10 07:44:21 -0500
committerNiko Matsakis <niko@alum.mit.edu>2014-02-11 16:55:25 -0500
commitc9e3cb678d556926c491d977550fbd805892d4af (patch)
treecd0d71605230181eb9ad34b13fb2c35898ba01d2 /src/test
parent3805c5416e0df7c6a3214e980a145a34119f4ad5 (diff)
test -- add new tests specifically examining closure borrows
Diffstat (limited to 'src/test')
-rw-r--r--src/test/compile-fail/borrowck-closures-mut-and-imm.rs79
-rw-r--r--src/test/compile-fail/borrowck-closures-mut-of-imm.rs31
-rw-r--r--src/test/compile-fail/borrowck-closures-two-mut.rs56
-rw-r--r--src/test/compile-fail/borrowck-closures-unique.rs50
-rw-r--r--src/test/compile-fail/borrowck-closures-use-after-free.rs31
-rw-r--r--src/test/run-pass/borrowck-closures-two-imm.rs49
6 files changed, 296 insertions, 0 deletions
diff --git a/src/test/compile-fail/borrowck-closures-mut-and-imm.rs b/src/test/compile-fail/borrowck-closures-mut-and-imm.rs
new file mode 100644
index 00000000000..006f475b29d
--- /dev/null
+++ b/src/test/compile-fail/borrowck-closures-mut-and-imm.rs
@@ -0,0 +1,79 @@
+// 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.
+
+// Tests that two closures cannot simultaneously have mutable
+// and immutable access to the variable. Issue #6801.
+
+fn get(x: &int) -> int {
+    *x
+}
+
+fn set(x: &mut int) {
+    *x = 4;
+}
+
+fn a() {
+    let mut x = 3;
+    let c1 = || x = 4;
+    let c2 = || x * 5; //~ ERROR cannot borrow `x`
+}
+
+fn b() {
+    let mut x = 3;
+    let c1 = || set(&mut x);
+    let c2 = || get(&x); //~ ERROR cannot borrow `x`
+}
+
+fn c() {
+    let mut x = 3;
+    let c1 = || set(&mut x);
+    let c2 = || x * 5; //~ ERROR cannot borrow `x`
+}
+
+fn d() {
+    let mut x = 3;
+    let c2 = || x * 5;
+    x = 5; //~ ERROR cannot assign
+}
+
+fn e() {
+    let mut x = 3;
+    let c1 = || get(&x);
+    x = 5; //~ ERROR cannot assign
+}
+
+fn f() {
+    let mut x = ~3;
+    let c1 = || get(&*x);
+    *x = 5; //~ ERROR cannot assign
+}
+
+fn g() {
+    struct Foo {
+        f: ~int
+    }
+
+    let mut x = ~Foo { f: ~3 };
+    let c1 = || get(&*x.f);
+    *x.f = 5; //~ ERROR cannot assign to `*x.f`
+}
+
+fn h() {
+    struct Foo {
+        f: ~int
+    }
+
+    let mut x = ~Foo { f: ~3 };
+    let c1 = || get(&*x.f);
+    let c2 = || *x.f = 5; //~ ERROR cannot borrow `x` as mutable
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/borrowck-closures-mut-of-imm.rs b/src/test/compile-fail/borrowck-closures-mut-of-imm.rs
new file mode 100644
index 00000000000..cdfb569762d
--- /dev/null
+++ b/src/test/compile-fail/borrowck-closures-mut-of-imm.rs
@@ -0,0 +1,31 @@
+// 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.
+
+// Tests that two closures cannot simultaneously have mutable
+// and immutable access to the variable. Issue #6801.
+
+fn get(x: &int) -> int {
+    *x
+}
+
+fn set(x: &mut int) {
+    *x = 4;
+}
+
+fn a(x: &int) {
+    let c1 = || set(&mut *x);
+    //~^ ERROR cannot borrow
+    let c2 = || set(&mut *x);
+    //~^ ERROR closure requires unique access to `x`
+    //~^^ ERROR cannot borrow
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/borrowck-closures-two-mut.rs b/src/test/compile-fail/borrowck-closures-two-mut.rs
new file mode 100644
index 00000000000..570249aed44
--- /dev/null
+++ b/src/test/compile-fail/borrowck-closures-two-mut.rs
@@ -0,0 +1,56 @@
+// 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.
+
+// Tests that two closures cannot simultaneously have mutable
+// access to the variable, whether that mutable access be used
+// for direct assignment or for taking mutable ref. Issue #6801.
+
+fn a() {
+    let mut x = 3;
+    let c1 = || x = 4;
+    let c2 = || x = 5; //~ ERROR cannot borrow `x` as mutable more than once
+}
+
+fn set(x: &mut int) {
+    *x = 4;
+}
+
+fn b() {
+    let mut x = 3;
+    let c1 = || set(&mut x);
+    let c2 = || set(&mut x); //~ ERROR cannot borrow `x` as mutable more than once
+}
+
+fn c() {
+    let mut x = 3;
+    let c1 = || x = 5;
+    let c2 = || set(&mut x); //~ ERROR cannot borrow `x` as mutable more than once
+}
+
+fn d() {
+    let mut x = 3;
+    let c1 = || x = 5;
+    let c2 = || { let _y = || set(&mut x); }; // (nested closure)
+    //~^ ERROR cannot borrow `x` as mutable more than once
+}
+
+fn g() {
+    struct Foo {
+        f: ~int
+    }
+
+    let mut x = ~Foo { f: ~3 };
+    let c1 = || set(&mut *x.f);
+    let c2 = || set(&mut *x.f);
+    //~^ ERROR cannot borrow `x` as mutable more than once
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/borrowck-closures-unique.rs b/src/test/compile-fail/borrowck-closures-unique.rs
new file mode 100644
index 00000000000..80d942e58d1
--- /dev/null
+++ b/src/test/compile-fail/borrowck-closures-unique.rs
@@ -0,0 +1,50 @@
+// 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.
+
+// Tests that a closure which requires mutable access to the referent
+// of an `&mut` requires a "unique" borrow -- that is, the variable to
+// be borrowed (here, `x`) will not be borrowed *mutably*, but
+//  may be *immutable*, but we cannot allow
+// multiple borrows.
+
+fn get(x: &int) -> int {
+    *x
+}
+
+fn set(x: &mut int) -> int {
+    *x
+}
+
+fn a(x: &mut int) {
+    let c1 = || get(x);
+    let c2 = || get(x);
+}
+
+fn b(x: &mut int) {
+    let c1 = || get(x);
+    let c2 = || set(x); //~ ERROR closure requires unique access to `x`
+}
+
+fn c(x: &mut int) {
+    let c1 = || get(x);
+    let c2 = || { get(x); set(x); }; //~ ERROR closure requires unique access to `x`
+}
+
+fn d(x: &mut int) {
+    let c1 = || set(x);
+    let c2 = || set(x); //~ ERROR closure requires unique access to `x`
+}
+
+fn e(x: &mut int) {
+    let c1: || = || x = fail!(); //~ ERROR closure cannot assign to immutable argument `x`
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/borrowck-closures-use-after-free.rs b/src/test/compile-fail/borrowck-closures-use-after-free.rs
new file mode 100644
index 00000000000..38c13b1fce9
--- /dev/null
+++ b/src/test/compile-fail/borrowck-closures-use-after-free.rs
@@ -0,0 +1,31 @@
+// 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.
+
+// Tests that a closure which mutates a local variable
+// cannot also be supplied a borrowed version of that
+// variable's contents. Issue #11192.
+
+struct Foo {
+  x: int
+}
+
+impl Drop for Foo {
+  fn drop(&mut self) {
+    println!("drop {}", self.x);
+  }
+}
+
+fn main() {
+  let mut ptr = ~Foo { x: 0 };
+  let test = |foo: &Foo| {
+    ptr = ~Foo { x: ptr.x + 1 };
+  };
+  test(ptr); //~ ERROR cannot borrow `*ptr`
+}
diff --git a/src/test/run-pass/borrowck-closures-two-imm.rs b/src/test/run-pass/borrowck-closures-two-imm.rs
new file mode 100644
index 00000000000..3bd12b03041
--- /dev/null
+++ b/src/test/run-pass/borrowck-closures-two-imm.rs
@@ -0,0 +1,49 @@
+// 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.
+
+// Tests that two closures can simultaneously have immutable
+// access to the variable, whether that immutable access be used
+// for direct reads or for taking immutable ref. Also check
+// that the main function can read the variable too while
+// the closures are in scope. Issue #6801.
+
+fn a() -> int {
+    let mut x = 3;
+    x += 1;
+    let c1 = || x * 4;
+    let c2 = || x * 5;
+    c1() * c2() * x
+}
+
+fn get(x: &int) -> int {
+    *x * 4
+}
+
+fn b() -> int {
+    let mut x = 3;
+    x += 1;
+    let c1 = || get(&x);
+    let c2 = || get(&x);
+    c1() * c2() * x
+}
+
+fn c() -> int {
+    let mut x = 3;
+    x += 1;
+    let c1 = || x * 5;
+    let c2 = || get(&x);
+    c1() * c2() * x
+}
+
+pub fn main() {
+    assert_eq!(a(), 1280);
+    assert_eq!(b(), 1024);
+    assert_eq!(c(), 1280);
+}