Skip to content

Commit d242edb

Browse files
committed
Handle predicates that recurse in a check() expression
typestate was using the enclosing function ID for the "this function returns" constraint, which meant confusion and panic in the case where a predicate p includes "check p()". Fixed it to use a fresh ID. Closes #933
1 parent b9d5172 commit d242edb

File tree

3 files changed

+12
-9
lines changed

3 files changed

+12
-9
lines changed

src/comp/middle/tstate/collect_locals.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,24 +136,25 @@ fn mk_fn_info(ccx: crate_ctxt,
136136
/* add the special i_diverge and i_return constraints
137137
(see the type definition for auxiliary::fn_info for an explanation) */
138138

139-
// use the name of the function for the "return" constraint
139+
// use the function name for the "returns" constraint"
140+
let returns_id = ccx.tcx.sess.next_node_id();
141+
let returns_constr = ninit(returns_id, name);
140142
next =
141-
add_constraint(cx.tcx, respan(f_sp, ninit(id, name)), next, res_map);
143+
add_constraint(cx.tcx, respan(f_sp, returns_constr), next, res_map);
142144
// and the name of the function, with a '!' appended to it, for the
143145
// "diverges" constraint
144146
let diverges_id = ccx.tcx.sess.next_node_id();
145-
let diverges_name = name + "!";
146-
next = add_constraint(cx.tcx, respan(f_sp, ninit(diverges_id,
147-
diverges_name)),
148-
next, res_map);
147+
let diverges_constr = ninit(diverges_id, name + "!");
148+
next = add_constraint(cx.tcx, respan(f_sp, diverges_constr), next,
149+
res_map);
149150

150151
let v: @mutable [node_id] = @mutable [];
151152
let rslt =
152153
{constrs: res_map,
153154
num_constraints: next,
154155
cf: f_decl.cf,
155-
i_return: ninit(id, name),
156-
i_diverge: ninit(diverges_id, diverges_name),
156+
i_return: returns_constr,
157+
i_diverge: diverges_constr,
157158
used_vars: v};
158159
ccx.fm.insert(id, rslt);
159160
#debug("%s has %u constraints", name, num_constraints(rslt));

src/comp/middle/tstate/states.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool {
585585
woo! */
586586
let post = false_postcond(num_constrs);
587587
alt fcx.enclosing.cf {
588-
noreturn { kill_poststate_(fcx, ninit(fcx.id, fcx.name), post); }
588+
noreturn { kill_poststate_(fcx, fcx.enclosing.i_return, post); }
589589
_ { }
590590
}
591591
ret set_prestate_ann(fcx.ccx, e.id, pres) |

src/test/run-pass/issue-933.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pure fn c() -> bool { check c(); true }
2+
fn main() {}

0 commit comments

Comments
 (0)