2011-11-21 03:56:00 -06:00
|
|
|
import syntax::visit;
|
|
|
|
import syntax::ast::*;
|
2012-01-12 10:59:49 -06:00
|
|
|
import driver::session::session;
|
2011-11-21 03:56:00 -06:00
|
|
|
|
2012-03-26 20:35:18 -05:00
|
|
|
type ctx = {tcx: ty::ctxt, mut allow_block: bool};
|
2011-11-21 03:56:00 -06:00
|
|
|
|
|
|
|
fn check_crate(tcx: ty::ctxt, crate: @crate) {
|
2012-03-26 20:35:18 -05:00
|
|
|
let cx = {tcx: tcx, mut allow_block: false};
|
2011-11-21 03:56:00 -06:00
|
|
|
let v = visit::mk_vt(@{visit_expr: visit_expr
|
|
|
|
with *visit::default_visitor()});
|
|
|
|
visit::visit_crate(*crate, cx, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
|
|
|
|
if !cx.allow_block {
|
2012-08-06 14:34:08 -05:00
|
|
|
match ty::get(ty::expr_ty(cx.tcx, ex)).struct {
|
2012-08-03 21:59:04 -05:00
|
|
|
ty::ty_fn({proto: p, _}) if is_blockish(p) => {
|
2012-05-29 14:14:44 -05:00
|
|
|
cx.tcx.sess.span_err(ex.span,
|
2012-07-14 00:57:48 -05:00
|
|
|
~"expressions with stack closure type \
|
2011-11-21 03:56:00 -06:00
|
|
|
can only appear in callee or (by-ref) argument position");
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
_ => {}
|
2011-11-21 03:56:00 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
let outer = cx.allow_block;
|
2012-08-06 14:34:08 -05:00
|
|
|
match ex.node {
|
2012-08-03 21:59:04 -05:00
|
|
|
expr_call(f, args, _) => {
|
2011-11-21 03:56:00 -06:00
|
|
|
cx.allow_block = true;
|
|
|
|
v.visit_expr(f, cx, v);
|
2012-03-15 08:47:03 -05:00
|
|
|
let mut i = 0u;
|
2012-06-30 18:19:07 -05:00
|
|
|
for ty::ty_fn_args(ty::expr_ty(cx.tcx, f)).each |arg_t| {
|
2012-02-02 18:50:17 -06:00
|
|
|
cx.allow_block = (ty::arg_mode(cx.tcx, arg_t) == by_ref);
|
2011-11-21 03:56:00 -06:00
|
|
|
v.visit_expr(args[i], cx, v);
|
|
|
|
i += 1u;
|
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
expr_loop_body(body) | expr_do_body(body) => {
|
2012-03-26 09:09:27 -05:00
|
|
|
cx.allow_block = true;
|
|
|
|
v.visit_expr(body, cx, v);
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
_ => {
|
2011-11-21 03:56:00 -06:00
|
|
|
cx.allow_block = false;
|
|
|
|
visit::visit_expr(ex, cx, v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cx.allow_block = outer;
|
|
|
|
}
|