new borrow checker (mass squash)
This commit is contained in:
parent
b5a7e8b353
commit
a896440ca1
172 changed files with 6475 additions and 4303 deletions
|
|
@ -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
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
@ -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!()
|
||||
|
|
|
|||
43
src/test/compile-fail/borrowck-bad-nested-calls-free.rs
Normal file
43
src/test/compile-fail/borrowck-bad-nested-calls-free.rs
Normal 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() {}
|
||||
43
src/test/compile-fail/borrowck-bad-nested-calls-move.rs
Normal file
43
src/test/compile-fail/borrowck-bad-nested-calls-move.rs
Normal 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() {}
|
||||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
|||
52
src/test/compile-fail/borrowck-lend-flow-if.rs
Normal file
52
src/test/compile-fail/borrowck-lend-flow-if.rs
Normal 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() {}
|
||||
164
src/test/compile-fail/borrowck-lend-flow-loop.rs
Normal file
164
src/test/compile-fail/borrowck-lend-flow-loop.rs
Normal 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() {}
|
||||
60
src/test/compile-fail/borrowck-lend-flow-match.rs
Normal file
60
src/test/compile-fail/borrowck-lend-flow-match.rs
Normal 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() {}
|
||||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = || {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 => {}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 => ()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
}
|
||||
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 `()`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 () {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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 => {}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue