Add 'do' expressions
This commit is contained in:
@@ -174,7 +174,7 @@ impl public_methods for borrowck_ctxt {
|
||||
ast::expr_swap(*) | ast::expr_move(*) | ast::expr_assign(*) |
|
||||
ast::expr_assign_op(*) | ast::expr_fn(*) | ast::expr_fn_block(*) |
|
||||
ast::expr_assert(*) | ast::expr_check(*) | ast::expr_ret(*) |
|
||||
ast::expr_loop_body(*) | ast::expr_unary(*) |
|
||||
ast::expr_loop_body(*) | ast::expr_do_body(*) | ast::expr_unary(*) |
|
||||
ast::expr_copy(*) | ast::expr_cast(*) | ast::expr_fail(*) |
|
||||
ast::expr_vstore(*) | ast::expr_vec(*) | ast::expr_tup(*) |
|
||||
ast::expr_if_check(*) | ast::expr_if(*) | ast::expr_log(*) |
|
||||
|
||||
@@ -412,7 +412,8 @@ fn visit_expr(expr: @expr, &&self: @ir_maps, vt: vt<@ir_maps>) {
|
||||
expr_vec(*) | expr_rec(*) | expr_call(*) | expr_tup(*) |
|
||||
expr_bind(*) | expr_new(*) | expr_log(*) | expr_binary(*) |
|
||||
expr_assert(*) | expr_check(*) | expr_addr_of(*) | expr_copy(*) |
|
||||
expr_loop_body(*) | expr_cast(*) | expr_unary(*) | expr_fail(*) |
|
||||
expr_loop_body(*) | expr_do_body(*) | expr_cast(*) |
|
||||
expr_unary(*) | expr_fail(*) |
|
||||
expr_break | expr_cont | expr_lit(_) | expr_ret(*) |
|
||||
expr_block(*) | expr_move(*) | expr_assign(*) | expr_swap(*) |
|
||||
expr_assign_op(*) | expr_mac(*) {
|
||||
@@ -1054,6 +1055,7 @@ class liveness {
|
||||
expr_addr_of(_, e) |
|
||||
expr_copy(e) |
|
||||
expr_loop_body(e) |
|
||||
expr_do_body(e) |
|
||||
expr_cast(e, _) |
|
||||
expr_unary(_, e) {
|
||||
self.propagate_through_expr(e, succ)
|
||||
@@ -1406,7 +1408,8 @@ fn check_expr(expr: @expr, &&self: @liveness, vt: vt<@liveness>) {
|
||||
expr_vec(*) | expr_rec(*) | expr_tup(*) |
|
||||
expr_bind(*) | expr_new(*) | expr_log(*) | expr_binary(*) |
|
||||
expr_assert(*) | expr_check(*) | expr_copy(*) |
|
||||
expr_loop_body(*) | expr_cast(*) | expr_unary(*) | expr_fail(*) |
|
||||
expr_loop_body(*) | expr_do_body(*) |
|
||||
expr_cast(*) | expr_unary(*) | expr_fail(*) |
|
||||
expr_ret(*) | expr_break | expr_cont | expr_lit(_) |
|
||||
expr_block(*) | expr_swap(*) | expr_mac(*) | expr_addr_of(*) {
|
||||
visit::visit_expr(expr, self, vt);
|
||||
|
||||
@@ -3622,6 +3622,9 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
|
||||
ast::expr_loop_body(blk) {
|
||||
ret trans_loop_body(bcx, e, none, dest);
|
||||
}
|
||||
ast::expr_do_body(blk) {
|
||||
ret trans_expr(bcx, blk, dest);
|
||||
}
|
||||
ast::expr_bind(f, args) {
|
||||
ret closure::trans_bind(
|
||||
bcx, f, args, e.id, dest);
|
||||
|
||||
@@ -223,7 +223,8 @@ fn mark_for_expr(cx: ctx, e: @expr) {
|
||||
expr_while(_, _) | expr_fail(_) | expr_break | expr_cont |
|
||||
expr_unary(_, _) | expr_lit(_) | expr_assert(_) | expr_check(_, _) |
|
||||
expr_if_check(_, _, _) | expr_mac(_) | expr_addr_of(_, _) |
|
||||
expr_ret(_) | expr_loop(_) | expr_bind(_, _) | expr_loop_body(_) {}
|
||||
expr_ret(_) | expr_loop(_) | expr_bind(_, _) |
|
||||
expr_loop_body(_) | expr_do_body(_) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -364,7 +364,7 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) {
|
||||
} else { find_pre_post_exprs(fcx, [l, r], e.id); }
|
||||
}
|
||||
expr_addr_of(_, x) | expr_cast(x, _) | expr_unary(_, x) |
|
||||
expr_loop_body(x) | expr_assert(x) | expr_copy(x) {
|
||||
expr_loop_body(x) | expr_do_body(x) | expr_assert(x) | expr_copy(x) {
|
||||
find_pre_post_expr(fcx, x);
|
||||
copy_pre_post(fcx.ccx, e.id, x);
|
||||
}
|
||||
|
||||
@@ -486,7 +486,8 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool {
|
||||
}
|
||||
ret changed | set_poststate_ann(fcx.ccx, e.id, a_post);
|
||||
}
|
||||
expr_field(x, _, _) | expr_loop_body(x) | expr_unary(_, x) |
|
||||
expr_field(x, _, _) | expr_loop_body(x) | expr_do_body(x) |
|
||||
expr_unary(_, x) |
|
||||
expr_addr_of(_, x) | expr_assert(x) | expr_cast(x, _) |
|
||||
expr_copy(x) {
|
||||
ret find_pre_post_state_sub(fcx, pres, x, e.id, none);
|
||||
|
||||
@@ -1364,6 +1364,32 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::expr_do_body(b) {
|
||||
let expected_sty = unpack_expected(fcx, expected, {|x|some(x)}).get();
|
||||
let (inner_ty, proto) = alt expected_sty {
|
||||
ty::ty_fn(fty) {
|
||||
(ty::mk_fn(tcx, fty), fty.proto)
|
||||
}
|
||||
_ {
|
||||
tcx.sess.span_fatal(expr.span, "a do function's last argument \
|
||||
should be of function type");
|
||||
}
|
||||
};
|
||||
alt check b.node {
|
||||
ast::expr_fn_block(decl, body, cap_clause) {
|
||||
check_expr_fn(fcx, b, proto, decl, body, true, some(inner_ty));
|
||||
demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b));
|
||||
capture::check_capture_clause(tcx, b.id, cap_clause);
|
||||
}
|
||||
}
|
||||
let block_ty = structurally_resolved_type(
|
||||
fcx, expr.span, fcx.node_ty(b.id));
|
||||
alt check ty::get(block_ty).struct {
|
||||
ty::ty_fn(fty) {
|
||||
fcx.write_ty(expr.id, ty::mk_fn(tcx, fty));
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::expr_block(b) {
|
||||
// If this is an unchecked block, turn off purity-checking
|
||||
bot = check_block(fcx, b);
|
||||
|
||||
Reference in New Issue
Block a user