new borrow checker (mass squash)

This commit is contained in:
Niko Matsakis 2013-03-15 15:24:24 -04:00
parent b5a7e8b353
commit a896440ca1
172 changed files with 6475 additions and 4303 deletions

View file

@ -16,6 +16,6 @@ fn unpack(_unpack: &fn(v: &sty) -> ~[int]) {}
fn main() {
let _foo = unpack(|s| {
// Test that `s` is moved here.
match *s { sty(v) => v } //~ ERROR moving out of dereference of immutable & pointer
match *s { sty(v) => v } //~ ERROR cannot move out
});
}

View file

@ -17,6 +17,7 @@ fn main() {
y = Some(x.downgrade(write_mode));
//~^ ERROR cannot infer an appropriate lifetime
}
y.get();
// Adding this line causes a method unification failure instead
// do (&option::unwrap(y)).read |state| { assert!(*state == 1); }
}

View file

@ -17,6 +17,7 @@ fn main() {
do x.write_downgrade |write_mode| {
y = Some(write_mode);
}
y.get();
// Adding this line causes a method unification failure instead
// do (&option::unwrap(y)).write |state| { assert!(*state == 1); }
}

View file

@ -11,6 +11,6 @@
// Check that bogus field access is non-fatal
fn main() {
let x = 0;
debug!(x.foo); //~ ERROR attempted access of field
debug!(x.bar); //~ ERROR attempted access of field
let _ = x.foo; //~ ERROR attempted access of field
let _ = x.bar; //~ ERROR attempted access of field
}

View file

@ -9,12 +9,12 @@
// except according to those terms.
fn foo(x: @int) -> @fn() -> &'static int {
let result: @fn() -> &'static int = || &*x; //~ ERROR illegal borrow
let result: @fn() -> &'static int = || &*x; //~ ERROR cannot root
result
}
fn bar(x: @int) -> @fn() -> &int {
let result: @fn() -> &int = || &*x; //~ ERROR illegal borrow
let result: @fn() -> &int = || &*x; //~ ERROR cannot root
result
}

View file

@ -17,9 +17,11 @@ fn a() {
let mut p = ~[1];
// Create an immutable pointer into p's contents:
let _q: &int = &p[0]; //~ NOTE loan of mutable vec content granted here
let q: &int = &p[0];
p[0] = 5; //~ ERROR assigning to mutable vec content prohibited due to outstanding loan
p[0] = 5; //~ ERROR cannot assign
debug!("%d", *q);
}
fn borrow(_x: &[int], _f: &fn()) {}
@ -30,8 +32,8 @@ fn b() {
let mut p = ~[1];
do borrow(p) { //~ NOTE loan of mutable vec content granted here
p[0] = 5; //~ ERROR assigning to mutable vec content prohibited due to outstanding loan
do borrow(p) {
p[0] = 5; //~ ERROR cannot assign to
}
}

View file

@ -12,12 +12,13 @@ struct point { x: int, y: int }
fn a() {
let mut p = point {x: 3, y: 4};
let _q = &p; //~ NOTE loan of mutable local variable granted here
let q = &p;
// This assignment is illegal because the field x is not
// inherently mutable; since `p` was made immutable, `p.x` is now
// immutable. Otherwise the type of &_q.x (&int) would be wrong.
p.x = 5; //~ ERROR assigning to mutable field prohibited due to outstanding loan
p.x = 5; //~ ERROR cannot assign to `p.x`
q.x;
}
fn c() {
@ -25,9 +26,10 @@ fn c() {
// and then try to overwrite `p` as a whole.
let mut p = point {x: 3, y: 4};
let _q = &p.y; //~ NOTE loan of mutable local variable granted here
p = point {x: 5, y: 7};//~ ERROR assigning to mutable local variable prohibited due to outstanding loan
copy p;
let q = &p.y;
p = point {x: 5, y: 7};//~ ERROR cannot assign to `p`
p.x; // silence warning
*q; // stretch loan
}
fn d() {
@ -35,9 +37,9 @@ fn d() {
// address of a subcomponent and then modify that subcomponent:
let mut p = point {x: 3, y: 4};
let _q = &p.y; //~ NOTE loan of mutable field granted here
p.y = 5; //~ ERROR assigning to mutable field prohibited due to outstanding loan
copy p;
let q = &p.y;
p.y = 5; //~ ERROR cannot assign to `p.y`
*q;
}
fn main() {

View file

@ -12,6 +12,6 @@ static foo: int = 5;
fn main() {
// assigning to various global constants
None = Some(3); //~ ERROR assigning to static item
foo = 6; //~ ERROR assigning to static item
None = Some(3); //~ ERROR cannot assign to immutable static item
foo = 6; //~ ERROR cannot assign to immutable static item
}

View file

@ -12,5 +12,5 @@ struct foo(int);
fn main() {
let x = foo(3);
*x = 4; //~ ERROR assigning to anonymous field
*x = 4; //~ ERROR cannot assign to immutable anonymous field
}

View file

@ -34,6 +34,6 @@ fn main() {
// in these cases we pass through a box, so the mut
// of the box is dominant
p.x.a = 2; //~ ERROR assigning to immutable field
p.x.a = 2; //~ ERROR cannot assign to immutable field
p.z.a = 2;
}

View file

@ -14,18 +14,14 @@ struct Foo {
x: int
}
trait Stuff {
fn printme(self);
}
impl<'self> Stuff for &'self mut Foo {
fn printme(self) {
pub impl Foo {
fn printme(&mut self) {
io::println(fmt!("%d", self.x));
}
}
fn main() {
let x = Foo { x: 3 };
x.printme(); //~ ERROR illegal borrow
x.printme(); //~ ERROR cannot borrow
}

View file

@ -17,10 +17,10 @@ pub impl X {
}
fn main() {
let mut x = X(Right(main));
do (&mut x).with |opt| { //~ ERROR illegal borrow
do (&mut x).with |opt| {
match opt {
&Right(ref f) => {
x = X(Left((0,0))); //~ ERROR assigning to captured outer mutable variable
x = X(Left((0,0))); //~ ERROR cannot assign to `x`
(*f)()
},
_ => fail!()

View file

@ -0,0 +1,43 @@
// Copyright 2012 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.
// Test that we detect nested calls that could free pointers evaluated
// for earlier arguments.
fn rewrite(v: &mut ~uint) -> uint {
*v = ~22;
**v
}
fn add(v: &uint, w: uint) -> uint {
*v + w
}
fn implicit() {
let mut a = ~1;
// Note the danger here:
//
// the pointer for the first argument has already been
// evaluated, but it gets freed when evaluating the second
// argument!
add(
a,
rewrite(&mut a)); //~ ERROR cannot borrow
}
fn explicit() {
let mut a = ~1;
add(
&*a,
rewrite(&mut a)); //~ ERROR cannot borrow
}
fn main() {}

View file

@ -0,0 +1,43 @@
// Copyright 2012 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.
// Test that we detect nested calls that could free pointers evaluated
// for earlier arguments.
fn rewrite(v: &mut ~uint) -> uint {
*v = ~22;
**v
}
fn add(v: &uint, w: ~uint) -> uint {
*v + *w
}
fn implicit() {
let mut a = ~1;
// Note the danger here:
//
// the pointer for the first argument has already been
// evaluated, but it gets moved when evaluating the second
// argument!
add(
a,
a); //~ ERROR cannot move
}
fn explicit() {
let mut a = ~1;
add(
&*a,
a); //~ ERROR cannot move
}
fn main() {}

View file

@ -22,32 +22,37 @@ fn make_foo() -> ~Foo { fail!() }
fn borrow_same_field_twice_mut_mut() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1;
let _bar2 = &mut foo.bar1; //~ ERROR conflicts with prior loan
let bar1 = &mut foo.bar1;
let _bar2 = &mut foo.bar1; //~ ERROR cannot borrow
*bar1;
}
fn borrow_same_field_twice_mut_imm() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1;
let _bar2 = &foo.bar1; //~ ERROR conflicts with prior loan
let bar1 = &mut foo.bar1;
let _bar2 = &foo.bar1; //~ ERROR cannot borrow
*bar1;
}
fn borrow_same_field_twice_imm_mut() {
let mut foo = make_foo();
let _bar1 = &foo.bar1;
let _bar2 = &mut foo.bar1; //~ ERROR conflicts with prior loan
let bar1 = &foo.bar1;
let _bar2 = &mut foo.bar1; //~ ERROR cannot borrow
*bar1;
}
fn borrow_same_field_twice_imm_imm() {
let mut foo = make_foo();
let _bar1 = &foo.bar1;
let bar1 = &foo.bar1;
let _bar2 = &foo.bar1;
*bar1;
}
fn borrow_both_mut() {
fn borrow_both_fields_mut() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1;
let bar1 = &mut foo.bar1;
let _bar2 = &mut foo.bar2;
*bar1;
}
fn borrow_both_mut_pattern() {
@ -59,66 +64,77 @@ fn borrow_both_mut_pattern() {
fn borrow_var_and_pattern() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1;
let bar1 = &mut foo.bar1;
match *foo {
Foo { bar1: ref mut _bar1, bar2: _ } => {}
//~^ ERROR conflicts with prior loan
//~^ ERROR cannot borrow
}
*bar1;
}
fn borrow_mut_and_base_imm() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1.int1;
let _foo1 = &foo.bar1; //~ ERROR conflicts with prior loan
let _foo2 = &*foo; //~ ERROR conflicts with prior loan
let bar1 = &mut foo.bar1.int1;
let _foo1 = &foo.bar1; //~ ERROR cannot borrow
let _foo2 = &*foo; //~ ERROR cannot borrow
*bar1;
}
fn borrow_mut_and_base_mut() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1.int1;
let _foo1 = &mut foo.bar1; //~ ERROR conflicts with prior loan
let bar1 = &mut foo.bar1.int1;
let _foo1 = &mut foo.bar1; //~ ERROR cannot borrow
*bar1;
}
fn borrow_mut_and_base_mut2() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1.int1;
let _foo2 = &mut *foo; //~ ERROR conflicts with prior loan
let bar1 = &mut foo.bar1.int1;
let _foo2 = &mut *foo; //~ ERROR cannot borrow
*bar1;
}
fn borrow_imm_and_base_mut() {
let mut foo = make_foo();
let _bar1 = &foo.bar1.int1;
let _foo1 = &mut foo.bar1; //~ ERROR conflicts with prior loan
let bar1 = &foo.bar1.int1;
let _foo1 = &mut foo.bar1; //~ ERROR cannot borrow
*bar1;
}
fn borrow_imm_and_base_mut2() {
let mut foo = make_foo();
let _bar1 = &foo.bar1.int1;
let _foo2 = &mut *foo; //~ ERROR conflicts with prior loan
let bar1 = &foo.bar1.int1;
let _foo2 = &mut *foo; //~ ERROR cannot borrow
*bar1;
}
fn borrow_imm_and_base_imm() {
let mut foo = make_foo();
let _bar1 = &foo.bar1.int1;
let bar1 = &foo.bar1.int1;
let _foo1 = &foo.bar1;
let _foo2 = &*foo;
*bar1;
}
fn borrow_mut_and_imm() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1;
let bar1 = &mut foo.bar1;
let _foo1 = &foo.bar2;
*bar1;
}
fn borrow_mut_from_imm() {
let foo = make_foo();
let _bar1 = &mut foo.bar1; //~ ERROR illegal borrow
let bar1 = &mut foo.bar1; //~ ERROR cannot borrow
*bar1;
}
fn borrow_long_path_both_mut() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1.int1;
let _foo1 = &mut foo.bar2.int2;
let bar1 = &mut foo.bar1.int1;
let foo1 = &mut foo.bar2.int2;
*bar1;
*foo1;
}
fn main() {}

View file

@ -22,32 +22,37 @@ fn make_foo() -> Foo { fail!() }
fn borrow_same_field_twice_mut_mut() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1;
let _bar2 = &mut foo.bar1; //~ ERROR conflicts with prior loan
let bar1 = &mut foo.bar1;
let _bar2 = &mut foo.bar1; //~ ERROR cannot borrow
*bar1;
}
fn borrow_same_field_twice_mut_imm() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1;
let _bar2 = &foo.bar1; //~ ERROR conflicts with prior loan
let bar1 = &mut foo.bar1;
let _bar2 = &foo.bar1; //~ ERROR cannot borrow
*bar1;
}
fn borrow_same_field_twice_imm_mut() {
let mut foo = make_foo();
let _bar1 = &foo.bar1;
let _bar2 = &mut foo.bar1; //~ ERROR conflicts with prior loan
let bar1 = &foo.bar1;
let _bar2 = &mut foo.bar1; //~ ERROR cannot borrow
*bar1;
}
fn borrow_same_field_twice_imm_imm() {
let mut foo = make_foo();
let _bar1 = &foo.bar1;
let bar1 = &foo.bar1;
let _bar2 = &foo.bar1;
*bar1;
}
fn borrow_both_mut() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1;
let bar1 = &mut foo.bar1;
let _bar2 = &mut foo.bar2;
*bar1;
}
fn borrow_both_mut_pattern() {
@ -59,66 +64,76 @@ fn borrow_both_mut_pattern() {
fn borrow_var_and_pattern() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1;
let bar1 = &mut foo.bar1;
match foo {
Foo { bar1: ref mut _bar1, bar2: _ } => {}
//~^ ERROR conflicts with prior loan
Foo { bar1: ref mut _bar1, bar2: _ } => {} //
//~^ ERROR cannot borrow
}
*bar1;
}
fn borrow_mut_and_base_imm() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1.int1;
let _foo1 = &foo.bar1; //~ ERROR conflicts with prior loan
let _foo2 = &foo; //~ ERROR conflicts with prior loan
let bar1 = &mut foo.bar1.int1;
let _foo1 = &foo.bar1; //~ ERROR cannot borrow
let _foo2 = &foo; //~ ERROR cannot borrow
*bar1;
}
fn borrow_mut_and_base_mut() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1.int1;
let _foo1 = &mut foo.bar1; //~ ERROR conflicts with prior loan
let bar1 = &mut foo.bar1.int1;
let _foo1 = &mut foo.bar1; //~ ERROR cannot borrow
*bar1;
}
fn borrow_mut_and_base_mut2() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1.int1;
let _foo2 = &mut foo; //~ ERROR conflicts with prior loan
let bar1 = &mut foo.bar1.int1;
let _foo2 = &mut foo; //~ ERROR cannot borrow
*bar1;
}
fn borrow_imm_and_base_mut() {
let mut foo = make_foo();
let _bar1 = &foo.bar1.int1;
let _foo1 = &mut foo.bar1; //~ ERROR conflicts with prior loan
let bar1 = &foo.bar1.int1;
let _foo1 = &mut foo.bar1; //~ ERROR cannot borrow
*bar1;
}
fn borrow_imm_and_base_mut2() {
let mut foo = make_foo();
let _bar1 = &foo.bar1.int1;
let _foo2 = &mut foo; //~ ERROR conflicts with prior loan
let bar1 = &foo.bar1.int1;
let _foo2 = &mut foo; //~ ERROR cannot borrow
*bar1;
}
fn borrow_imm_and_base_imm() {
let mut foo = make_foo();
let _bar1 = &foo.bar1.int1;
let bar1 = &foo.bar1.int1;
let _foo1 = &foo.bar1;
let _foo2 = &foo;
*bar1;
}
fn borrow_mut_and_imm() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1;
let bar1 = &mut foo.bar1;
let _foo1 = &foo.bar2;
*bar1;
}
fn borrow_mut_from_imm() {
let foo = make_foo();
let _bar1 = &mut foo.bar1; //~ ERROR illegal borrow
let bar1 = &mut foo.bar1; //~ ERROR cannot borrow
*bar1;
}
fn borrow_long_path_both_mut() {
let mut foo = make_foo();
let _bar1 = &mut foo.bar1.int1;
let bar1 = &mut foo.bar1.int1;
let _foo1 = &mut foo.bar2.int2;
*bar1;
}
fn main() {}

