From d7544fe987104ad0a82b1929b819cfd7e2321bb2 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Mon, 24 Jun 2013 20:02:24 -0400 Subject: [PATCH] Add two tests for the case of the recurring closure. --- .../the-case-of-the-recurring-closure-2.rs | 44 +++++++++++++++++++ .../the-case-of-the-recurring-closure.rs | 44 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 src/test/compile-fail/the-case-of-the-recurring-closure-2.rs create mode 100644 src/test/compile-fail/the-case-of-the-recurring-closure.rs 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 index 000000000000..bfb1e910495d --- /dev/null +++ b/src/test/compile-fail/the-case-of-the-recurring-closure-2.rs @@ -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 or the MIT license +// , 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 index 000000000000..f05c30c3355e --- /dev/null +++ b/src/test/compile-fail/the-case-of-the-recurring-closure.rs @@ -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 or the MIT license +// , 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() }