Skip to content

Commit 28459ca

Browse files
committed
Handle lazy binops properly in typestate
The typestate analysis now reflects that the second operand of a logical and or or may not be evaluated.
1 parent a7c4c19 commit 28459ca

File tree

4 files changed

+44
-7
lines changed

4 files changed

+44
-7
lines changed

src/comp/middle/tstate/pre_post_conditions.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -434,10 +434,19 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
434434
find_pre_post_expr(fcx, ternary_to_if(e));
435435
}
436436
case (expr_binary(?bop, ?l, ?r)) {
437-
/* *unless* bop is lazy (e.g. and, or)?
438-
FIXME */
439-
440-
find_pre_post_exprs(fcx, [l, r], e.id);
437+
if (lazy_binop(bop)) {
438+
find_pre_post_expr(fcx, l);
439+
find_pre_post_expr(fcx, r);
440+
auto overall_pre = seq_preconds(fcx,
441+
[expr_pp(fcx.ccx, l), expr_pp(fcx.ccx, r)]);
442+
set_precondition(node_id_to_ts_ann(fcx.ccx, e.id),
443+
overall_pre);
444+
set_postcondition(node_id_to_ts_ann(fcx.ccx, e.id),
445+
expr_postcond(fcx.ccx, l));
446+
}
447+
else {
448+
find_pre_post_exprs(fcx, [l, r], e.id);
449+
}
441450
}
442451
case (expr_send(?l, ?r)) {
443452
find_pre_post_exprs(fcx, [l, r], e.id);

src/comp/middle/tstate/states.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,18 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool {
420420
ret find_pre_post_state_expr(fcx, pres, ternary_to_if(e));
421421
}
422422
case (expr_binary(?bop, ?l, ?r)) {
423-
/* FIXME: what if bop is lazy? */
424-
ret find_pre_post_state_two(fcx, pres, l, r, e.id, oper_pure);
423+
if (lazy_binop(bop)) {
424+
auto changed = find_pre_post_state_expr(fcx, pres, l);
425+
changed |= find_pre_post_state_expr(fcx,
426+
expr_poststate(fcx.ccx, l), r);
427+
ret changed
428+
| set_prestate_ann(fcx.ccx, e.id, pres)
429+
| set_poststate_ann(fcx.ccx, e.id,
430+
expr_poststate(fcx.ccx, l));
431+
}
432+
else {
433+
ret find_pre_post_state_two(fcx, pres, l, r, e.id, oper_pure);
434+
}
425435
}
426436
case (expr_send(?l, ?r)) {
427437
ret find_pre_post_state_two(fcx, pres, l, r, e.id, oper_pure);
@@ -507,7 +517,7 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool {
507517
find_pre_post_state_expr(fcx, pres, val);
508518
auto e_post = expr_poststate(fcx.ccx, val);
509519
auto a_post;
510-
if (vec::len[arm](alts) > 0u) {
520+
if (vec::len(alts) > 0u) {
511521
a_post = false_postcond(num_constrs);
512522
for (arm an_alt in alts) {
513523
changed |= find_pre_post_state_block

src/test/compile-fail/and-init.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// xfail-stage0
2+
// error-pattern: Unsatisfied precondition constraint (for example, init(i
3+
4+
fn main() {
5+
let int i;
6+
7+
log (false && {i = 5; true});
8+
log i;
9+
}

src/test/compile-fail/or-init.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// xfail-stage0
2+
// error-pattern: Unsatisfied precondition constraint (for example, init(i
3+
4+
fn main() {
5+
let int i;
6+
7+
log (false || {i = 5; true});
8+
log i;
9+
}

0 commit comments

Comments
 (0)