Skip to content

Commit c9e3cb6

Browse files
committed
test -- add new tests specifically examining closure borrows
1 parent 3805c54 commit c9e3cb6

6 files changed

+296
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Tests that two closures cannot simultaneously have mutable
12+
// and immutable access to the variable. Issue #6801.
13+
14+
fn get(x: &int) -> int {
15+
*x
16+
}
17+
18+
fn set(x: &mut int) {
19+
*x = 4;
20+
}
21+
22+
fn a() {
23+
let mut x = 3;
24+
let c1 = || x = 4;
25+
let c2 = || x * 5; //~ ERROR cannot borrow `x`
26+
}
27+
28+
fn b() {
29+
let mut x = 3;
30+
let c1 = || set(&mut x);
31+
let c2 = || get(&x); //~ ERROR cannot borrow `x`
32+
}
33+
34+
fn c() {
35+
let mut x = 3;
36+
let c1 = || set(&mut x);
37+
let c2 = || x * 5; //~ ERROR cannot borrow `x`
38+
}
39+
40+
fn d() {
41+
let mut x = 3;
42+
let c2 = || x * 5;
43+
x = 5; //~ ERROR cannot assign
44+
}
45+
46+
fn e() {
47+
let mut x = 3;
48+
let c1 = || get(&x);
49+
x = 5; //~ ERROR cannot assign
50+
}
51+
52+
fn f() {
53+
let mut x = ~3;
54+
let c1 = || get(&*x);
55+
*x = 5; //~ ERROR cannot assign
56+
}
57+
58+
fn g() {
59+
struct Foo {
60+
f: ~int
61+
}
62+
63+
let mut x = ~Foo { f: ~3 };
64+
let c1 = || get(&*x.f);
65+
*x.f = 5; //~ ERROR cannot assign to `*x.f`
66+
}
67+
68+
fn h() {
69+
struct Foo {
70+
f: ~int
71+
}
72+
73+
let mut x = ~Foo { f: ~3 };
74+
let c1 = || get(&*x.f);
75+
let c2 = || *x.f = 5; //~ ERROR cannot borrow `x` as mutable
76+
}
77+
78+
fn main() {
79+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Tests that two closures cannot simultaneously have mutable
12+
// and immutable access to the variable. Issue #6801.
13+
14+
fn get(x: &int) -> int {
15+
*x
16+
}
17+
18+
fn set(x: &mut int) {
19+
*x = 4;
20+
}
21+
22+
fn a(x: &int) {
23+
let c1 = || set(&mut *x);
24+
//~^ ERROR cannot borrow
25+
let c2 = || set(&mut *x);
26+
//~^ ERROR closure requires unique access to `x`
27+
//~^^ ERROR cannot borrow
28+
}
29+
30+
fn main() {
31+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Tests that two closures cannot simultaneously have mutable
12+
// access to the variable, whether that mutable access be used
13+
// for direct assignment or for taking mutable ref. Issue #6801.
14+
15+
fn a() {
16+
let mut x = 3;
17+
let c1 = || x = 4;
18+
let c2 = || x = 5; //~ ERROR cannot borrow `x` as mutable more than once
19+
}
20+
21+
fn set(x: &mut int) {
22+
*x = 4;
23+
}
24+
25+
fn b() {
26+
let mut x = 3;
27+
let c1 = || set(&mut x);
28+
let c2 = || set(&mut x); //~ ERROR cannot borrow `x` as mutable more than once
29+
}
30+
31+
fn c() {
32+
let mut x = 3;
33+
let c1 = || x = 5;
34+
let c2 = || set(&mut x); //~ ERROR cannot borrow `x` as mutable more than once
35+
}
36+
37+
fn d() {
38+
let mut x = 3;
39+
let c1 = || x = 5;
40+
let c2 = || { let _y = || set(&mut x); }; // (nested closure)
41+
//~^ ERROR cannot borrow `x` as mutable more than once
42+
}
43+
44+
fn g() {
45+
struct Foo {
46+
f: ~int
47+
}
48+
49+
let mut x = ~Foo { f: ~3 };
50+
let c1 = || set(&mut *x.f);
51+
let c2 = || set(&mut *x.f);
52+
//~^ ERROR cannot borrow `x` as mutable more than once
53+
}
54+
55+
fn main() {
56+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Tests that a closure which requires mutable access to the referent
12+
// of an `&mut` requires a "unique" borrow -- that is, the variable to
13+
// be borrowed (here, `x`) will not be borrowed *mutably*, but
14+
// may be *immutable*, but we cannot allow
15+
// multiple borrows.
16+
17+
fn get(x: &int) -> int {
18+
*x
19+
}
20+
21+
fn set(x: &mut int) -> int {
22+
*x
23+
}
24+
25+
fn a(x: &mut int) {
26+
let c1 = || get(x);
27+
let c2 = || get(x);
28+
}
29+
30+
fn b(x: &mut int) {
31+
let c1 = || get(x);
32+
let c2 = || set(x); //~ ERROR closure requires unique access to `x`
33+
}
34+
35+
fn c(x: &mut int) {
36+
let c1 = || get(x);
37+
let c2 = || { get(x); set(x); }; //~ ERROR closure requires unique access to `x`
38+
}
39+
40+
fn d(x: &mut int) {
41+
let c1 = || set(x);
42+
let c2 = || set(x); //~ ERROR closure requires unique access to `x`
43+
}
44+
45+
fn e(x: &mut int) {
46+
let c1: || = || x = fail!(); //~ ERROR closure cannot assign to immutable argument `x`
47+
}
48+
49+
fn main() {
50+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Tests that a closure which mutates a local variable
12+
// cannot also be supplied a borrowed version of that
13+
// variable's contents. Issue #11192.
14+
15+
struct Foo {
16+
x: int
17+
}
18+
19+
impl Drop for Foo {
20+
fn drop(&mut self) {
21+
println!("drop {}", self.x);
22+
}
23+
}
24+
25+
fn main() {
26+
let mut ptr = ~Foo { x: 0 };
27+
let test = |foo: &Foo| {
28+
ptr = ~Foo { x: ptr.x + 1 };
29+
};
30+
test(ptr); //~ ERROR cannot borrow `*ptr`
31+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Tests that two closures can simultaneously have immutable
12+
// access to the variable, whether that immutable access be used
13+
// for direct reads or for taking immutable ref. Also check
14+
// that the main function can read the variable too while
15+
// the closures are in scope. Issue #6801.
16+
17+
fn a() -> int {
18+
let mut x = 3;
19+
x += 1;
20+
let c1 = || x * 4;
21+
let c2 = || x * 5;
22+
c1() * c2() * x
23+
}
24+
25+
fn get(x: &int) -> int {
26+
*x * 4
27+
}
28+
29+
fn b() -> int {
30+
let mut x = 3;
31+
x += 1;
32+
let c1 = || get(&x);
33+
let c2 = || get(&x);
34+
c1() * c2() * x
35+
}
36+
37+
fn c() -> int {
38+
let mut x = 3;
39+
x += 1;
40+
let c1 = || x * 5;
41+
let c2 = || get(&x);
42+
c1() * c2() * x
43+
}
44+
45+
pub fn main() {
46+
assert_eq!(a(), 1280);
47+
assert_eq!(b(), 1024);
48+
assert_eq!(c(), 1280);
49+
}

0 commit comments

Comments
 (0)