Add new tests for irrefutable patterns used in various tricky ways

This commit is contained in:
Niko Matsakis 2013-06-20 15:11:47 -04:00
parent 17b3712487
commit 1670a8cfb1
9 changed files with 156 additions and 0 deletions

View File

@ -0,0 +1,16 @@
fn with(f: &fn(&~str)) {}
fn arg_item(&_x: &~str) {}
//~^ ERROR cannot move out of dereference of & pointer
fn arg_closure() {
with(|&_x| ())
//~^ ERROR cannot move out of dereference of & pointer
}
fn let_pat() {
let &_x = &~"hi";
//~^ ERROR cannot move out of dereference of & pointer
}
pub fn main() {}

View File

@ -0,0 +1,22 @@
struct S {f:~str}
impl Drop for S {
fn finalize(&self) { println(self.f); }
}
fn move_in_match() {
match S {f:~"foo"} {
S {f:_s} => {}
//~^ ERROR cannot move out of type `S`, which defines the `Drop` trait
}
}
fn move_in_let() {
let S {f:_s} = S {f:~"foo"};
//~^ ERROR cannot move out of type `S`, which defines the `Drop` trait
}
fn move_in_fn_arg(S {f:_s}: S) {
//~^ ERROR cannot move out of type `S`, which defines the `Drop` trait
}
fn main() {}

View File

@ -0,0 +1,22 @@
struct S(~str);
impl Drop for S {
fn finalize(&self) { println(**self); }
}
fn move_in_match() {
match S(~"foo") {
S(_s) => {}
//~^ ERROR cannot move out of type `S`, which defines the `Drop` trait
}
}
fn move_in_let() {
let S(_s) = S(~"foo");
//~^ ERROR cannot move out of type `S`, which defines the `Drop` trait
}
fn move_in_fn_arg(S(_s): S) {
//~^ ERROR cannot move out of type `S`, which defines the `Drop` trait
}
fn main() {}

View File

@ -0,0 +1,11 @@
fn arg_item(~ref x: ~int) -> &'static int {
x //~^ ERROR borrowed value does not live long enough
}
fn with<R>(f: &fn(~int) -> R) -> R { f(~3) }
fn arg_closure() -> &'static int {
with(|~ref x| x) //~ ERROR borrowed value does not live long enough
}
fn main() {}

View File

@ -0,0 +1,20 @@
// Test that we do not leak when the arg pattern must drop part of the
// argument (in this case, the `y` field).
struct Foo {
x: ~uint,
y: ~uint,
}
fn foo(Foo {x, _}: Foo) -> *uint {
let addr: *uint = &*x;
addr
}
fn main() {
let obj = ~1;
let objptr: *uint = &*obj;
let f = Foo {x: obj, y: ~2};
let xptr = foo(f);
assert_eq!(objptr, xptr);
}

View File

@ -0,0 +1,24 @@
// exec-env:RUST_POISON_ON_FREE=1
// Test argument patterns where we create refs to the inside of `~`
// boxes. Make sure that we don't free the box as we match the
// pattern.
fn getaddr(~ref x: ~uint) -> *uint {
let addr: *uint = &*x;
addr
}
fn checkval(~ref x: ~uint) -> uint {
*x
}
fn main() {
let obj = ~1;
let objptr: *uint = &*obj;
let xptr = getaddr(obj);
assert_eq!(objptr, xptr);
let obj = ~22;
assert_eq!(checkval(obj), 22);
}

View File

@ -0,0 +1,10 @@
// Test that we can compile code that uses a `_` in function argument
// patterns.
fn foo((x, _): (int, int)) -> int {
x
}
fn main() {
assert_eq!(foo((22, 23)), 22);
}

View File

@ -0,0 +1,5 @@
fn main() {
let x = ~"hello";
let ref y = x;
assert_eq!(x.slice(0, x.len()), y.slice(0, y.len()));
}

View File

@ -0,0 +1,26 @@
// Tests a tricky scenario involving string matching,
// copying, and moving to ensure that we don't segfault
// or double-free, as we were wont to do in the past.
use std::io;
fn parse_args() -> ~str {
let args = std::os::args();
let mut n = 0;
while n < args.len() {
match copy args[n] {
~"-v" => (),
s => {
return s;
}
}
n += 1;
}
return ~""
}
fn main() {
io::println(parse_args());
}