Ported check_loop from oldvisit to <V:Visit> trait API.

This commit is contained in:
Felix S. Klock II 2013-08-13 02:49:30 +02:00
parent 4127c67406
commit 356341192f

View File

@ -12,7 +12,8 @@
use middle::ty;
use syntax::ast::*;
use syntax::oldvisit;
use syntax::visit;
use syntax::visit::Visitor;
#[deriving(Clone)]
pub struct Context {
@ -20,50 +21,55 @@ pub struct Context {
can_ret: bool
}
struct CheckLoopVisitor {
tcx: ty::ctxt,
}
pub fn check_crate(tcx: ty::ctxt, crate: &Crate) {
oldvisit::visit_crate(crate,
(Context { in_loop: false, can_ret: true },
oldvisit::mk_vt(@oldvisit::Visitor {
visit_item: |i, (_cx, v)| {
oldvisit::visit_item(i, (Context {
visit::walk_crate(&mut CheckLoopVisitor { tcx: tcx },
crate,
Context { in_loop: false, can_ret: true });
}
impl Visitor<Context> for CheckLoopVisitor {
fn visit_item(&mut self, i:@item, _cx:Context) {
visit::walk_item(self, i, Context {
in_loop: false,
can_ret: true
}, v));
},
visit_expr: |e: @expr, (cx, v): (Context, oldvisit::vt<Context>)| {
});
}
fn visit_expr(&mut self, e:@expr, cx:Context) {
match e.node {
expr_while(e, ref b) => {
(v.visit_expr)(e, (cx, v));
(v.visit_block)(b, (Context { in_loop: true,.. cx }, v));
self.visit_expr(e, cx);
self.visit_block(b, Context { in_loop: true,.. cx });
}
expr_loop(ref b, _) => {
(v.visit_block)(b, (Context { in_loop: true,.. cx }, v));
self.visit_block(b, Context { in_loop: true,.. cx });
}
expr_fn_block(_, ref b) => {
(v.visit_block)(b, (Context {
in_loop: false,
can_ret: false
}, v));
self.visit_block(b, Context { in_loop: false, can_ret: false });
}
expr_break(_) => {
if !cx.in_loop {
tcx.sess.span_err(e.span, "`break` outside of loop");
self.tcx.sess.span_err(e.span, "`break` outside of loop");
}
}
expr_again(_) => {
if !cx.in_loop {
tcx.sess.span_err(e.span, "`loop` outside of loop");
self.tcx.sess.span_err(e.span, "`loop` outside of loop");
}
}
expr_ret(oe) => {
if !cx.can_ret {
tcx.sess.span_err(e.span, "`return` in block function");
self.tcx.sess.span_err(e.span, "`return` in block function");
}
oldvisit::visit_expr_opt(oe, (cx, v));
visit::walk_expr_opt(self, oe, cx);
}
_ => oldvisit::visit_expr(e, (cx, v))
_ => visit::walk_expr(self, e, cx)
}
},
.. *oldvisit::default_visitor()
})));
}
}