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 middle::ty;
|
||||||
|
|
||||||
use syntax::ast::*;
|
use syntax::ast::*;
|
||||||
use syntax::oldvisit;
|
use syntax::visit;
|
||||||
|
use syntax::visit::Visitor;
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
@ -20,50 +21,55 @@ pub struct Context {
|
|||||||
can_ret: bool
|
can_ret: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CheckLoopVisitor {
|
||||||
|
tcx: ty::ctxt,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn check_crate(tcx: ty::ctxt, crate: &Crate) {
|
pub fn check_crate(tcx: ty::ctxt, crate: &Crate) {
|
||||||
oldvisit::visit_crate(crate,
|
visit::walk_crate(&mut CheckLoopVisitor { tcx: tcx },
|
||||||
(Context { in_loop: false, can_ret: true },
|
crate,
|
||||||
oldvisit::mk_vt(@oldvisit::Visitor {
|
Context { in_loop: false, can_ret: true });
|
||||||
visit_item: |i, (_cx, v)| {
|
}
|
||||||
oldvisit::visit_item(i, (Context {
|
|
||||||
|
impl Visitor<Context> for CheckLoopVisitor {
|
||||||
|
fn visit_item(&mut self, i:@item, _cx:Context) {
|
||||||
|
visit::walk_item(self, i, Context {
|
||||||
in_loop: false,
|
in_loop: false,
|
||||||
can_ret: true
|
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 {
|
match e.node {
|
||||||
expr_while(e, ref b) => {
|
expr_while(e, ref b) => {
|
||||||
(v.visit_expr)(e, (cx, v));
|
self.visit_expr(e, cx);
|
||||||
(v.visit_block)(b, (Context { in_loop: true,.. cx }, v));
|
self.visit_block(b, Context { in_loop: true,.. cx });
|
||||||
}
|
}
|
||||||
expr_loop(ref b, _) => {
|
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) => {
|
expr_fn_block(_, ref b) => {
|
||||||
(v.visit_block)(b, (Context {
|
self.visit_block(b, Context { in_loop: false, can_ret: false });
|
||||||
in_loop: false,
|
|
||||||
can_ret: false
|
|
||||||
}, v));
|
|
||||||
}
|
}
|
||||||
expr_break(_) => {
|
expr_break(_) => {
|
||||||
if !cx.in_loop {
|
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(_) => {
|
expr_again(_) => {
|
||||||
if !cx.in_loop {
|
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) => {
|
expr_ret(oe) => {
|
||||||
if !cx.can_ret {
|
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