tests: Add new tests for borrowck/objects and update some existing tests

This commit is contained in:
Niko Matsakis 2013-08-11 13:58:48 -04:00
parent df016dc4bf
commit b402e343e4
13 changed files with 265 additions and 22 deletions

View File

@ -8,22 +8,17 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Check that `&mut` objects cannot be borrowed twice, just like
// other `&mut` pointers.
trait Foo {
fn f(&self) -> int;
fn f1<'a>(&'a mut self) -> &'a ();
fn f2(&mut self);
}
struct Bar {
x: int
fn test(x: &mut Foo) {
let _y = x.f1();
x.f2(); //~ ERROR cannot borrow `*x` as mutable more than once at a time
}
impl Foo for Bar {
fn f(&self) -> int {
self.x
}
}
pub fn main() {
let x = ~Bar { x: 10 };
let y = x as ~Foo;
assert_eq!(y.f(), 10);
}
fn main() {}

View File

@ -0,0 +1,42 @@
// 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.
trait Foo {
fn borrowed<'a>(&'a self) -> &'a ();
}
fn borrowed_receiver<'a>(x: &'a Foo) -> &'a () {
x.borrowed()
}
fn managed_receiver(x: @Foo) -> &() {
x.borrowed() //~ ERROR cannot root managed value long enough
}
fn managed_receiver_1(x: @Foo) {
*x.borrowed()
}
fn owned_receiver(x: ~Foo) -> &() {
x.borrowed() //~ ERROR borrowed value does not live long enough
}
fn mut_owned_receiver(mut x: ~Foo) {
let _y = x.borrowed();
let _z = &mut x; //~ ERROR cannot borrow
}
fn imm_owned_receiver(mut x: ~Foo) {
let _y = x.borrowed();
let _z = &x;
}
fn main() {}

View File

@ -0,0 +1,47 @@
// 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.
trait Foo {
fn borrowed(&self);
fn borrowed_mut(&mut self);
}
fn borrowed_receiver(x: &Foo) {
x.borrowed();
x.borrowed_mut(); //~ ERROR cannot borrow
}
fn borrowed_mut_receiver(x: &mut Foo) {
x.borrowed();
x.borrowed_mut();
}
fn managed_receiver(x: @Foo) {
x.borrowed();
x.borrowed_mut(); //~ ERROR cannot borrow
}
fn managed_mut_receiver(x: @mut Foo) {
x.borrowed();
x.borrowed_mut();
}
fn owned_receiver(x: ~Foo) {
x.borrowed();
x.borrowed_mut(); //~ ERROR cannot borrow
}
fn mut_owned_receiver(mut x: ~Foo) {
x.borrowed();
x.borrowed_mut();
}
fn main() {}

View File

@ -31,5 +31,4 @@ fn main() {
//~^ ERROR dereference of reference outside its lifetime
//~^^ ERROR automatically borrowed pointer is not valid at the time of borrow
//~^^^ ERROR lifetime of return value does not outlive the function call
//~^^^^ ERROR cannot infer an appropriate lifetime
}

View File

@ -0,0 +1,64 @@
// 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.
trait Foo {
fn borrowed(&self);
fn borrowed_mut(&mut self);
fn managed(@self);
fn managed_mut(@mut self);
fn owned(~self);
}
fn borrowed_receiver(x: &Foo) {
x.borrowed();
x.borrowed_mut(); // See [1]
x.managed(); //~ ERROR does not implement any method
x.managed_mut(); //~ ERROR does not implement any method
x.owned(); //~ ERROR does not implement any method
}
fn borrowed_mut_receiver(x: &mut Foo) {
x.borrowed();
x.borrowed_mut();
x.managed(); //~ ERROR does not implement any method
x.managed_mut(); //~ ERROR does not implement any method
x.owned(); //~ ERROR does not implement any method
}
fn managed_receiver(x: @Foo) {
x.borrowed();
x.borrowed_mut(); // See [1]
x.managed();
x.managed_mut(); //~ ERROR does not implement any method
x.owned(); //~ ERROR does not implement any method
}
fn managed_mut_receiver(x: @mut Foo) {
x.borrowed();
x.borrowed_mut();
x.managed(); //~ ERROR does not implement any method
x.managed_mut();
x.owned(); //~ ERROR does not implement any method
}
fn owned_receiver(x: ~Foo) {
x.borrowed();
x.borrowed_mut(); // See [1]
x.managed(); //~ ERROR does not implement any method
x.managed_mut(); //~ ERROR does not implement any method
x.owned();
}
fn main() {}
// [1]: These cases are illegal, but the error is not detected
// until borrowck, so see the test borrowck-object-mutability.rs

