From 6876916a45f14973897dd05fe4dfdd2b47ac9607 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Wed, 18 Dec 2013 00:06:20 +1100 Subject: [PATCH] rustc: Allow `return` to return from a closure. With the old `for` gone, this behaviour is no longer conflicting with that use of `return` in closures, and this allows shortcircuiting in a closure. --- src/librustc/middle/check_loop.rs | 6 --- .../compile-fail/return-in-block-function.rs | 15 ------- src/test/run-pass/return-from-closure.rs | 41 +++++++++++++++++++ 3 files changed, 41 insertions(+), 21 deletions(-) delete mode 100644 src/test/compile-fail/return-in-block-function.rs create mode 100644 src/test/run-pass/return-from-closure.rs diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs index a08884857a6..332e63288a1 100644 --- a/src/librustc/middle/check_loop.rs +++ b/src/librustc/middle/check_loop.rs @@ -47,12 +47,6 @@ impl Visitor for CheckLoopVisitor { } ast::ExprBreak(_) => self.require_loop("break", cx, e.span), ast::ExprAgain(_) => self.require_loop("continue", cx, e.span), - ast::ExprRet(oe) => { - if cx == Closure { - self.tcx.sess.span_err(e.span, "`return` in a closure"); - } - visit::walk_expr_opt(self, oe, cx); - } _ => visit::walk_expr(self, e, cx) } } diff --git a/src/test/compile-fail/return-in-block-function.rs b/src/test/compile-fail/return-in-block-function.rs deleted file mode 100644 index f231810cbf1..00000000000 --- a/src/test/compile-fail/return-in-block-function.rs +++ /dev/null @@ -1,15 +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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn main() { - let _x = || { - return //~ ERROR: `return` in a closure - }; -} diff --git a/src/test/run-pass/return-from-closure.rs b/src/test/run-pass/return-from-closure.rs new file mode 100644 index 00000000000..1756d74a81e --- /dev/null +++ b/src/test/run-pass/return-from-closure.rs @@ -0,0 +1,41 @@ +// 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. + +// just to make sure that `return` is only returning from the closure, +// not the surrounding function. +static mut calls: uint = 0; + +fn surrounding() { + let return_works = |n: int| { + unsafe { calls += 1 } + + if n >= 0 { return; } + fail!() + }; + + return_works(10); + return_works(20); + + + let return_works_proc = proc(n: int) { + unsafe { calls += 1 } + + if n >= 0 { return; } + fail!() + }; + + return_works_proc(10); +} + +pub fn main() { + surrounding(); + + assert_eq!(unsafe {calls}, 3); +}