Skip to content

Commit 664b82a

Browse files
committed
Merge pull request #2375 from paulstansifer/remove_do_loops
Remove do loops
2 parents fa6c18e + f943667 commit 664b82a

33 files changed

+67
-205
lines changed

doc/rust.md

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1991,28 +1991,19 @@ way.
19911991

19921992
*TODO*.
19931993

1994-
### While expressions
1994+
### While loops
19951995

19961996
~~~~~~~~{.ebnf .gram}
19971997
while_expr : "while" expr '{' block '}'
19981998
| "do" '{' block '}' "while" expr ;
19991999
~~~~~~~~
20002000

2001-
A `while` expression is a loop construct. A `while` loop may be either a
2002-
simple `while` or a `do`-`while` loop.
2001+
A `while` loop begins by evaluating the boolean loop conditional expression.
2002+
If the loop conditional expression evaluates to `true`, the loop body block
2003+
executes and control returns to the loop conditional expression. If the loop
2004+
conditional expression evaluates to `false`, the `while` expression completes.
20032005

2004-
In the case of a simple `while`, the loop begins by evaluating the boolean
2005-
loop conditional expression. If the loop conditional expression evaluates to
2006-
`true`, the loop body block executes and control returns to the loop
2007-
conditional expression. If the loop conditional expression evaluates to
2008-
`false`, the `while` expression completes.
2009-
2010-
In the case of a `do`-`while`, the loop begins with an execution of the loop
2011-
body. After the loop body executes, it evaluates the loop conditional
2012-
expression. If it evaluates to `true`, control returns to the beginning of the
2013-
loop body. If it evaluates to `false`, control exits the loop.
2014-
2015-
An example of a simple `while` expression:
2006+
An example:
20162007

20172008
~~~~
20182009
# let mut i = 0;
@@ -2024,18 +2015,6 @@ while i < 10 {
20242015
}
20252016
~~~~
20262017

2027-
An example of a `do`-`while` expression:
2028-
2029-
~~~~
2030-
# let mut i = 0;
2031-
# let println = io::println;
2032-
2033-
do {
2034-
println("hello\n");
2035-
i = i + 1;
2036-
} while i < 10;
2037-
~~~~
2038-
20392018
### Infinite loops
20402019

20412020
A `loop` expression denotes an infinite loop:

doc/tutorial.md

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,15 @@ a specific value, are not allowed.
667667
keyword `break` can be used to abort the loop, and `cont` can be used
668668
to abort the current iteration and continue with the next.
669669

