From b402e343e4976d0993d8735e8b1c678f7da11f75 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 11 Aug 2013 13:58:48 -0400 Subject: [PATCH] tests: Add new tests for borrowck/objects and update some existing tests --- .../borrowck-borrow-mut-object-twice.rs} | 23 +++---- .../compile-fail/borrowck-object-lifetime.rs | 42 ++++++++++++ .../borrowck-object-mutability.rs | 47 ++++++++++++++ .../kindck-owned-trait-contains.rs | 1 - src/test/compile-fail/object-pointer-types.rs | 64 +++++++++++++++++++ src/test/compile-fail/selftype-traittype.rs | 2 +- src/test/run-fail/borrowck-wg-fail-object.rs | 21 ++++++ src/test/run-pass/class-cast-to-trait.rs | 2 +- ...cts-owned-object-borrowed-method-header.rs | 39 +++++++++++ ...wned-object-borrowed-method-headerless.rs} | 4 ++ .../objects-owned-object-owned-method.rs | 32 ++++++++++ src/test/run-pass/reflect-visit-data.rs | 4 +- src/test/run-pass/reflect-visit-type.rs | 6 +- 13 files changed, 265 insertions(+), 22 deletions(-) rename src/test/{run-pass/unique-object.rs => compile-fail/borrowck-borrow-mut-object-twice.rs} (62%) create mode 100644 src/test/compile-fail/borrowck-object-lifetime.rs create mode 100644 src/test/compile-fail/borrowck-object-mutability.rs create mode 100644 src/test/compile-fail/object-pointer-types.rs create mode 100644 src/test/run-fail/borrowck-wg-fail-object.rs create mode 100644 src/test/run-pass/objects-owned-object-borrowed-method-header.rs rename src/test/run-pass/{owned-trait-objects.rs => objects-owned-object-borrowed-method-headerless.rs} (84%) create mode 100644 src/test/run-pass/objects-owned-object-owned-method.rs diff --git a/src/test/run-pass/unique-object.rs b/src/test/compile-fail/borrowck-borrow-mut-object-twice.rs similarity index 62% rename from src/test/run-pass/unique-object.rs rename to src/test/compile-fail/borrowck-borrow-mut-object-twice.rs index e645f13cd4c..502d7e017b5 100644 --- a/src/test/run-pass/unique-object.rs +++ b/src/test/compile-fail/borrowck-borrow-mut-object-twice.rs @@ -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() {} diff --git a/src/test/compile-fail/borrowck-object-lifetime.rs b/src/test/compile-fail/borrowck-object-lifetime.rs new file mode 100644 index 00000000000..25d5be7ed55 --- /dev/null +++ b/src/test/compile-fail/borrowck-object-lifetime.rs @@ -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 or the MIT license +// , 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() {} + diff --git a/src/test/compile-fail/borrowck-object-mutability.rs b/src/test/compile-fail/borrowck-object-mutability.rs new file mode 100644 index 00000000000..1ea9e3c8815 --- /dev/null +++ b/src/test/compile-fail/borrowck-object-mutability.rs @@ -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 or the MIT license +// , 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() {} + diff --git a/src/test/compile-fail/kindck-owned-trait-contains.rs b/src/test/compile-fail/kindck-owned-trait-contains.rs index 19b38769d95..cf047674cd6 100644 --- a/src/test/compile-fail/kindck-owned-trait-contains.rs +++ b/src/test/compile-fail/kindck-owned-trait-contains.rs @@ -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 } diff --git a/src/test/compile-fail/object-pointer-types.rs b/src/test/compile-fail/object-pointer-types.rs new file mode 100644 index 00000000000..b7d320fbab0 --- /dev/null +++ b/src/test/compile-fail/object-pointer-types.rs @@ -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 or the MIT license +// , 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 diff --git a/src/test/compile-fail/selftype-traittype.rs b/src/test/compile-fail/selftype-traittype.rs index 220573660c5..b5484b786a0 100644 --- a/src/test/compile-fail/selftype-traittype.rs +++ b/src/test/compile-fail/selftype-traittype.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() {} diff --git a/src/test/run-fail/borrowck-wg-fail-object.rs b/src/test/run-fail/borrowck-wg-fail-object.rs new file mode 100644 index 00000000000..73f2cf09552 --- /dev/null +++ b/src/test/run-fail/borrowck-wg-fail-object.rs @@ -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); +} diff --git a/src/test/run-pass/class-cast-to-trait.rs b/src/test/run-pass/class-cast-to-trait.rs index a8ff9061216..737253a956f 100644 --- a/src/test/run-pass/class-cast-to-trait.rs +++ b/src/test/run-pass/class-cast-to-trait.rs @@ -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(); } diff --git a/src/test/run-pass/objects-owned-object-borrowed-method-header.rs b/src/test/run-pass/objects-owned-object-borrowed-method-header.rs new file mode 100644 index 00000000000..23c271f53ca --- /dev/null +++ b/src/test/run-pass/objects-owned-object-borrowed-method-header.rs @@ -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 or the MIT license +// , 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()); + } +} diff --git a/src/test/run-pass/owned-trait-objects.rs b/src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs similarity index 84% rename from src/test/run-pass/owned-trait-objects.rs rename to src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs index c9d0fde6d3c..72ae7cf9bb9 100644 --- a/src/test/run-pass/owned-trait-objects.rs +++ b/src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs @@ -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; } diff --git a/src/test/run-pass/objects-owned-object-owned-method.rs b/src/test/run-pass/objects-owned-object-owned-method.rs new file mode 100644 index 00000000000..0d675c16d1a --- /dev/null +++ b/src/test/run-pass/objects-owned-object-owned-method.rs @@ -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 or the MIT license +// , 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()); +} diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index 2a91d1fc8b5..8ab1bef286c 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -502,7 +502,7 @@ impl my_visitor { unsafe { let u = my_visitor(**self); let v = ptr_visit_adaptor::(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(); diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs index 3ea597e0d59..544f42eb69f 100644 --- a/src/test/run-pass/reflect-visit-type.rs +++ b/src/test/run-pass/reflect-visit-type.rs @@ -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(v: @TyVisitor) { +fn visit_ty(v: &TyVisitor) { unsafe { visit_tydesc(get_tydesc::(), v); }