test -- add new tests specifically examining closure borrows
This commit is contained in:
parent
3805c5416e
commit
c9e3cb678d
6 changed files with 296 additions and 0 deletions
79
src/test/compile-fail/borrowck-closures-mut-and-imm.rs
Normal file
79
src/test/compile-fail/borrowck-closures-mut-and-imm.rs
Normal file
|
@ -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() {
|
||||
}
|
31
src/test/compile-fail/borrowck-closures-mut-of-imm.rs
Normal file
31
src/test/compile-fail/borrowck-closures-mut-of-imm.rs
Normal file
|
@ -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() {
|
||||
}
|
56
src/test/compile-fail/borrowck-closures-two-mut.rs
Normal file
56
src/test/compile-fail/borrowck-closures-two-mut.rs
Normal file
|
@ -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() {
|
||||
}
|
50
src/test/compile-fail/borrowck-closures-unique.rs
Normal file
50
src/test/compile-fail/borrowck-closures-unique.rs
Normal file
|
@ -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() {
|
||||
}
|
31
src/test/compile-fail/borrowck-closures-use-after-free.rs
Normal file
31
src/test/compile-fail/borrowck-closures-use-after-free.rs
Normal file
|
@ -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`
|
||||
}
|
49
src/test/run-pass/borrowck-closures-two-imm.rs
Normal file
49
src/test/run-pass/borrowck-closures-two-imm.rs
Normal file
|
@ -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);
|
||||
}
|
Loading…
Add table
Reference in a new issue