Add 'do' expressions

This commit is contained in:
Brian Anderson
2012-06-18 17:42:09 -07:00
parent ee9e5b9d20
commit 1ec5a5c635
18 changed files with 91 additions and 8 deletions

View File

@@ -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(*) |

View File

@@ -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);

View File

@@ -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);

View File

@@ -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(_) {}
}
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);