Skip to content

Commit b89a5af

Browse files
committed
Check in a forgotten new file
1 parent 87e097a commit b89a5af

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

src/rustc/middle/check_loop.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import syntax::ast::*;
2+
import syntax::visit;
3+
import driver::session::session;
4+
5+
type ctx = {in_loop: bool, can_ret: bool};
6+
7+
fn check_crate(sess: session, crate: @crate) {
8+
visit::visit_crate(*crate, {in_loop: false,can_ret: true}, visit::mk_vt(@{
9+
visit_item: {|i, _cx, v|
10+
visit::visit_item(i, {in_loop: false, can_ret: true}, v);
11+
},
12+
visit_expr: {|e: @expr, cx: ctx, v: visit::vt<ctx>|
13+
alt e.node {
14+
expr_for(_, e, b) | expr_while(e, b) | expr_do_while(b, e) {
15+
v.visit_expr(e, cx, v);
16+
v.visit_block(b, {in_loop: true with cx}, v);
17+
}
18+
expr_loop(b) {
19+
v.visit_block(b, {in_loop: true with cx}, v);
20+
}
21+
expr_fn(_, _, _, _) {
22+
visit::visit_expr(e, {in_loop: false, can_ret: true}, v);
23+
}
24+
expr_fn_block(fn_decl, blk) {
25+
visit::visit_expr(e, {in_loop: false, can_ret: false}, v);
26+
}
27+
expr_break {
28+
if !cx.in_loop {
29+
sess.span_err(e.span, "`break` outside of loop");
30+
}
31+
}
32+
expr_cont {
33+
if !cx.in_loop {
34+
sess.span_err(e.span, "`cont` outside of loop");
35+
}
36+
}
37+
expr_ret(oe) {
38+
if !cx.can_ret {
39+
sess.span_err(e.span, "`ret` in block function");
40+
}
41+
visit::visit_expr_opt(oe, cx, v);
42+
}
43+
expr_be(re) {
44+
if !cx.can_ret {
45+
sess.span_err(e.span, "`be` in block function");
46+
}
47+
v.visit_expr(re, cx, v);
48+
}
49+
_ { visit::visit_expr(e, cx, v); }
50+
}
51+
}
52+
with *visit::default_visitor()
53+
}));
54+
}

0 commit comments

Comments
 (0)