Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test -- add new tests specifically examining closure borrows
- Loading branch information
1 parent
3805c54
commit c9e3cb6
Showing
6 changed files
with
296 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |