Ported check_loop from oldvisit to <V:Visit> trait API.
This commit is contained in:
parent
4127c67406
commit
356341192f
@ -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()
|
||||
})));
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user