View File

@ -13,7 +13,7 @@ trait add {
}
fn do_add(x: @add, y: @add) -> @add {
x.plus(y) //~ ERROR cannot call a method whose type contains a self-type through a boxed trait
x.plus(y) //~ ERROR cannot call a method whose type contains a self-type through an object
}
fn main() {}

View File

@ -0,0 +1,21 @@
// error-pattern:borrowed
trait Foo {
fn foo(&self, @mut int);
}
impl Foo for int {
fn foo(&self, x: @mut int) {
*x += *self;
}
}
fn main() {
let x = @mut 3_i;
let y = x as @mut Foo;
// The call to `y.foo(...)` should freeze `y` (and thus also `x`,
// since `x === y`). It is thus an error when `foo` tries to
// mutate `x`.
y.foo(x);
}

View File

@ -56,6 +56,6 @@ fn cat(in_x : uint, in_y : int, in_name: ~str) -> cat {
pub fn main() {
let mut nyan: @noisy = @cat(0u, 2, ~"nyan") as @noisy;
let nyan: @mut noisy = @mut cat(0u, 2, ~"nyan") as @mut noisy;
nyan.speak();
}

View File

@ -0,0 +1,39 @@
// Copyright 2013 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 invoked `&self` methods on owned objects where the values
// closed over contain managed values. This implies that the ~ boxes
// will have headers that must be skipped over.
trait FooTrait {
fn foo(&self) -> uint;
}
struct BarStruct {
x: @uint
}
impl FooTrait for BarStruct {
fn foo(&self) -> uint {
*self.x
}
}
pub fn main() {
let foos: ~[ ~FooTrait: ] = ~[
~BarStruct{ x: @0 } as ~FooTrait:,
~BarStruct{ x: @1 } as ~FooTrait:,
~BarStruct{ x: @2 } as ~FooTrait:
];
for i in range(0u, foos.len()) {
assert_eq!(i, foos[i].foo());
}
}

View File

@ -8,6 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test invoked `&self` methods on owned objects where the values
// closed over do not contain managed values, and thus the ~ boxes do
// not have headers.
trait FooTrait {
fn foo(&self) -> uint;
}

View File

@ -0,0 +1,32 @@
// Copyright 2013 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 invoked `&self` methods on owned objects where the values
// closed over contain managed values. This implies that the ~ boxes
// will have headers that must be skipped over.
trait FooTrait {
fn foo(~self) -> uint;
}
struct BarStruct {
x: uint
}
impl FooTrait for BarStruct {
fn foo(~self) -> uint {
self.x
}
}
pub fn main() {
let foo = ~BarStruct{ x: 22 } as ~FooTrait;
assert_eq!(22, foo.foo());
}

View File

@ -502,7 +502,7 @@ impl my_visitor {
unsafe {
let u = my_visitor(**self);
let v = ptr_visit_adaptor::<my_visitor>(Inner {inner: u});
visit_tydesc(inner, @v as @TyVisitor);
visit_tydesc(inner, &v as &TyVisitor);
true
}
}
@ -662,7 +662,7 @@ pub fn main() {
let td = get_tydesc_for(r);
error!("tydesc sz: %u, align: %u",
(*td).size, (*td).align);
let v = @v as @TyVisitor;
let v = &v as &TyVisitor;
visit_tydesc(td, v);
let r = u.vals.clone();

View File

@ -79,7 +79,7 @@ impl TyVisitor for MyVisitor {
fn visit_evec_uniq(&self, _mtbl: uint, inner: *TyDesc) -> bool {
self.types.push(~"[");
unsafe {
visit_tydesc(inner, (@*self) as @TyVisitor);
visit_tydesc(inner, (&*self) as &TyVisitor);
}
self.types.push(~"]");
true
@ -87,7 +87,7 @@ impl TyVisitor for MyVisitor {
fn visit_evec_uniq_managed(&self, _mtbl: uint, inner: *TyDesc) -> bool {
self.types.push(~"[");
unsafe {
visit_tydesc(inner, (@*self) as @TyVisitor);
visit_tydesc(inner, (&*self) as &TyVisitor);
}
self.types.push(~"]");
true
@ -154,7 +154,7 @@ impl TyVisitor for MyVisitor {
fn visit_closure_ptr(&self, _ck: uint) -> bool { true }
}
fn visit_ty<T>(v: @TyVisitor) {
fn visit_ty<T>(v: &TyVisitor) {
unsafe {
visit_tydesc(get_tydesc::<T>(), v);
}