View file

@ -28,5 +28,6 @@ fn defer<'r>(x: &'r [&'r str]) -> defer<'r> {
}
fn main() {
let _x = defer(~["Goodbye", "world!"]); //~ ERROR illegal borrow
let x = defer(~["Goodbye", "world!"]); //~ ERROR borrowed value does not live long enough
x.x[0];
}

View file

@ -15,7 +15,7 @@ use core::hashmap::HashMap;
fn main() {
let mut buggy_map :HashMap<uint, &uint> =
HashMap::new::<uint, &uint>();
buggy_map.insert(42, &*~1); //~ ERROR illegal borrow
buggy_map.insert(42, &*~1); //~ ERROR borrowed value does not live long enough
// but it is ok if we use a temporary
let tmp = ~2;

View file

@ -27,13 +27,15 @@ fn a(x: &mut Foo) {
fn b(x: &Foo) {
x.f();
x.g();
x.h(); //~ ERROR illegal borrow
x.h(); //~ ERROR cannot borrow
}
fn c(x: &const Foo) {
x.f(); //~ ERROR illegal borrow unless pure
x.f(); //~ ERROR cannot borrow
//~^ ERROR unsafe borrow
x.g();
x.h(); //~ ERROR illegal borrow
x.h(); //~ ERROR cannot borrow
//~^ ERROR unsafe borrow
}
fn main() {

View file

@ -10,9 +10,9 @@
fn main() {
let mut _a = 3;
let _b = &mut _a; //~ NOTE loan of mutable local variable granted here
let _b = &mut _a;
{
let _c = &*_b;
_a = 4; //~ ERROR assigning to mutable local variable prohibited
_a = 4; //~ ERROR cannot assign to `_a`
}
}

View file

@ -23,8 +23,8 @@ pub impl Foo {
}
fn bar(f: &mut Foo) {
do f.foo |a| { //~ NOTE prior loan as mutable granted here
f.n.insert(*a); //~ ERROR conflicts with prior loan
do f.foo |a| {
f.n.insert(*a); //~ ERROR cannot borrow
}
}

View file

@ -10,9 +10,9 @@
fn main() {
let x = Some(~1);
match x { //~ NOTE loan of immutable local variable granted here
match x {
Some(ref _y) => {
let _a = x; //~ ERROR moving out of immutable local variable prohibited due to outstanding loan
let _a = x; //~ ERROR cannot move
}
_ => {}
}

View file

@ -12,7 +12,7 @@ fn main() {
let x = Some(~1);
match x {
Some(ref y) => {
let _b = *y; //~ ERROR moving out of dereference of immutable & pointer
let _b = *y; //~ ERROR cannot move out
}
_ => {}
}

View file

@ -0,0 +1,52 @@
// Copyright 2012 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.
// Note: the borrowck analysis is currently flow-insensitive.
// Therefore, some of these errors are marked as spurious and could be
// corrected by a simple change to the analysis. The others are
// either genuine or would require more advanced changes. The latter
// cases are noted.
fn borrow(_v: &int) {}
fn borrow_mut(_v: &mut int) {}
fn cond() -> bool { fail!() }
fn for_func(_f: &fn() -> bool) { fail!() }
fn produce<T>() -> T { fail!(); }
fn inc(v: &mut ~int) {
*v = ~(**v + 1);
}
fn pre_freeze_cond() {
// In this instance, the freeze is conditional and starts before
// the mut borrow.
let mut v = ~3;
let _w;
if cond() {
_w = &v;
}
borrow_mut(v); //~ ERROR cannot borrow
}
fn pre_freeze_else() {
// In this instance, the freeze and mut borrow are on separate sides
// of the if.
let mut v = ~3;
let _w;
if cond() {
_w = &v;
} else {
borrow_mut(v);
}
}
fn main() {}

View file

@ -0,0 +1,164 @@
// Copyright 2012 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.
// Note: the borrowck analysis is currently flow-insensitive.
// Therefore, some of these errors are marked as spurious and could be
// corrected by a simple change to the analysis. The others are
// either genuine or would require more advanced changes. The latter
// cases are noted.
fn borrow(_v: &int) {}
fn borrow_mut(_v: &mut int) {}
fn cond() -> bool { fail!() }
fn for_func(_f: &fn() -> bool) { fail!() }
fn produce<T>() -> T { fail!(); }
fn inc(v: &mut ~int) {
*v = ~(**v + 1);
}
fn loop_overarching_alias_mut() {
// In this instance, the borrow encompasses the entire loop.
let mut v = ~3;
let mut x = &mut v;
**x += 1;
loop {
borrow(v); //~ ERROR cannot borrow
}
}
fn block_overarching_alias_mut() {
// In this instance, the borrow encompasses the entire closure call.
let mut v = ~3;
let mut x = &mut v;
for 3.times {
borrow(v); //~ ERROR cannot borrow
}
*x = ~5;
}
fn loop_aliased_mut() {
// In this instance, the borrow is carried through the loop.
let mut v = ~3, w = ~4;
let mut _x = &w;
loop {
borrow_mut(v); //~ ERROR cannot borrow
_x = &v;
}
}
fn while_aliased_mut() {
// In this instance, the borrow is carried through the loop.
let mut v = ~3, w = ~4;
let mut _x = &w;
while cond() {
borrow_mut(v); //~ ERROR cannot borrow
_x = &v;
}
}
fn for_loop_aliased_mut() {
// In this instance, the borrow is carried through the loop.
let mut v = ~3, w = ~4;
let mut _x = &w;
for for_func {
borrow_mut(v); //~ ERROR cannot borrow
_x = &v;
}
}
fn loop_aliased_mut_break() {
// In this instance, the borrow is carried through the loop.
let mut v = ~3, w = ~4;
let mut _x = &w;
loop {
borrow_mut(v);
_x = &v;
break;
}
borrow_mut(v); //~ ERROR cannot borrow
}
fn while_aliased_mut_break() {
// In this instance, the borrow is carried through the loop.
let mut v = ~3, w = ~4;
let mut _x = &w;
while cond() {
borrow_mut(v);
_x = &v;
break;
}
borrow_mut(v); //~ ERROR cannot borrow
}
fn for_aliased_mut_break() {
// In this instance, the borrow is carried through the loop.
let mut v = ~3, w = ~4;
let mut _x = &w;
for for_func {
// here we cannot be sure that `for_func` respects the break below
borrow_mut(v); //~ ERROR cannot borrow
_x = &v;
break;
}
borrow_mut(v); //~ ERROR cannot borrow
}
fn while_aliased_mut_cond(cond: bool, cond2: bool) {
let mut v = ~3, w = ~4;
let mut x = &mut w;
while cond {
**x += 1;
borrow(v); //~ ERROR cannot borrow
if cond2 {
x = &mut v; //~ ERROR cannot borrow
}
}
}
fn loop_break_pops_scopes<'r>(_v: &'r mut [uint], f: &fn(&'r mut uint) -> bool) {
// Here we check that when you break out of an inner loop, the
// borrows that go out of scope as you exit the inner loop are
// removed from the bitset.
while cond() {
while cond() {
// this borrow is limited to the scope of `r`...
let r: &'r mut uint = produce();
if !f(&mut *r) {
break; // ...so it is not live as exit the `while` loop here
}
}
}
}
fn loop_loop_pops_scopes<'r>(_v: &'r mut [uint], f: &fn(&'r mut uint) -> bool) {
// Similar to `loop_break_pops_scopes` but for the `loop` keyword
while cond() {
while cond() {
// this borrow is limited to the scope of `r`...
let r: &'r mut uint = produce();
if !f(&mut *r) {
loop; // ...so it is not live as exit (and re-enter) the `while` loop here
}
}
}
}
fn main() {}

View file

@ -0,0 +1,60 @@
// Copyright 2012 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.
// xfail-pretty -- comments are infaithfully preserved
#[allow(unused_variable)];
#[allow(dead_assignment)];
fn cond() -> bool { fail!() }
fn link<'a>(v: &'a uint, w: &mut &'a uint) -> bool { *w = v; true }
fn separate_arms() {
// Here both arms perform assignments, but only is illegal.
let mut x = None;
match x {
None => {
// It is ok to reassign x here, because there is in
// fact no outstanding loan of x!
x = Some(0);
}
Some(ref _i) => {
x = Some(1); //~ ERROR cannot assign
}
}
copy x; // just to prevent liveness warnings
}
fn guard() {
// Here the guard performs a borrow. This borrow "infects" all
// subsequent arms (but not the prior ones).
let mut a = ~3;
let mut b = ~4;
let mut w = &*a;
match 22 {
_ if cond() => {
b = ~5;
}
_ if link(&*b, &mut w) => {
b = ~6; //~ ERROR cannot assign
}
_ => {
b = ~7; //~ ERROR cannot assign
}
}
b = ~8; //~ ERROR cannot assign
}
fn main() {}

View file

@ -15,96 +15,37 @@
// cases are noted.
fn borrow(_v: &int) {}
fn borrow_mut(_v: &mut int) {}
fn cond() -> bool { fail!() }
fn for_func(_f: &fn() -> bool) { fail!() }
fn produce<T>() -> T { fail!(); }
fn inc(v: &mut ~int) {
*v = ~(**v + 1);
}
fn post_aliased_const() {
fn pre_freeze() {
// In this instance, the freeze starts before the mut borrow.
let mut v = ~3;
let _w = &v;
borrow_mut(v); //~ ERROR cannot borrow
}
fn pre_const() {
// In this instance, the freeze starts before the mut borrow.
let mut v = ~3;
borrow(v);
let _w = &const v;
borrow_mut(v);
}
fn post_aliased_mut() {
// SPURIOUS--flow
fn post_freeze() {
// In this instance, the const alias starts after the borrow.
let mut v = ~3;
borrow(v); //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
let _w = &mut v; //~ NOTE prior loan as mutable granted here
}
fn post_aliased_scope(cond: bool) {
let mut v = ~3;
borrow(v);
if cond { inc(&mut v); }
}
fn loop_overarching_alias_mut() {
let mut v = ~3;
let mut _x = &mut v; //~ NOTE prior loan as mutable granted here
loop {
borrow(v); //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
}
}
fn block_overarching_alias_mut() {
let mut v = ~3;
let mut _x = &mut v; //~ NOTE prior loan as mutable granted here
for 3.times {
borrow(v); //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
}
}
fn loop_aliased_mut() {
let mut v = ~3, w = ~4;
let mut _x = &mut w;
loop {
borrow(v); //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
_x = &mut v; //~ NOTE prior loan as mutable granted here
}
}
fn while_aliased_mut(cond: bool) {
let mut v = ~3, w = ~4;
let mut _x = &mut w;
while cond {
borrow(v); //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
_x = &mut v; //~ NOTE prior loan as mutable granted here
}
}
fn while_aliased_mut_cond(cond: bool, cond2: bool) {
let mut v = ~3, w = ~4;
let mut _x = &mut w;
while cond {
borrow(v); //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
if cond2 {
_x = &mut v; //~ NOTE prior loan as mutable granted here
}
}
}
fn loop_in_block() {
let mut v = ~3, w = ~4;
let mut _x = &mut w;
for uint::range(0u, 10u) |_i| {
borrow(v); //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
_x = &mut v; //~ NOTE prior loan as mutable granted here
}
}
fn at_most_once_block() {
fn at_most_once(f: &fn()) { f() }
// Here, the borrow check has no way of knowing that the block is
// executed at most once.
let mut v = ~3, w = ~4;
let mut _x = &mut w;
do at_most_once {
borrow(v); //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
_x = &mut v; //~ NOTE prior loan as mutable granted here
}
borrow_mut(v);
let _w = &v;
}
fn main() {}

View file

@ -14,17 +14,17 @@ fn borrow(v: &int, f: &fn(x: &int)) {
fn box_imm() {
let v = ~3;
let _w = &v; //~ NOTE loan of immutable local variable granted here
let _w = &v;
do task::spawn {
debug!("v=%d", *v);
//~^ ERROR by-move capture of immutable local variable prohibited due to outstanding loan
//~^ ERROR cannot move `v` into closure
}
let v = ~3;
let _w = &v; //~ NOTE loan of immutable local variable granted here
let _w = &v;
task::spawn(|| {
debug!("v=%d", *v);
//~^ ERROR by-move capture of immutable local variable prohibited due to outstanding loan
//~^ ERROR cannot move
});
}

View file

@ -13,8 +13,8 @@ fn take(_v: ~int) {
fn box_imm() {
let v = ~3;
let _w = &v; //~ NOTE loan of immutable local variable granted here
take(v); //~ ERROR moving out of immutable local variable prohibited due to outstanding loan
let _w = &v;
take(v); //~ ERROR cannot move out of `v` because it is borrowed
}
fn main() {

View file

@ -14,8 +14,8 @@ fn borrow(v: &int, f: &fn(x: &int)) {
fn box_imm() {
let mut v = ~3;
do borrow(v) |w| { //~ NOTE loan of mutable local variable granted here
v = ~4; //~ ERROR assigning to captured outer mutable variable in a stack closure prohibited due to outstanding loan
do borrow(v) |w| {
v = ~4; //~ ERROR cannot assign to `v` because it is borrowed
assert!(*v == 3);
assert!(*w == 4);
}

View file

@ -22,13 +22,13 @@ use core::either::{Either, Left, Right};
fn g() {
let mut x: Either<int,float> = Left(3);
io::println(f(&mut x, &x).to_str()); //~ ERROR conflicts with prior loan
io::println(f(&mut x, &x).to_str()); //~ ERROR cannot borrow
}
fn h() {
let mut x: Either<int,float> = Left(3);
let y: &Either<int, float> = &x;
let z: &mut Either<int, float> = &mut x; //~ ERROR conflicts with prior loan
let z: &mut Either<int, float> = &mut x; //~ ERROR cannot borrow
*z = *y;
}

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
struct Point {
struct Point {
x: int,
y: int,
}
@ -38,10 +38,10 @@ fn b() {
// Here I create an outstanding loan and check that we get conflicts:
let q = &mut p; //~ NOTE prior loan as mutable granted here
let q = &mut p;
p + 3; // ok for pure fns
p.times(3); //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
p.times(3); //~ ERROR cannot borrow `p`
q.x += 1;
}

View file

@ -13,7 +13,6 @@ struct point { x: int, y: int }
trait methods {
fn impurem(&self);
fn blockm(&self, f: &fn());
fn purem(&self);
}
impl methods for point {
@ -21,9 +20,6 @@ impl methods for point {
}
fn blockm(&self, f: &fn()) { f() }
fn purem(&self) {
}
}
fn a() {
@ -31,12 +27,11 @@ fn a() {
// Here: it's ok to call even though receiver is mutable, because we
// can loan it out.
p.purem();
p.impurem();
// But in this case we do not honor the loan:
do p.blockm { //~ NOTE loan of mutable local variable granted here
p.x = 10; //~ ERROR assigning to mutable field prohibited due to outstanding loan
do p.blockm {
p.x = 10; //~ ERROR cannot assign
}
}
@ -45,20 +40,21 @@ fn b() {
// Here I create an outstanding loan and check that we get conflicts:
let l = &mut p; //~ NOTE prior loan as mutable granted here
//~^ NOTE prior loan as mutable granted here
p.purem(); //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
p.impurem(); //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
let l = &mut p;
p.impurem(); //~ ERROR cannot borrow
l.x += 1;
}
fn c() {
// Loaning @mut as & is considered legal due to dynamic checks:
// Loaning @mut as & is considered legal due to dynamic checks...
let q = @mut point {x: 3, y: 4};
q.purem();
q.impurem();
// ...but we still detect errors statically when we can.
do q.blockm {
q.x = 10; //~ ERROR cannot assign
}
}
fn main() {

View file

@ -24,8 +24,8 @@ fn has_mut_vec_and_does_not_try_to_change_it() {
fn has_mut_vec_but_tries_to_change_it() {
let mut v = ~[1, 2, 3];
do takes_imm_elt(&v[0]) { //~ NOTE loan of mutable vec content granted here
v[1] = 4; //~ ERROR assigning to mutable vec content prohibited due to outstanding loan
do takes_imm_elt(&v[0]) {
v[1] = 4; //~ ERROR cannot assign
}
}

View file

@ -4,7 +4,7 @@ fn main() {
let foo = ~3;
let _pfoo = &foo;
let _f: @fn() -> int = || *foo + 5;
//~^ ERROR by-move capture
//~^ ERROR cannot move `foo`
let bar = ~3;
let _g = || {

View file

@ -10,7 +10,7 @@
fn main() {
let x: int = 3;
let y: &mut int = &mut x; //~ ERROR illegal borrow
let y: &mut int = &mut x; //~ ERROR cannot borrow
*y = 5;
debug!(*y);
}

View file

@ -10,8 +10,8 @@
fn main() {
let v = @mut [ 1, 2, 3 ];
for v.each |_x| { //~ ERROR illegal borrow
v[1] = 4;
for v.each |_x| {
v[1] = 4; //~ ERROR cannot assign
}
}

View file

@ -11,8 +11,8 @@
struct foo(~int);
fn borrow(x: @mut foo) {
let _y = &***x; //~ ERROR illegal borrow unless pure
*x = foo(~4); //~ NOTE impure due to assigning to dereference of mutable @ pointer
let _y = &***x;
*x = foo(~4); //~ ERROR cannot assign
}
fn main() {

View file

@ -14,5 +14,5 @@ fn write(v: &mut [int]) {
fn main() {
let v = ~[1, 2, 3];
write(v); //~ ERROR illegal borrow
write(v); //~ ERROR cannot borrow
}

View file

@ -19,9 +19,9 @@ enum cycle {
fn main() {
let mut x = ~node(node_ {a: ~empty});
// Create a cycle!
match *x { //~ NOTE loan of mutable local variable granted here
match *x {
node(ref mut y) => {
y.a = x; //~ ERROR moving out of mutable local variable prohibited due to outstanding loan
y.a = x; //~ ERROR cannot move out of
}
empty => {}
};

View file

@ -12,23 +12,24 @@ fn process<T>(_t: T) {}
fn match_const_opt_by_mut_ref(v: &const Option<int>) {
match *v {
Some(ref mut i) => process(i), //~ ERROR illegal borrow
Some(ref mut i) => process(i), //~ ERROR cannot borrow
//~^ ERROR unsafe borrow of aliasable, const value
None => ()
}
}
fn match_const_opt_by_const_ref(v: &const Option<int>) {
match *v {
Some(ref const i) => process(i), //~ ERROR illegal borrow unless pure
//~^ NOTE impure due to
Some(ref const i) => process(i),
//~^ ERROR unsafe borrow of aliasable, const value
None => ()
}
}
fn match_const_opt_by_imm_ref(v: &const Option<int>) {
match *v {
Some(ref i) => process(i), //~ ERROR illegal borrow unless pure
//~^ NOTE impure due to
Some(ref i) => process(i), //~ ERROR cannot borrow
//~^ ERROR unsafe borrow of aliasable, const value
None => ()
}
}

View file

@ -26,7 +26,8 @@ fn match_ref_unused(&&v: Option<int>) {
fn match_const_reg(v: &const Option<int>) -> int {
match *v {
Some(ref i) => {*i} // OK because this is pure
Some(ref i) => {*i} //~ ERROR cannot borrow
//~^ ERROR unsafe borrow
None => {0}
}
}
@ -43,8 +44,8 @@ fn match_const_reg_unused(v: &const Option<int>) {
fn match_const_reg_impure(v: &const Option<int>) {
match *v {
Some(ref i) => {impure(*i)} //~ ERROR illegal borrow unless pure
//~^ NOTE impure due to access to impure function
Some(ref i) => {impure(*i)} //~ ERROR cannot borrow
//~^ ERROR unsafe borrow
None => {}
}
}
@ -56,5 +57,12 @@ fn match_imm_reg(v: &Option<int>) {
}
}
fn match_mut_reg(v: &mut Option<int>) {
match *v {
Some(ref i) => {impure(*i)} // OK, frozen
None => {}
}
}
fn main() {
}

View file

@ -12,11 +12,14 @@
fn main() {
let mut x: Option<int> = None;
match x { //~ NOTE loan of mutable local variable granted here
None => {}
match x {
None => {
// Note: on this branch, no borrow has occurred.
x = Some(0);
}
Some(ref i) => {
// Not ok: i is an outstanding ptr into x.
x = Some(*i+1); //~ ERROR assigning to mutable local variable prohibited due to outstanding loan
// But on this branch, `i` is an outstanding borrow
x = Some(*i+1); //~ ERROR cannot assign to `x`
}
}
copy x; // just to prevent liveness warnings

View file

@ -1,26 +0,0 @@
// Copyright 2012 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.
// xfail-pretty -- comments are infaithfully preserved
fn main() {
let mut x = None;
match x { //~ NOTE loan of mutable local variable granted here
None => {
// It is ok to reassign x here, because there is in
// fact no outstanding loan of x!
x = Some(0);
}
Some(ref _i) => {
x = Some(1); //~ ERROR assigning to mutable local variable prohibited due to outstanding loan
}
}
copy x; // just to prevent liveness warnings
}

View file

@ -20,17 +20,17 @@ struct Bar {
fn borrow_same_field_twice_mut_mut(foo: &mut Foo) {
let _bar1 = &mut foo.bar1;
let _bar2 = &mut foo.bar1; //~ ERROR conflicts with prior loan
let _bar2 = &mut foo.bar1; //~ ERROR cannot borrow
}
fn borrow_same_field_twice_mut_imm(foo: &mut Foo) {
let _bar1 = &mut foo.bar1;
let _bar2 = &foo.bar1; //~ ERROR conflicts with prior loan
let _bar2 = &foo.bar1; //~ ERROR cannot borrow
}
fn borrow_same_field_twice_imm_mut(foo: &mut Foo) {
let _bar1 = &foo.bar1;
let _bar2 = &mut foo.bar1; //~ ERROR conflicts with prior loan
let _bar2 = &mut foo.bar1; //~ ERROR cannot borrow
}
fn borrow_same_field_twice_imm_imm(foo: &mut Foo) {
@ -53,34 +53,34 @@ fn borrow_var_and_pattern(foo: &mut Foo) {
let _bar1 = &mut foo.bar1;
match *foo {
Foo { bar1: ref mut _bar1, bar2: _ } => {}
//~^ ERROR conflicts with prior loan
//~^ ERROR cannot borrow
}
}
fn borrow_mut_and_base_imm(foo: &mut Foo) {
let _bar1 = &mut foo.bar1.int1;
let _foo1 = &foo.bar1; //~ ERROR conflicts with prior loan
let _foo2 = &*foo; //~ ERROR conflicts with prior loan
let _foo1 = &foo.bar1; //~ ERROR cannot borrow
let _foo2 = &*foo; //~ ERROR cannot borrow
}
fn borrow_mut_and_base_mut(foo: &mut Foo) {
let _bar1 = &mut foo.bar1.int1;
let _foo1 = &mut foo.bar1; //~ ERROR conflicts with prior loan
let _foo1 = &mut foo.bar1; //~ ERROR cannot borrow
}
fn borrow_mut_and_base_mut2(foo: &mut Foo) {
let _bar1 = &mut foo.bar1.int1;
let _foo2 = &mut *foo; //~ ERROR conflicts with prior loan
let _foo2 = &mut *foo; //~ ERROR cannot borrow
}
fn borrow_imm_and_base_mut(foo: &mut Foo) {
let _bar1 = &foo.bar1.int1;
let _foo1 = &mut foo.bar1; //~ ERROR conflicts with prior loan
let _foo1 = &mut foo.bar1; //~ ERROR cannot borrow
}
fn borrow_imm_and_base_mut2(foo: &mut Foo) {
let _bar1 = &foo.bar1.int1;
let _foo2 = &mut *foo; //~ ERROR conflicts with prior loan
let _foo2 = &mut *foo; //~ ERROR cannot borrow
}
fn borrow_imm_and_base_imm(foo: &mut Foo) {
@ -95,7 +95,7 @@ fn borrow_mut_and_imm(foo: &mut Foo) {
}
fn borrow_mut_from_imm(foo: &Foo) {
let _bar1 = &mut foo.bar1; //~ ERROR illegal borrow
let _bar1 = &mut foo.bar1; //~ ERROR cannot borrow
}
fn borrow_long_path_both_mut(foo: &mut Foo) {

View file

@ -10,12 +10,12 @@
fn main() {
let msg;
match Some(~"Hello") { //~ ERROR illegal borrow
Some(ref m) => {
match Some(~"Hello") {
Some(ref m) => { //~ ERROR borrowed value does not live long enough
msg = m;
},
},
None => { fail!() }
}
}
io::println(*msg);
}

View file

@ -11,7 +11,7 @@
fn destructure(x: Option<int>) -> int {
match x {
None => 0,
Some(ref mut v) => *v //~ ERROR illegal borrow
Some(ref mut v) => *v //~ ERROR cannot borrow
}
}

View file

@ -28,5 +28,5 @@ struct wrapper(noncopyable);
fn main() {
let x1 = wrapper(noncopyable());
let _x2 = *x1; //~ ERROR moving out of anonymous field
let _x2 = *x1; //~ ERROR cannot move out
}

View file

@ -9,8 +9,8 @@
// except according to those terms.
fn foo(+x: ~int) -> int {
let y = &*x; //~ NOTE loan of argument granted here
free(x); //~ ERROR moving out of argument prohibited due to outstanding loan
let y = &*x;
free(x); //~ ERROR cannot move out of `*x` because it is borrowed
*y
}

View file

@ -1,55 +0,0 @@
// Copyright 2012 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.
struct Rec {
f: ~int,
}
struct Outer {
f: Inner
}
struct Inner {
g: Innermost
}
struct Innermost {
h: ~int,
}
fn borrow(_v: &int) {}
fn box_mut(v: @mut ~int) {
borrow(*v); //~ ERROR illegal borrow unless pure
}
fn box_mut_rec(v: @mut Rec) {
borrow(v.f); //~ ERROR illegal borrow unless pure
}
fn box_mut_recs(v: @mut Outer) {
borrow(v.f.g.h); //~ ERROR illegal borrow unless pure
}
fn box_imm(v: @~int) {
borrow(*v); // OK
}
fn box_imm_rec(v: @Rec) {
borrow(v.f); // OK
}
fn box_imm_recs(v: @Outer) {
borrow(v.f.g.h); // OK
}
fn main() {
}

View file

@ -43,8 +43,8 @@ fn aliased_const() {
fn aliased_mut() {
let mut v = ~3;
let _w = &mut v; //~ NOTE prior loan as mutable granted here
borrow(v); //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
let _w = &mut v;
borrow(v); //~ ERROR cannot borrow `*v`
}
fn aliased_other() {
@ -56,8 +56,8 @@ fn aliased_other() {
fn aliased_other_reassign() {
let mut v = ~3, w = ~4;
let mut _x = &mut w;
_x = &mut v; //~ NOTE prior loan as mutable granted here
borrow(v); //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
_x = &mut v;
borrow(v); //~ ERROR cannot borrow `*v`
}
fn main() {

View file

@ -25,6 +25,7 @@ struct Innermost {
}
fn borrow(_v: &int) {}
fn borrow_const(_v: &const int) {}
fn box_mut(v: &mut ~int) {
borrow(*v); // OK: &mut -> &imm
@ -51,15 +52,15 @@ fn box_imm_recs(v: &Outer) {
}
fn box_const(v: &const ~int) {
borrow(*v); //~ ERROR illegal borrow unless pure
borrow_const(*v); //~ ERROR unsafe borrow
}
fn box_const_rec(v: &const Rec) {
borrow(v.f); //~ ERROR illegal borrow unless pure
borrow_const(v.f); //~ ERROR unsafe borrow
}
fn box_const_recs(v: &const Outer) {
borrow(v.f.g.h); //~ ERROR illegal borrow unless pure
borrow_const(v.f.g.h); //~ ERROR unsafe borrow
}
fn main() {

View file

@ -1,7 +1,7 @@
fn a() -> &[int] {
let vec = [1, 2, 3, 4];
let tail = match vec { //~ ERROR illegal borrow
[_, ..tail] => tail,
let tail = match vec {
[_, ..tail] => tail, //~ ERROR does not live long enough
_ => fail!(~"a")
};
tail
@ -9,8 +9,8 @@ fn a() -> &[int] {
fn b() -> &[int] {
let vec = [1, 2, 3, 4];
let init = match vec { //~ ERROR illegal borrow
[..init, _] => init,
let init = match vec {
[..init, _] => init, //~ ERROR does not live long enough
_ => fail!(~"b")
};
init
@ -18,8 +18,8 @@ fn b() -> &[int] {
fn c() -> &[int] {
let vec = [1, 2, 3, 4];
let slice = match vec { //~ ERROR illegal borrow
[_, ..slice, _] => slice,
let slice = match vec {
[_, ..slice, _] => slice, //~ ERROR does not live long enough
_ => fail!(~"c")
};
slice

View file

@ -2,7 +2,7 @@ fn a() {
let mut v = ~[1, 2, 3];
match v {
[_a, ..tail] => {
v.push(tail[0] + tail[1]); //~ ERROR conflicts with prior loan
v.push(tail[0] + tail[1]); //~ ERROR cannot borrow
}
_ => {}
};

View file

@ -1,8 +1,9 @@
fn main() {
let mut a = [1, 2, 3, 4];
let _ = match a {
let t = match a {
[1, 2, ..tail] => tail,
_ => core::util::unreachable()
};
a[0] = 0; //~ ERROR: assigning to mutable vec content prohibited due to outstanding loan
a[0] = 0; //~ ERROR cannot assign to `a[]` because it is borrowed
t[0];
}

View file

@ -2,7 +2,7 @@ fn a() {
let mut vec = [~1, ~2, ~3];
match vec {
[~ref _a] => {
vec[0] = ~4; //~ ERROR prohibited due to outstanding loan
vec[0] = ~4; //~ ERROR cannot assign to `vec[]` because it is borrowed
}
_ => fail!(~"foo")
}
@ -12,7 +12,7 @@ fn b() {
let mut vec = [~1, ~2, ~3];
match vec {
[.._b] => {
vec[0] = ~4; //~ ERROR prohibited due to outstanding loan
vec[0] = ~4; //~ ERROR cannot assign to `vec[]` because it is borrowed
}
}
}

View file

@ -1,7 +1,7 @@
fn a() -> &int {
let vec = [1, 2, 3, 4];
let tail = match vec { //~ ERROR illegal borrow
[_a, ..tail] => &tail[0],
let tail = match vec {
[_a, ..tail] => &tail[0], //~ ERROR borrowed value does not live long enough
_ => fail!(~"foo")
};
tail

View file

@ -1,6 +1,6 @@
fn main() {
let mut b = ~3;
let _x = &mut *b; //~ NOTE prior loan as mutable granted here
let _y = &mut *b; //~ ERROR loan of dereference of mutable ~ pointer as mutable conflicts with prior loan
let _x = &mut *b;
let _y = &mut *b; //~ ERROR cannot borrow
}

View file

@ -1,8 +1,8 @@
fn main() {
let mut a = ~3;
let mut b = &mut a; //~ NOTE loan of mutable local variable granted here
let mut b = &mut a;
let _c = &mut *b;
let mut d = /*move*/ a; //~ ERROR moving out of mutable local variable prohibited due to outstanding loan
let mut d = /*move*/ a; //~ ERROR cannot move out
*d += 1;
}

View file

@ -1,7 +1,7 @@
fn main() {
let mut b = ~3;
let _x = &mut *b; //~ NOTE loan of mutable local variable granted here
let mut y = /*move*/ b; //~ ERROR moving out of mutable local variable prohibited
let _x = &mut *b;
let mut y = /*move*/ b; //~ ERROR cannot move out
*y += 1;
}

View file

@ -2,7 +2,7 @@ fn foo(x: &mut int) {
let mut a = 3;
let mut _y = &mut *x;
let _z = &mut *_y;
_y = &mut a; //~ ERROR assigning to mutable local variable prohibited
_y = &mut a; //~ ERROR cannot assign
}
fn main() {

View file

@ -31,5 +31,5 @@ fn main() {
// mutability check will fail, because the
// type of r has been inferred to be
// fn(@const int) -> @const int
*r(@mut 3) = 4; //~ ERROR assigning to dereference of const @ pointer
*r(@mut 3) = 4; //~ ERROR cannot assign to const dereference of @ pointer
}

View file

@ -9,11 +9,11 @@
// except according to those terms.
fn f(y: ~int) {
*y = 5; //~ ERROR assigning to dereference of immutable ~ pointer
*y = 5; //~ ERROR cannot assign
}
fn g() {
let _frob: &fn(~int) = |q| { *q = 2; }; //~ ERROR assigning to dereference of immutable ~ pointer
let _frob: &fn(~int) = |q| { *q = 2; }; //~ ERROR cannot assign
}

View file

@ -10,5 +10,5 @@
fn main() {
let z = ();
debug!(z[0]); //~ ERROR cannot index a value of type `()`
let _ = z[0]; //~ ERROR cannot index a value of type `()`
}

View file

@ -8,11 +8,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test that we require managed closures to be rooted when borrowed.
struct boxedFn<'self> { theFn: &'self fn() -> uint }
fn createClosure (closedUint: uint) -> boxedFn {
let theFn: @fn() -> uint = || closedUint;
boxedFn {theFn: theFn} //~ ERROR illegal borrow
boxedFn {theFn: theFn} //~ ERROR cannot root
}
fn main () {

View file

@ -23,5 +23,4 @@ impl<A> vec_monad<A> for ~[A] {
fn main() {
["hi"].bind(|x| [x] );
//~^ ERROR type `[&'static str, .. 1]` does not implement any method in scope named `bind`
//~^^ ERROR Unconstrained region variable
}

View file

@ -10,7 +10,6 @@
fn main() {
for vec::each(fail!()) |i| {
debug!(i * 2);
//~^ ERROR the type of this value must be known
let _ = i * 2; //~ ERROR the type of this value must be known
};
}

View file

@ -18,7 +18,7 @@ trait parse {
impl parse for parser {
fn parse(&self) -> ~[int] {
self.tokens //~ ERROR moving out of immutable field
self.tokens //~ ERROR cannot move out of field
}
}

View file

@ -11,7 +11,6 @@
fn main() {
let needlesArr: ~[char] = ~['a', 'f'];
do vec::foldr(needlesArr) |x, y| {
//~^ ERROR Unconstrained region variable #2
}
//~^ ERROR 2 parameters were supplied (including the closure passed by the `do` keyword)
//

View file

@ -17,5 +17,5 @@ fn f<T:Eq>(o: &mut Option<T>) {
fn main() {
f::<int>(&mut option::None);
//~^ ERROR illegal borrow: creating mutable alias to static item
//~^ ERROR cannot borrow
}

View file

@ -29,4 +29,7 @@ fn main() {
};
assert!(3 == *(y.get())); //~ ERROR dereference of reference outside its lifetime
//~^ ERROR reference is not valid outside of its lifetime
//~^^ ERROR reference is not valid outside of its lifetime
//~^^^ ERROR reference is not valid outside of its lifetime
//~^^^^ ERROR cannot infer an appropriate lifetime
}

View file

@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:assigning to captured outer immutable variable in a stack closure
// Make sure that nesting a block within a @fn doesn't let us
// mutate upvars from a @fn.
fn f2(x: &fn()) { x(); }
@ -16,6 +15,7 @@ fn f2(x: &fn()) { x(); }
fn main() {
let i = 0;
let ctr: @fn() -> int = || { f2(|| i = i + 1 ); i };
//~^ ERROR cannot assign
error!(ctr());
error!(ctr());
error!(ctr());

View file

@ -8,11 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:assigning to captured outer variable in a heap closure
// Make sure we can't write to upvars from @fns
fn main() {
let i = 0;
let ctr: @fn() -> int = || { i = i + 1; i };
//~^ ERROR cannot assign
error!(ctr());
error!(ctr());
error!(ctr());

View file

@ -16,7 +16,7 @@ fn main() {
let s = S { x: ~Bar(~42) };
loop {
do f(&s) |hellothere| {
match hellothere.x { //~ ERROR moving out of immutable field
match hellothere.x { //~ ERROR cannot move out
~Foo(_) => {}
~Bar(x) => io::println(x.to_str()),
~Baz => {}

View file

@ -13,6 +13,6 @@ fn test(_x: ~uint) {}
fn main() {
let i = ~3;
for uint::range(0, 10) |_x| {
test(i); //~ ERROR moving out of captured outer immutable variable in a stack closure
test(i); //~ ERROR cannot move out
}
}

View file

@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:assigning to immutable field
struct cat {
priv mut meows : uint,
@ -17,7 +16,7 @@ struct cat {
pub impl cat {
fn eat(&self) {
self.how_hungry -= 5;
self.how_hungry -= 5; //~ ERROR cannot assign
}
}

View file

@ -8,12 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:assigning to immutable field
struct cat {
priv mut meows : uint,
how_hungry : int,
}
fn cat(in_x : uint, in_y : int) -> cat {
@ -25,5 +22,5 @@ fn cat(in_x : uint, in_y : int) -> cat {
fn main() {
let nyan : cat = cat(52u, 99);
nyan.how_hungry = 0;
nyan.how_hungry = 0; //~ ERROR cannot assign
}

View file

@ -12,7 +12,7 @@ extern mod std;
fn main() {
unsafe fn f(&&v: *const int) {
*v = 1 //~ ERROR assigning to dereference of const * pointer
*v = 1 //~ ERROR cannot assign
}
unsafe {

View file

@ -9,7 +9,7 @@
// except according to those terms.
fn foo(a: int) {
let _p: &'static int = &a; //~ ERROR illegal borrow
let _p: &'static int = &a; //~ ERROR borrowed value does not live long enough
}
fn bar(a: int) {

View file

@ -30,12 +30,12 @@ fn compute(x: &ast) -> uint {
fn map_nums(x: &ast, f: &fn(uint) -> uint) -> &ast {
match *x {
num(x) => {
return &num(f(x)); //~ ERROR illegal borrow
return &num(f(x)); //~ ERROR borrowed value does not live long enough
}
add(x, y) => {
let m_x = map_nums(x, f);
let m_y = map_nums(y, f);
return &add(m_x, m_y); //~ ERROR illegal borrow
return &add(m_x, m_y); //~ ERROR borrowed value does not live long enough
}
}
}

View file

@ -14,8 +14,7 @@ enum ast<'self> {
}
fn mk_add_bad2<'a>(x: &'a ast<'a>, y: &'a ast<'a>, z: &ast) -> ast {
add(x, y)
//~^ ERROR cannot infer an appropriate lifetime
add(x, y) //~ ERROR cannot infer an appropriate lifetime
}
fn main() {

View file

@ -14,6 +14,6 @@ fn with_int(f: &fn(x: &int)) {
}
fn main() {
let mut x: Option<&int> = None; //~ ERROR cannot infer
let mut x: Option<&int> = None; //~ ERROR cannot infer
with_int(|y| x = Some(y));
}

View file

@ -18,6 +18,6 @@ fn main() {
loop {
let x = 1 + *p;
p = &x; //~ ERROR illegal borrow
p = &x; //~ ERROR borrowed value does not live long enough
}
}

View file

@ -14,8 +14,8 @@ fn broken() {
let mut _y = ~[&mut x];
while x < 10 {
let mut z = x;
_y.push(&mut z); //~ ERROR illegal borrow
x += 1; //~ ERROR assigning to mutable local variable prohibited due to outstanding loan
_y.push(&mut z); //~ ERROR borrowed value does not live long enough
x += 1; //~ ERROR cannot assign
}
}

View file

@ -23,13 +23,8 @@ fn with<R:deref>(f: &fn(x: &int) -> R) -> int {
}
fn return_it() -> int {
with(|o| o)
//~^ ERROR cannot infer an appropriate lifetime due to conflicting requirements
//~^^ ERROR reference is not valid outside of its lifetime
//~^^^ ERROR reference is not valid outside of its lifetime
with(|o| o) //~ ERROR reference is not valid outside of its lifetime
}
fn main() {
let x = return_it();
debug!("foo=%d", x);
}

View file

@ -18,7 +18,7 @@ fn x_coord<'r>(p: &'r point) -> &'r int {
}
fn foo(p: @point) -> &int {
let xc = x_coord(p); //~ ERROR illegal borrow
let xc = x_coord(p); //~ ERROR cannot root
assert!(*xc == 3);
return xc;
}

View file

@ -17,7 +17,7 @@ fn foo(cond: &fn() -> bool, box: &fn() -> @int) {
// Here we complain because the resulting region
// of this borrow is the fn body as a whole.
y = borrow(x); //~ ERROR illegal borrow: cannot root managed value long enough
y = borrow(x); //~ ERROR cannot root
assert!(*x == *y);
if cond() { break; }

View file

@ -13,7 +13,7 @@ fn ignore(_f: &fn<'z>(&'z int) -> &'z int) {}
fn nested() {
let y = 3;
ignore(|z| {
if false { &y } else { z } //~ ERROR illegal borrow
if false { &y } else { z } //~ ERROR borrowed value does not live long enough
});
}

View file

@ -16,7 +16,7 @@ fn nested<'x>(x: &'x int) {
ignore::<&fn<'z>(&'z int)>(|z| {
ay = x;
ay = &y; //~ ERROR cannot infer an appropriate lifetime
ay = &y;
ay = z;
});

View file

@ -19,6 +19,7 @@ fn with<'a, R>(f: &fn(x: &'a int) -> R) -> R {
fn return_it<'a>() -> &'a int {
with(|o| o) //~ ERROR mismatched types
//~^ ERROR reference is not valid outside of its lifetime
//~^^ ERROR reference is not valid outside of its lifetime
}
fn main() {

View file

@ -22,6 +22,7 @@ fn with<R>(f: &fn(x: &int) -> R) -> R {
fn return_it() -> &int {
with(|o| o) //~ ERROR mismatched types
//~^ ERROR reference is not valid outside of its lifetime
//~^^ ERROR reference is not valid outside of its lifetime
}
fn main() {

View file

@ -9,7 +9,7 @@
// except according to those terms.
fn f<'a>(_x : &'a int) -> &'a int {
return &3; //~ ERROR illegal borrow
return &3; //~ ERROR borrowed value does not live long enough
}
fn main() {

View file

@ -14,7 +14,7 @@ fn foo(cond: bool) {
let mut x;
if cond {
x = &3; //~ ERROR illegal borrow: borrowed value does not live long enough
x = &3; //~ ERROR borrowed value does not live long enough
assert!((*x == 3));
}
}

View file

@ -10,6 +10,6 @@
fn main() {
5 <-> 3;
//~^ ERROR swapping to and from non-lvalue
//~^^ ERROR swapping to and from non-lvalue
//~^ ERROR cannot assign
//~^^ ERROR cannot assign
}

View file

@ -8,5 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:assigning to immutable vec content
fn main() { let v: ~[int] = ~[1, 2, 3]; v[1] = 4; }
fn main() {
let v: ~[int] = ~[1, 2, 3];
v[1] = 4; //~ ERROR cannot assign
}

View file

@ -8,7 +8,25 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn main () {
let mut _p: & int = & 4;
_p = &*~3; //~ ERROR illegal borrow
// xfail-test #5074 nested method calls
// Test that (safe) nested calls with `&mut` receivers are permitted.
struct Foo {a: uint, b: uint}
pub impl Foo {
fn inc_a(&mut self, v: uint) { self.a += v; }
fn next_b(&mut self) -> uint {
let b = self.b;
self.b += 1;
b
}
}
fn main() {
let mut f = Foo {a: 22, b: 23};
f.inc_a(f.next_b());
assert_eq!(f.a, 22+23);
assert_eq!(f.b, 24);
}

View file

@ -1,10 +1,10 @@
trait Reverser {
fn reverse(&self);
fn reverse(self);
}
impl<'self> Reverser for &'self mut [uint] {
fn reverse(&self) {
vec::reverse(*self);
fn reverse(self) {
vec::reverse(self);
}
}

View file

@ -9,27 +9,25 @@
// except according to those terms.
// This test should behave exactly like issue-2735-3
struct defer<'self> {
b: &'self mut bool,
struct defer {
b: @mut bool,
}
#[unsafe_destructor]
impl<'self> Drop for defer<'self> {
impl Drop for defer {
fn finalize(&self) {
unsafe {
*(self.b) = true;
}
*self.b = true;
}
}
fn defer<'r>(b: &'r mut bool) -> defer<'r> {
fn defer(b: @mut bool) -> defer {
defer {
b: b
}
}
pub fn main() {
let mut dtor_ran = false;
let _ = defer(&mut dtor_ran);
assert!((dtor_ran));
let dtor_ran = @mut false;
let _ = defer(dtor_ran);
assert!(*dtor_ran);
}

View file

@ -9,27 +9,25 @@
// except according to those terms.
// This test should behave exactly like issue-2735-2
struct defer<'self> {
b: &'self mut bool,
struct defer {
b: @mut bool,
}
#[unsafe_destructor]
impl<'self> Drop for defer<'self> {
impl Drop for defer {
fn finalize(&self) {
unsafe {
*(self.b) = true;
}
*self.b = true;
}
}
fn defer<'r>(b: &'r mut bool) -> defer<'r> {
fn defer(b: @mut bool) -> defer {
defer {
b: b
}
}
pub fn main() {
let mut dtor_ran = false;
defer(&mut dtor_ran);
assert!((dtor_ran));
let dtor_ran = @mut false;
defer(dtor_ran);
assert!(*dtor_ran);
}