]> git.lizzy.rs Git - rust.git/commitdiff
Add two tests for the case of the recurring closure.
authorBen Blum <bblum@andrew.cmu.edu>
Tue, 25 Jun 2013 00:02:24 +0000 (20:02 -0400)
committerBen Blum <bblum@andrew.cmu.edu>
Sat, 29 Jun 2013 08:39:38 +0000 (04:39 -0400)
src/test/compile-fail/the-case-of-the-recurring-closure-2.rs [new file with mode: 0644]
src/test/compile-fail/the-case-of-the-recurring-closure.rs [new file with mode: 0644]

diff --git a/src/test/compile-fail/the-case-of-the-recurring-closure-2.rs b/src/test/compile-fail/the-case-of-the-recurring-closure-2.rs
new file mode 100644 (file)
index 0000000..bfb1e91
--- /dev/null
@@ -0,0 +1,44 @@
+// 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.
+
+// Tests correct kind-checking of the reason stack closures without the :Copy
+// bound must be noncopyable. For details see
+// http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/
+
+struct R<'self> {
+    // This struct is needed to create the
+    // otherwise infinite type of a fn that
+    // accepts itself as argument:
+    c: &'self fn:Copy(&R, bool)
+}
+
+fn innocent_looking_victim() {
+    let mut x = Some(~"hello");
+    do conspirator |f, writer| {
+        if writer {
+            x = None; //~ ERROR cannot implicitly borrow
+        } else {
+            match x {
+                Some(ref msg) => {
+                    (f.c)(f, true);
+                    println(fmt!("%?", msg));
+                },
+                None => fail!("oops"),
+            }
+        }
+    }
+}
+
+fn conspirator(f: &fn:Copy(&R, bool)) {
+    let r = R {c: f};
+    f(&r, false)
+}
+
+fn main() { innocent_looking_victim() }
diff --git a/src/test/compile-fail/the-case-of-the-recurring-closure.rs b/src/test/compile-fail/the-case-of-the-recurring-closure.rs
new file mode 100644 (file)
index 0000000..f05c30c
--- /dev/null
@@ -0,0 +1,44 @@
+// 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.
+
+// Tests correct kind-checking of the reason stack closures without the :Copy
+// bound must be noncopyable. For details see
+// http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/
+
+struct R<'self> {
+    // This struct is needed to create the
+    // otherwise infinite type of a fn that
+    // accepts itself as argument:
+    c: &'self fn(&R, bool)
+}
+
+fn innocent_looking_victim() {
+    let mut x = Some(~"hello");
+    do conspirator |f, writer| {
+        if writer {
+            x = None;
+        } else {
+            match x {
+                Some(ref msg) => {
+                    (f.c)(f, true);
+                    println(fmt!("%?", msg));
+                },
+                None => fail!("oops"),
+            }
+        }
+    }
+}
+
+fn conspirator(f: &fn(&R, bool)) {
+    let r = R {c: f};
+    f(&r, false) //~ ERROR use of moved value
+}
+
+fn main() { innocent_looking_victim() }