tests: Add new tests for borrowck/objects and update some existing tests
This commit is contained in:
parent
df016dc4bf
commit
b402e343e4
13 changed files with 265 additions and 22 deletions
|
@ -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() {}
|
42
src/test/compile-fail/borrowck-object-lifetime.rs
Normal file
42
src/test/compile-fail/borrowck-object-lifetime.rs
Normal 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() {}
|
||||
|
47
src/test/compile-fail/borrowck-object-mutability.rs
Normal file
47
src/test/compile-fail/borrowck-object-mutability.rs
Normal 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() {}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
64
src/test/compile-fail/object-pointer-types.rs
Normal file
64
src/test/compile-fail/object-pointer-types.rs
Normal 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
|
|
@ -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() {}
|
||||
|
|
21
src/test/run-fail/borrowck-wg-fail-object.rs
Normal file
21
src/test/run-fail/borrowck-wg-fail-object.rs
Normal 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);
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
32
src/test/run-pass/objects-owned-object-owned-method.rs
Normal file
32
src/test/run-pass/objects-owned-object-owned-method.rs
Normal 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());
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue