From f331cd9324e4c4246fb3f332720a444042267e69 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Wed, 20 Jun 2012 18:50:44 -0700 Subject: [PATCH] Don't consider loops to be breaking if they contain inner loops that break Closes #2642 --- src/rustc/util/common.rs | 26 +++++++++++++++++--------- src/test/run-pass/issue-2642.rs | 6 ++++++ 2 files changed, 23 insertions(+), 9 deletions(-) create mode 100644 src/test/run-pass/issue-2642.rs diff --git a/src/rustc/util/common.rs b/src/rustc/util/common.rs index ec599e72c4c..e12aa98b67a 100644 --- a/src/rustc/util/common.rs +++ b/src/rustc/util/common.rs @@ -34,25 +34,33 @@ fn field_exprs(fields: [ast::field]) -> [@ast::expr] { } // Takes a predicate p, returns true iff p is true for any subexpressions -// of b -fn block_expr_query(b: ast::blk, p: fn@(ast::expr_) -> bool) -> bool { +// of b -- skipping any inner loops (loop, while, loop_body) +fn loop_query(b: ast::blk, p: fn@(ast::expr_) -> bool) -> bool { let rs = @mut false; - let visit_expr = {|flag: @mut bool, e: @ast::expr| *flag |= p(e.node)}; - let v = - visit::mk_simple_visitor(@{visit_expr: {|a|visit_expr(rs, a)} - with *visit::default_simple_visitor()}); - visit::visit_block(b, (), v); + let visit_expr = {|e: @ast::expr, &&flag: @mut bool, + v: visit::vt<@mut bool>| + *flag |= p(e.node); + alt e.node { + // Skip inner loops, since a break in the inner loop isn't a + // break inside the outer loop + ast::expr_loop(*) | ast::expr_while(*) | ast::expr_loop_body(*) {} + _ { visit::visit_expr(e, flag, v); } + } + }; + let v = visit::mk_vt(@{visit_expr: visit_expr + with *visit::default_visitor()}); + visit::visit_block(b, rs, v); ret *rs; } fn has_nonlocal_exits(b: ast::blk) -> bool { - block_expr_query(b) {|e| alt e { + loop_query(b) {|e| alt e { ast::expr_break | ast::expr_cont { true } _ { false }}} } fn may_break(b: ast::blk) -> bool { - block_expr_query(b) {|e| alt e { + loop_query(b) {|e| alt e { ast::expr_break { true } _ { false }}} } diff --git a/src/test/run-pass/issue-2642.rs b/src/test/run-pass/issue-2642.rs new file mode 100644 index 00000000000..63e1fda60a8 --- /dev/null +++ b/src/test/run-pass/issue-2642.rs @@ -0,0 +1,6 @@ +fn f() { + let _x: uint = loop { loop { break; } }; +} + +fn main() { +} -- GitLab