Skip to content

Commit f331cd9

Browse files
committed
Don't consider loops to be breaking if they contain inner loops that break
Closes #2642
1 parent 613deb0 commit f331cd9

File tree

2 files changed

+23
-9
lines changed

2 files changed

+23
-9
lines changed

src/rustc/util/common.rs

+17-9
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,33 @@ fn field_exprs(fields: [ast::field]) -> [@ast::expr] {
3434
}
3535

3636
// Takes a predicate p, returns true iff p is true for any subexpressions
37-
// of b
38-
fn block_expr_query(b: ast::blk, p: fn@(ast::expr_) -> bool) -> bool {
37+
// of b -- skipping any inner loops (loop, while, loop_body)
38+
fn loop_query(b: ast::blk, p: fn@(ast::expr_) -> bool) -> bool {
3939
let rs = @mut false;
40-
let visit_expr = {|flag: @mut bool, e: @ast::expr| *flag |= p(e.node)};
41-
let v =
42-
visit::mk_simple_visitor(@{visit_expr: {|a|visit_expr(rs, a)}
43-
with *visit::default_simple_visitor()});
44-
visit::visit_block(b, (), v);
40+
let visit_expr = {|e: @ast::expr, &&flag: @mut bool,
41+
v: visit::vt<@mut bool>|
42+
*flag |= p(e.node);
43+
alt e.node {
44+
// Skip inner loops, since a break in the inner loop isn't a
45+
// break inside the outer loop
46+
ast::expr_loop(*) | ast::expr_while(*) | ast::expr_loop_body(*) {}
47+
_ { visit::visit_expr(e, flag, v); }
48+
}
49+
};
50+
let v = visit::mk_vt(@{visit_expr: visit_expr
51+
with *visit::default_visitor()});
52+
visit::visit_block(b, rs, v);
4553
ret *rs;
4654
}
4755

4856
fn has_nonlocal_exits(b: ast::blk) -> bool {
49-
block_expr_query(b) {|e| alt e {
57+
loop_query(b) {|e| alt e {
5058
ast::expr_break | ast::expr_cont { true }
5159
_ { false }}}
5260
}
5361

5462
fn may_break(b: ast::blk) -> bool {
55-
block_expr_query(b) {|e| alt e {
63+
loop_query(b) {|e| alt e {
5664
ast::expr_break { true }
5765
_ { false }}}
5866
}

src/test/run-pass/issue-2642.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fn f() {
2+
let _x: uint = loop { loop { break; } };
3+
}
4+
5+
fn main() {
6+
}

0 commit comments

Comments
 (0)