670+
~~~~
671+
let mut cake_amount = 8;
672+
while cake_amount > 0 {
673+
cake_amount -= 1;
674+
}
675+
~~~~
676+
677+
`loop` is the preferred way of writing `while true`:
678+
670679
~~~~
671680
let mut x = 5;
672681
while true {
@@ -679,17 +688,6 @@ while true {
679688
This code prints out a weird sequence of numbers and stops as soon as
680689
it finds one that can be divided by five.
681690

682-
There's also `while`'s ugly cousin, `do`/`while`, which does not check
683-
its condition on the first iteration, using traditional syntax:
684-
685-
~~~~
686-
# fn eat_cake() {}
687-
# fn any_cake_left() -> bool { false }
688-
do {
689-
eat_cake();
690-
} while any_cake_left();
691-
~~~~
692-
693691
For more involved iteration, such as going over the elements of a
694692
collection, Rust uses higher-order functions. We'll come back to those
695693
in a moment.
@@ -2496,12 +2494,12 @@ Here is the function which implements the child task:
24962494
fn stringifier(from_parent: comm::port<uint>,
24972495
to_parent: comm::chan<str>) {
24982496
let mut value: uint;
2499-
do {
2497+
loop {
25002498
value = comm::recv(from_parent);
25012499
comm::send(to_parent, uint::to_str(value, 10u));
2502-
} while value != 0u;
2500+
if value == 0u { break; }
2501+
}
25032502
}
2504-
25052503
~~~~
25062504

25072505
You can see that the function takes two parameters. The first is a

src/fuzzer/fuzzer.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,6 @@ pure fn safe_to_use_expr(e: ast::expr, tm: test_mode) -> bool {
7474
ast::expr_alt(_, _, _) { false }
7575
ast::expr_while(_, _) { false }
7676

77-
// https://github.com/mozilla/rust/issues/955
78-
ast::expr_do_while(_, _) { false }
79-
8077
// https://github.com/mozilla/rust/issues/929
8178
ast::expr_cast(_, _) { false }
8279
ast::expr_assert(_) { false }

src/libcore/path.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ fn normalize(p: path) -> path {
251251
let mut t = [];
252252
let mut i = vec::len(s);
253253
let mut skip = 0;
254-
do {
254+
while i != 0u {
255255
i -= 1u;
256256
if s[i] == ".." {
257257
skip += 1;
@@ -262,7 +262,7 @@ fn normalize(p: path) -> path {
262262
skip -= 1;
263263
}
264264
}
265-
} while i != 0u;
265+
}
266266
let mut t = vec::reversed(t);
267267
while skip > 0 {
268268
t += [".."];

src/librustsyntax/ast.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,6 @@ enum expr_ {
305305
expr_cast(@expr, @ty),
306306
expr_if(@expr, blk, option<@expr>),
307307
expr_while(@expr, blk),
308-
expr_do_while(blk, @expr),
309308
/* Conditionless loop (can be exited with break, cont, ret, or fail)
310309
Same semantics as while(true) { body }, but typestate knows that the
311310
(implicit) condition is always true. */

src/librustsyntax/fold.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,6 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
444444
expr_while(cond, body) {
445445
expr_while(fld.fold_expr(cond), fld.fold_block(body))
446446
}
447-
expr_do_while(blk, expr) {
448-
expr_do_while(fld.fold_block(blk), fld.fold_expr(expr))
449-
}
450447
expr_loop(body) {
451448
expr_loop(fld.fold_block(body))
452449
}

src/librustsyntax/parse/classify.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool {
77
alt e.node {
88
ast::expr_if(_, _, _) | ast::expr_if_check(_, _, _)
99
| ast::expr_alt(_, _, _) | ast::expr_block(_)
10-
| ast::expr_do_while(_, _) | ast::expr_while(_, _)
11-
| ast::expr_loop(_) | ast::expr_call(_, _, true) {
10+
| ast::expr_while(_, _) | ast::expr_loop(_)
11+
| ast::expr_call(_, _, true) {
1212
false
1313
}
1414
_ { true }

src/librustsyntax/parse/parser.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -727,8 +727,6 @@ fn parse_bottom_expr(p: parser) -> pexpr {
727727
ret pexpr(parse_for_expr(p));
728728
} else if eat_keyword(p, "while") {
729729
ret pexpr(parse_while_expr(p));
730-
} else if eat_keyword(p, "do") {
731-
ret pexpr(parse_do_while_expr(p));
732730
} else if eat_keyword(p, "loop") {
733731
ret pexpr(parse_loop_expr(p));
734732
} else if eat_keyword(p, "alt") {
@@ -1233,15 +1231,6 @@ fn parse_while_expr(p: parser) -> @expr {
12331231
ret mk_expr(p, lo, hi, expr_while(cond, body));
12341232
}
12351233

1236-
fn parse_do_while_expr(p: parser) -> @expr {
1237-
let lo = p.last_span.lo;
1238-
let body = parse_block_no_value(p);
1239-
expect_keyword(p, "while");
1240-
let cond = parse_expr(p);
1241-
let mut hi = cond.span.hi;
1242-
ret mk_expr(p, lo, hi, expr_do_while(body, cond));
1243-
}
1244-
12451234
fn parse_loop_expr(p: parser) -> @expr {
12461235
let lo = p.last_span.lo;
12471236
let body = parse_block_no_value(p);

src/librustsyntax/print/pprust.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -975,14 +975,6 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
975975
space(s.s);
976976
print_block(s, blk);
977977
}
978-
ast::expr_do_while(blk, expr) {
979-
head(s, "do");
980-
space(s.s);
981-
print_block(s, blk);
982-
space(s.s);
983-
word_space(s, "while");
984-
print_expr(s, expr);
985-
}
986978
ast::expr_alt(expr, arms, mode) {
987979
cbox(s, alt_indent_unit);
988980
ibox(s, 4u);

src/librustsyntax/visit.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,6 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
376376
}
377377
expr_while(x, b) { v.visit_expr(x, e, v); v.visit_block(b, e, v); }
378378
expr_loop(b) { v.visit_block(b, e, v); }
379-
expr_do_while(b, x) { v.visit_block(b, e, v); v.visit_expr(x, e, v); }
380379
expr_alt(x, arms, _) {
381380
v.visit_expr(x, e, v);
382381
for arms.each {|a| v.visit_arm(a, e, v); }

src/rustc/metadata/tydecode.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,11 @@ fn parse_constrs(st: @pstate, conv: conv_did) -> [@ty::constr] {
6969
let mut rslt: [@ty::constr] = [];
7070
alt peek(st) {
7171
':' {
72-
do {
72+
loop {
7373
next(st);
7474
rslt += [parse_constr(st, conv, parse_constr_arg)];
75-
} while peek(st) == ';'
75+
if peek(st) != ';' { break; }
76+
}
7677
}
7778
_ { }
7879
}
@@ -84,10 +85,11 @@ fn parse_ty_constrs(st: @pstate, conv: conv_did) -> [@ty::type_constr] {
8485
let mut rslt: [@ty::type_constr] = [];
8586
alt peek(st) {
8687
':' {
87-
do {
88+
loop {
8889
next(st);
8990
rslt += [parse_constr(st, conv, parse_ty_constr_arg)];
90-
} while peek(st) == ';'
91+
if peek(st) != ';' { break; }
92+
}
9193
}
9294
_ { }
9395
}
@@ -154,12 +156,13 @@ fn parse_constr<T: copy>(st: @pstate, conv: conv_did,
154156
assert (ignore == '(');
155157
let def = parse_def(st, conv);
156158
let mut an_arg: constr_arg_general_<T>;
157-
do {
159+
loop {
158160
an_arg = pser(st);
159161
// FIXME use a real span
160162
args += [@respan(sp, an_arg)];
161163
ignore = next(st);
162-
} while ignore == ';'
164+
if ignore != ';' { break; }
165+
}
163166
assert (ignore == ')');
164167
ret @respan(sp, {path: pth, args: args, id: def});
165168
}

src/rustc/middle/alias.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ fn visit_expr(cx: @ctx, ex: @ast::expr, sc: scope, v: vt<scope>) {
122122
check_lval(cx, dest, sc, v);
123123
}
124124
ast::expr_if(c, then, els) { check_if(c, then, els, sc, v); }
125-
ast::expr_while(_, _) | ast::expr_do_while(_, _) {
125+
ast::expr_while(_, _) {
126126
check_loop(*cx, sc) {|| visit::visit_expr(ex, sc, v); }
127127
}
128128
_ { handled = false; }

src/rustc/middle/borrowck.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -761,9 +761,9 @@ impl categorize_methods for borrowck_ctxt {
761761
ast::expr_vstore(*) | ast::expr_vec(*) | ast::expr_tup(*) |
762762
ast::expr_if_check(*) | ast::expr_if(*) | ast::expr_log(*) |
763763
ast::expr_new(*) | ast::expr_binary(*) | ast::expr_while(*) |
764-
ast::expr_do_while(*) | ast::expr_block(*) | ast::expr_loop(*) |
765-
ast::expr_alt(*) | ast::expr_lit(*) | ast::expr_break |
766-
ast::expr_mac(*) | ast::expr_cont | ast::expr_rec(*) {
764+
ast::expr_block(*) | ast::expr_loop(*) | ast::expr_alt(*) |
765+
ast::expr_lit(*) | ast::expr_break | ast::expr_mac(*) |
766+
ast::expr_cont | ast::expr_rec(*) {
767767
@{id:expr.id, span:expr.span,
768768
cat:cat_rvalue(rv_misc), lp:none,
769769
mutbl:m_imm, ty:expr_ty}

src/rustc/middle/check_loop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fn check_crate(tcx: ty::ctxt, crate: @crate) {
1111
},
1212
visit_expr: {|e: @expr, cx: ctx, v: visit::vt<ctx>|
1313
alt e.node {
14-
expr_while(e, b) | expr_do_while(b, e) {
14+
expr_while(e, b) {
1515
v.visit_expr(e, cx, v);
1616
v.visit_block(b, {in_loop: true with cx}, v);
1717
}

src/rustc/middle/last_use.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
103103
leave_fn(cx);
104104
}
105105
expr_break { add_block_exit(cx, lp); }
106-
expr_while(_, _) | expr_do_while(_, _) | expr_loop(_) {
106+
expr_while(_, _) | expr_loop(_) {
107107
visit_block(lp, cx) {|| visit::visit_expr(ex, cx, v);}
108108
}
109109
expr_alt(input, arms, _) {

src/rustc/middle/trans/base.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1761,23 +1761,6 @@ fn trans_while(cx: block, cond: @ast::expr, body: ast::blk)
17611761
ret next_cx;
17621762
}
17631763

1764-
fn trans_do_while(cx: block, body: ast::blk, cond: @ast::expr) ->
1765-
block {
1766-
let _icx = cx.insn_ctxt("trans_do_while");
1767-
let next_cx = sub_block(cx, "next");
1768-
let body_cx =
1769-
loop_scope_block(cx, cont_self, next_cx,
1770-
"do-while loop body", body.span);
1771-
let body_end = trans_block(body_cx, body, ignore);
1772-
let cond_cx = scope_block(body_cx, "do-while cond");
1773-
cleanup_and_Br(body_end, body_cx, cond_cx.llbb);
1774-
let cond_res = trans_temp_expr(cond_cx, cond);
1775-
let cond_bcx = trans_block_cleanups(cond_res.bcx, cond_cx);
1776-
CondBr(cond_bcx, cond_res.val, body_cx.llbb, next_cx.llbb);
1777-
Br(cx, body_cx.llbb);
1778-
ret next_cx;
1779-
}
1780-
17811764
fn trans_loop(cx:block, body: ast::blk) -> block {
17821765
let _icx = cx.insn_ctxt("trans_loop");
17831766
let next_cx = sub_block(cx, "next");
@@ -3285,10 +3268,6 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
32853268
assert dest == ignore;
32863269
ret trans_loop(bcx, body);
32873270
}
3288-
ast::expr_do_while(body, cond) {
3289-
assert dest == ignore;
3290-
ret trans_do_while(bcx, body, cond);
3291-
}
32923271
ast::expr_assign(dst, src) {
32933272
assert dest == ignore;
32943273
let src_r = trans_temp_lval(bcx, src);

src/rustc/middle/trans/type_use.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,9 @@ fn mark_for_expr(cx: ctx, e: @expr) {
212212
}
213213
}
214214
}
215-
expr_do_while(_, _) | expr_alt(_, _, _) |
216-
expr_block(_) | expr_if(_, _, _) | expr_while(_, _) |
217-
expr_fail(_) | expr_break | expr_cont | expr_unary(_, _) |
218-
expr_lit(_) | expr_assert(_) | expr_check(_, _) |
215+
expr_alt(_, _, _) | expr_block(_) | expr_if(_, _, _) |
216+
expr_while(_, _) | expr_fail(_) | expr_break | expr_cont |
217+
expr_unary(_, _) | expr_lit(_) | expr_assert(_) | expr_check(_, _) |
219218
expr_if_check(_, _, _) | expr_mac(_) | expr_addr_of(_, _) |
220219
expr_ret(_) | expr_loop(_) | expr_bind(_, _) | expr_loop_body(_) {}
221220
}

src/rustc/middle/tstate/pre_post_conditions.rs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -425,25 +425,6 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) {
425425
intersect_states(expr_postcond(fcx.ccx, test),
426426
block_postcond(fcx.ccx, body)));
427427
}
428-
expr_do_while(body, test) {
429-
find_pre_post_block(fcx, body);
430-
find_pre_post_expr(fcx, test);
431-
let mut loop_postcond =
432-
seq_postconds(fcx,
433-
[block_postcond(fcx.ccx, body),
434-
expr_postcond(fcx.ccx, test)]);
435-
/* conservative approximation: if the body
436-
could break or cont, the test may never be executed */
437-
438-
if has_nonlocal_exits(body) {
439-
loop_postcond = empty_poststate(num_local_vars);
440-
}
441-
set_pre_and_post(fcx.ccx, e.id,
442-
seq_preconds(fcx,
443-
[block_pp(fcx.ccx, body),
444-
expr_pp(fcx.ccx, test)]),
445-
loop_postcond);
446-
}
447428
expr_loop(body) {
448429
find_pre_post_block(fcx, body);
449430
/* Infinite loop: if control passes it, everything is true. */

0 commit comments

Comments
 (0)