about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-07-08 18:49:46 -0700
committerbors <bors@rust-lang.org>2013-07-08 18:49:46 -0700
commita48ca3290df992fde2f74ccf5b9f4e36563af8da (patch)
tree816142177cf53d6185626aee592ef837b5e1d93a /src/test
parent30c8aac677a754e0d4ebc16f261618f15d15a6e2 (diff)
parent0c6d02f391aa668b2ead91e8a4ed545475ac2c90 (diff)
downloadrust-a48ca3290df992fde2f74ccf5b9f4e36563af8da.tar.gz
rust-a48ca3290df992fde2f74ccf5b9f4e36563af8da.zip
auto merge of #7262 : nikomatsakis/rust/ref-bindings-in-irrefut-patterns, r=catamorphism
Correct treatment of irrefutable patterns. The old code was wrong in many, many ways. `ref` bindings didn't work, it sometimes copied when it should have moved, the borrow checker didn't even look at such patterns at all, we weren't consistent about preventing values with destructors from being pulled apart, etc.

Fixes #3224.
Fixes #3225.
Fixes #3255.
Fixes #6225.
Fixes #6386.

r? @catamorphism

Diffstat (limited to 'src/test')
-rw-r--r--src/test/bench/shootout-k-nucleotide-pipes.rs4
-rw-r--r--src/test/compile-fail/borrowck-move-in-irrefut-pat.rs16
-rw-r--r--src/test/compile-fail/borrowck-move-out-of-struct-with-dtor.rs22
-rw-r--r--src/test/compile-fail/borrowck-move-out-of-tuple-struct-with-dtor.rs22
-rw-r--r--src/test/compile-fail/borrowck-move-out-of-vec-tail.rs2
-rw-r--r--src/test/compile-fail/borrowck-vec-pattern-nesting.rs37
-rw-r--r--src/test/compile-fail/regions-ref-in-fn-arg.rs11
-rw-r--r--src/test/run-pass-fulldeps/qquote.rs2
-rw-r--r--src/test/run-pass/borrowck-newtype-issue-2573.rs32
-rw-r--r--src/test/run-pass/borrowck-wg-autoderef-and-autoborrowvec-combined-issue-6272.rs6
-rw-r--r--src/test/run-pass/func-arg-incomplete-pattern.rs20
-rw-r--r--src/test/run-pass/func-arg-ref-pattern.rs24
-rw-r--r--src/test/run-pass/func-arg-wild-pattern.rs10
-rw-r--r--src/test/run-pass/let-destruct-ref.rs5
-rw-r--r--src/test/run-pass/match-drop-strs-issue-4541.rs27
-rw-r--r--src/test/run-pass/match-pattern-drop.rs4
-rw-r--r--src/test/run-pass/reflect-visit-type.rs4
-rw-r--r--src/test/run-pass/vec-tail-matching.rs2
18 files changed, 207 insertions, 43 deletions
diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs
index 974cdb0a0ef..919c4daeb25 100644
--- a/src/test/bench/shootout-k-nucleotide-pipes.rs
+++ b/src/test/bench/shootout-k-nucleotide-pipes.rs
@@ -56,8 +56,8 @@ fn sort_and_fmt(mm: &HashMap<~[u8], uint>, total: uint) -> ~str {
    let mut pairs = ~[];
 
    // map -> [(k,%)]
-   for mm.iter().advance |(&key, &val)| {
-      pairs.push((key, pct(val, total)));
+   for mm.iter().advance |(key, &val)| {
+      pairs.push((copy *key, pct(val, total)));
    }
 
    let pairs_sorted = sortKV(pairs);
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..4407329f497
--- /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 drop(&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..400a4f07951
--- /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 drop(&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/borrowck-move-out-of-vec-tail.rs b/src/test/compile-fail/borrowck-move-out-of-vec-tail.rs
index dec976e0a60..91a3d843cd4 100644
--- a/src/test/compile-fail/borrowck-move-out-of-vec-tail.rs
+++ b/src/test/compile-fail/borrowck-move-out-of-vec-tail.rs
@@ -11,7 +11,7 @@ pub fn main() {
         Foo { string: ~"baz" }
     ];
     match x {
-        [first, ..tail] => {
+        [_, ..tail] => {
             match tail {
                 [Foo { string: a }, Foo { string: b }] => {
                     //~^ ERROR cannot move out of dereference of & pointer
diff --git a/src/test/compile-fail/borrowck-vec-pattern-nesting.rs b/src/test/compile-fail/borrowck-vec-pattern-nesting.rs
index 81f052918ed..36ae5f88208 100644
--- a/src/test/compile-fail/borrowck-vec-pattern-nesting.rs
+++ b/src/test/compile-fail/borrowck-vec-pattern-nesting.rs
@@ -17,4 +17,41 @@ fn b() {
     }
 }
 
+fn c() {
+    let mut vec = [~1, ~2, ~3];
+    match vec {
+        [_a, .._b] => {
+            //~^ ERROR cannot move out
+
+            // Note: `_a` is *moved* here, but `b` is borrowing,
+            // hence illegal.
+            //
+            // See comment in middle/borrowck/gather_loans/mod.rs
+            // in the case covering these sorts of vectors.
+        }
+        _ => {}
+    }
+    let a = vec[0]; //~ ERROR use of partially moved value: `vec`
+}
+
+fn d() {
+    let mut vec = [~1, ~2, ~3];
+    match vec {
+        [.._a, _b] => {
+            //~^ ERROR cannot move out
+        }
+        _ => {}
+    }
+    let a = vec[0]; //~ ERROR use of partially moved value: `vec`
+}
+
+fn e() {
+    let mut vec = [~1, ~2, ~3];
+    match vec {
+        [_a, _b, _c] => {}
+        _ => {}
+    }
+    let a = vec[0]; //~ ERROR use of partially moved value: `vec`
+}
+
 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<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() {}
\ No newline at end of file
diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs
index 9a3ba32390c..92344aae73e 100644
--- a/src/test/run-pass-fulldeps/qquote.rs
+++ b/src/test/run-pass-fulldeps/qquote.rs
@@ -68,7 +68,7 @@ fn main() {
     check_pp(ext_cx, *stmt, pprust::print_stmt, ~"let x = 20;");
 
     let pat = quote_pat!(Some(_));
-    check_pp(ext_cx, pat, pprust::print_refutable_pat, ~"Some(_)");
+    check_pp(ext_cx, pat, pprust::print_pat, ~"Some(_)");
 
 }
 
diff --git a/src/test/run-pass/borrowck-newtype-issue-2573.rs b/src/test/run-pass/borrowck-newtype-issue-2573.rs
deleted file mode 100644
index 5f0c7cad619..00000000000
--- a/src/test/run-pass/borrowck-newtype-issue-2573.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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.
-
-struct foo {bar: baz}
-
-struct baz_ {baz: int}
-
-type baz = @mut baz_;
-
-trait frob {
-    fn frob(&self);
-}
-
-impl frob for foo {
-    fn frob(&self) {
-        really_impure(self.bar);
-    }
-}
-
-// Override default mode so that we are passing by value
-fn really_impure(bar: baz) {
-    bar.baz = 3;
-}
-
-pub fn main() {}
diff --git a/src/test/run-pass/borrowck-wg-autoderef-and-autoborrowvec-combined-issue-6272.rs b/src/test/run-pass/borrowck-wg-autoderef-and-autoborrowvec-combined-issue-6272.rs
index 056397f55ff..5da7a6f2b56 100644
--- a/src/test/run-pass/borrowck-wg-autoderef-and-autoborrowvec-combined-issue-6272.rs
+++ b/src/test/run-pass/borrowck-wg-autoderef-and-autoborrowvec-combined-issue-6272.rs
@@ -28,12 +28,12 @@
 
 
 fn main() {
-    let a = @mut [3i];
+    let a = @mut 3i;
     let b = @mut [a];
-    let c = @mut b;
+    let c = @mut [3];
 
     // this should freeze `a` only
-    let _x: &mut [int] = c[0];
+    let _x: &mut int = a;
 
     // hence these writes should not fail:
     b[0] = b[0];
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..2a629b62534
--- /dev/null
+++ b/src/test/run-pass/match-drop-strs-issue-4541.rs
@@ -0,0 +1,27 @@
+// 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;
+use std::os;
+
+fn parse_args() -> ~str {
+    let args = 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());
+}
diff --git a/src/test/run-pass/match-pattern-drop.rs b/src/test/run-pass/match-pattern-drop.rs
index 71bbb1768e8..3ce4ef8a94c 100644
--- a/src/test/run-pass/match-pattern-drop.rs
+++ b/src/test/run-pass/match-pattern-drop.rs
@@ -14,8 +14,11 @@
 enum t { make_t(@int), clam, }
 
 fn foo(s: @int) {
+    debug!(::std::sys::refcount(s));
     let count = ::std::sys::refcount(s);
     let x: t = make_t(s); // ref up
+    assert_eq!(::std::sys::refcount(s), count + 1u);
+    debug!(::std::sys::refcount(s));
 
     match x {
       make_t(y) => {
@@ -38,6 +41,5 @@ pub fn main() {
 
     debug!("%u", ::std::sys::refcount(s));
     let count2 = ::std::sys::refcount(s);
-    let _ = ::std::sys::refcount(s); // don't get bitten by last-use.
     assert_eq!(count, count2);
 }
diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs
index 4ce229526ff..f8c369c2e5f 100644
--- a/src/test/run-pass/reflect-visit-type.rs
+++ b/src/test/run-pass/reflect-visit-type.rs
@@ -163,8 +163,8 @@ pub fn main() {
     visit_ty::<i16>(vv);
     visit_ty::<~[int]>(vv);
 
-    for v.types.iter().advance |&s| {
-        println(fmt!("type: %s", s));
+    for v.types.iter().advance |s| {
+        println(fmt!("type: %s", copy *s));
     }
     assert_eq!((*v.types).clone(), ~[~"bool", ~"int", ~"i8", ~"i16", ~"[", ~"int", ~"]"]);
 }
diff --git a/src/test/run-pass/vec-tail-matching.rs b/src/test/run-pass/vec-tail-matching.rs
index 6e1a47ad2df..27f4fc83351 100644
--- a/src/test/run-pass/vec-tail-matching.rs
+++ b/src/test/run-pass/vec-tail-matching.rs
@@ -9,7 +9,7 @@ pub fn main() {
         Foo { string: ~"baz" }
     ];
     match x {
-        [first, ..tail] => {
+        [ref first, ..tail] => {
             assert!(first.string == ~"foo");
             assert_eq!(tail.len(), 2);
             assert!(tail[0].string == ~"bar");