diff --git a/src/test/compile-fail/borrowck-move-in-irrefut-pat.rs b/src/test/compile-fail/borrowck-move-in-irrefut-pat.rs new file mode 100644 index 00000000000..c99a1ee60d7 --- /dev/null +++ b/src/test/compile-fail/borrowck-move-in-irrefut-pat.rs @@ -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() {} \ No newline at end of file diff --git a/src/test/compile-fail/borrowck-move-out-of-struct-with-dtor.rs b/src/test/compile-fail/borrowck-move-out-of-struct-with-dtor.rs new file mode 100644 index 00000000000..827e35e0c83 --- /dev/null +++ b/src/test/compile-fail/borrowck-move-out-of-struct-with-dtor.rs @@ -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() {} diff --git a/src/test/compile-fail/borrowck-move-out-of-tuple-struct-with-dtor.rs b/src/test/compile-fail/borrowck-move-out-of-tuple-struct-with-dtor.rs new file mode 100644 index 00000000000..6013999d835 --- /dev/null +++ b/src/test/compile-fail/borrowck-move-out-of-tuple-struct-with-dtor.rs @@ -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() {} diff --git a/src/test/compile-fail/regions-ref-in-fn-arg.rs b/src/test/compile-fail/regions-ref-in-fn-arg.rs new file mode 100644 index 00000000000..f90fe924587 --- /dev/null +++ b/src/test/compile-fail/regions-ref-in-fn-arg.rs @@ -0,0 +1,11 @@ +fn arg_item(~ref x: ~int) -> &'static int { + x //~^ ERROR borrowed value does not live long enough +} + +fn with(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() {} \ No newline at end of file diff --git a/src/test/run-pass/func-arg-incomplete-pattern.rs b/src/test/run-pass/func-arg-incomplete-pattern.rs new file mode 100644 index 00000000000..b08d3beae1b --- /dev/null +++ b/src/test/run-pass/func-arg-incomplete-pattern.rs @@ -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); +} \ No newline at end of file diff --git a/src/test/run-pass/func-arg-ref-pattern.rs b/src/test/run-pass/func-arg-ref-pattern.rs new file mode 100644 index 00000000000..84c2b3acf35 --- /dev/null +++ b/src/test/run-pass/func-arg-ref-pattern.rs @@ -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); +} diff --git a/src/test/run-pass/func-arg-wild-pattern.rs b/src/test/run-pass/func-arg-wild-pattern.rs new file mode 100644 index 00000000000..c2d60c85329 --- /dev/null +++ b/src/test/run-pass/func-arg-wild-pattern.rs @@ -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); +} diff --git a/src/test/run-pass/let-destruct-ref.rs b/src/test/run-pass/let-destruct-ref.rs new file mode 100644 index 00000000000..7f3f9110b1c --- /dev/null +++ b/src/test/run-pass/let-destruct-ref.rs @@ -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())); +} diff --git a/src/test/run-pass/match-drop-strs-issue-4541.rs b/src/test/run-pass/match-drop-strs-issue-4541.rs new file mode 100644 index 00000000000..ec65f36dc06 --- /dev/null +++ b/src/test/run-pass/match-drop-strs-issue-4541.rs @@ -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()); +}