Remove do { ... } while ... from the language.

This commit is contained in:
Paul Stansifer 2012-05-09 09:17:27 -07:00
parent 5af58e7926
commit 13c924c049
16 changed files with 11 additions and 118 deletions

View File

@ -74,9 +74,6 @@ fn dsl(l: ast::lit_) -> ast::lit {
ast::expr_alt(_, _, _) { false }
ast::expr_while(_, _) { false }
// https://github.com/mozilla/rust/issues/955
ast::expr_do_while(_, _) { false }
// https://github.com/mozilla/rust/issues/929
ast::expr_cast(_, _) { false }
ast::expr_assert(_) { false }

View File

@ -305,7 +305,6 @@ enum expr_ {
expr_cast(@expr, @ty),
expr_if(@expr, blk, option<@expr>),
expr_while(@expr, blk),
expr_do_while(blk, @expr),
/* Conditionless loop (can be exited with break, cont, ret, or fail)
Same semantics as while(true) { body }, but typestate knows that the
(implicit) condition is always true. */

View File

@ -444,9 +444,6 @@ fn fold_field_(field: field, fld: ast_fold) -> field {
expr_while(cond, body) {
expr_while(fld.fold_expr(cond), fld.fold_block(body))
}
expr_do_while(blk, expr) {
expr_do_while(fld.fold_block(blk), fld.fold_expr(expr))
}
expr_loop(body) {
expr_loop(fld.fold_block(body))
}

View File

@ -7,8 +7,8 @@ fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool {
alt e.node {
ast::expr_if(_, _, _) | ast::expr_if_check(_, _, _)
| ast::expr_alt(_, _, _) | ast::expr_block(_)
| ast::expr_do_while(_, _) | ast::expr_while(_, _)
| ast::expr_loop(_) | ast::expr_call(_, _, true) {
| ast::expr_while(_, _) | ast::expr_loop(_)
| ast::expr_call(_, _, true) {
false
}
_ { true }

View File

@ -727,8 +727,6 @@ fn parse_bottom_expr(p: parser) -> pexpr {
ret pexpr(parse_for_expr(p));
} else if eat_keyword(p, "while") {
ret pexpr(parse_while_expr(p));
} else if eat_keyword(p, "do") {
ret pexpr(parse_do_while_expr(p));
} else if eat_keyword(p, "loop") {
ret pexpr(parse_loop_expr(p));
} else if eat_keyword(p, "alt") {
@ -1233,15 +1231,6 @@ fn parse_while_expr(p: parser) -> @expr {
ret mk_expr(p, lo, hi, expr_while(cond, body));
}
fn parse_do_while_expr(p: parser) -> @expr {
let lo = p.last_span.lo;
let body = parse_block_no_value(p);
expect_keyword(p, "while");
let cond = parse_expr(p);
let mut hi = cond.span.hi;
ret mk_expr(p, lo, hi, expr_do_while(body, cond));
}
fn parse_loop_expr(p: parser) -> @expr {
let lo = p.last_span.lo;
let body = parse_block_no_value(p);

View File

@ -975,14 +975,6 @@ fn print_opt(s: ps, expr: option<@ast::expr>) {
space(s.s);
print_block(s, blk);
}
ast::expr_do_while(blk, expr) {
head(s, "do");
space(s.s);
print_block(s, blk);
space(s.s);
word_space(s, "while");
print_expr(s, expr);
}
ast::expr_alt(expr, arms, mode) {
cbox(s, alt_indent_unit);
ibox(s, 4u);

View File

@ -376,7 +376,6 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
}
expr_while(x, b) { v.visit_expr(x, e, v); v.visit_block(b, e, v); }
expr_loop(b) { v.visit_block(b, e, v); }
expr_do_while(b, x) { v.visit_block(b, e, v); v.visit_expr(x, e, v); }
expr_alt(x, arms, _) {
v.visit_expr(x, e, v);
for arms.each {|a| v.visit_arm(a, e, v); }

View File

@ -122,7 +122,7 @@ fn visit_expr(cx: @ctx, ex: @ast::expr, sc: scope, v: vt<scope>) {
check_lval(cx, dest, sc, v);
}
ast::expr_if(c, then, els) { check_if(c, then, els, sc, v); }
ast::expr_while(_, _) | ast::expr_do_while(_, _) {
ast::expr_while(_, _) {
check_loop(*cx, sc) {|| visit::visit_expr(ex, sc, v); }
}
_ { handled = false; }

View File

@ -761,9 +761,9 @@ fn cat_expr(expr: @ast::expr) -> cmt {
ast::expr_vstore(*) | ast::expr_vec(*) | ast::expr_tup(*) |
ast::expr_if_check(*) | ast::expr_if(*) | ast::expr_log(*) |
ast::expr_new(*) | ast::expr_binary(*) | ast::expr_while(*) |
ast::expr_do_while(*) | ast::expr_block(*) | ast::expr_loop(*) |
ast::expr_alt(*) | ast::expr_lit(*) | ast::expr_break |
ast::expr_mac(*) | ast::expr_cont | ast::expr_rec(*) {
ast::expr_block(*) | ast::expr_loop(*) | ast::expr_alt(*) |
ast::expr_lit(*) | ast::expr_break | ast::expr_mac(*) |
ast::expr_cont | ast::expr_rec(*) {
@{id:expr.id, span:expr.span,
cat:cat_rvalue(rv_misc), lp:none,
mutbl:m_imm, ty:expr_ty}

View File

@ -11,7 +11,7 @@ fn check_crate(tcx: ty::ctxt, crate: @crate) {
},
visit_expr: {|e: @expr, cx: ctx, v: visit::vt<ctx>|
alt e.node {
expr_while(e, b) | expr_do_while(b, e) {
expr_while(e, b) {
v.visit_expr(e, cx, v);
v.visit_block(b, {in_loop: true with cx}, v);
}

View File

@ -103,7 +103,7 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
leave_fn(cx);
}
expr_break { add_block_exit(cx, lp); }
expr_while(_, _) | expr_do_while(_, _) | expr_loop(_) {
expr_while(_, _) | expr_loop(_) {
visit_block(lp, cx) {|| visit::visit_expr(ex, cx, v);}
}
expr_alt(input, arms, _) {

View File

@ -1761,23 +1761,6 @@ fn trans_while(cx: block, cond: @ast::expr, body: ast::blk)
ret next_cx;
}
fn trans_do_while(cx: block, body: ast::blk, cond: @ast::expr) ->
block {
let _icx = cx.insn_ctxt("trans_do_while");
let next_cx = sub_block(cx, "next");
let body_cx =
loop_scope_block(cx, cont_self, next_cx,
"do-while loop body", body.span);
let body_end = trans_block(body_cx, body, ignore);
let cond_cx = scope_block(body_cx, "do-while cond");
cleanup_and_Br(body_end, body_cx, cond_cx.llbb);
let cond_res = trans_temp_expr(cond_cx, cond);
let cond_bcx = trans_block_cleanups(cond_res.bcx, cond_cx);
CondBr(cond_bcx, cond_res.val, body_cx.llbb, next_cx.llbb);
Br(cx, body_cx.llbb);
ret next_cx;
}
fn trans_loop(cx:block, body: ast::blk) -> block {
let _icx = cx.insn_ctxt("trans_loop");
let next_cx = sub_block(cx, "next");
@ -3285,10 +3268,6 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
assert dest == ignore;
ret trans_loop(bcx, body);
}
ast::expr_do_while(body, cond) {
assert dest == ignore;
ret trans_do_while(bcx, body, cond);
}
ast::expr_assign(dst, src) {
assert dest == ignore;
let src_r = trans_temp_lval(bcx, src);

View File

@ -212,10 +212,9 @@ fn mark_for_expr(cx: ctx, e: @expr) {
}
}
}
expr_do_while(_, _) | expr_alt(_, _, _) |
expr_block(_) | expr_if(_, _, _) | expr_while(_, _) |
expr_fail(_) | expr_break | expr_cont | expr_unary(_, _) |
expr_lit(_) | expr_assert(_) | expr_check(_, _) |
expr_alt(_, _, _) | expr_block(_) | expr_if(_, _, _) |
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(_) {}
}

View File

@ -425,25 +425,6 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) {
intersect_states(expr_postcond(fcx.ccx, test),
block_postcond(fcx.ccx, body)));
}
expr_do_while(body, test) {
find_pre_post_block(fcx, body);
find_pre_post_expr(fcx, test);
let mut loop_postcond =
seq_postconds(fcx,
[block_postcond(fcx.ccx, body),
expr_postcond(fcx.ccx, test)]);
/* conservative approximation: if the body
could break or cont, the test may never be executed */
if has_nonlocal_exits(body) {
loop_postcond = empty_poststate(num_local_vars);
}
set_pre_and_post(fcx.ccx, e.id,
seq_preconds(fcx,
[block_pp(fcx.ccx, body),
expr_pp(fcx.ccx, test)]),
loop_postcond);
}
expr_loop(body) {
find_pre_post_block(fcx, body);
/* Infinite loop: if control passes it, everything is true. */

View File

@ -540,40 +540,6 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool {
intersect_states(e_post, b_post));
}
}
expr_do_while(body, test) {
let loop_pres = intersect_states(expr_poststate(fcx.ccx, test), pres);
let mut changed = set_prestate_ann(fcx.ccx, e.id, loop_pres);
changed |= find_pre_post_state_block(fcx, loop_pres, body);
/* conservative approximination: if the body of the loop
could break or cont, we revert to the prestate
(TODO: could treat cont differently from break, since
if there's a cont, the test will execute) */
changed |=
find_pre_post_state_expr(fcx, block_poststate(fcx.ccx, body),
test);
let breaks = has_nonlocal_exits(body);
if breaks {
// this should probably be true_poststate and not pres,
// b/c the body could invalidate stuff
// FIXME [Break-unsound]
// This is unsound as it is -- consider
// while (true) {
// x <- y;
// break;
// }
// The poststate wouldn't take into account that
// y gets deinitialized
changed |= set_poststate_ann(fcx.ccx, e.id, pres);
} else {
changed |=
set_poststate_ann(fcx.ccx, e.id,
expr_poststate(fcx.ccx, test));
}
ret changed;
}
expr_loop(body) {
let loop_pres =
intersect_states(block_poststate(fcx.ccx, body), pres);

View File

@ -3444,11 +3444,6 @@ fn check_expr_fn(fcx: @fn_ctxt,
check_block_no_value(fcx, body);
fcx.write_ty(id, ty::mk_nil(tcx));
}
ast::expr_do_while(body, cond) {
bot = check_expr_with(fcx, cond, ty::mk_bool(tcx)) |
check_block_no_value(fcx, body);
fcx.write_ty(id, fcx.node_ty(body.node.id));
}
ast::expr_loop(body) {
check_block_no_value(fcx, body);
fcx.write_ty(id, ty::mk_nil(tcx));