diff options
| author | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-01-19 19:07:29 -0800 |
|---|---|---|
| committer | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-01-19 22:53:22 -0800 |
| commit | d242edb57b5ffb83bf0536471d0cc174f1a5c28b (patch) | |
| tree | 50cbc8205857eea3f666855821182b6991b0b273 /src/comp | |
| parent | b9d517296aaf8660ef279c83a82d5b0ce0d5b535 (diff) | |
| download | rust-d242edb57b5ffb83bf0536471d0cc174f1a5c28b.tar.gz rust-d242edb57b5ffb83bf0536471d0cc174f1a5c28b.zip | |
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
Diffstat (limited to 'src/comp')
| -rw-r--r-- | src/comp/middle/tstate/collect_locals.rs | 17 | ||||
| -rw-r--r-- | src/comp/middle/tstate/states.rs | 2 |
2 files changed, 10 insertions, 9 deletions
diff --git a/src/comp/middle/tstate/collect_locals.rs b/src/comp/middle/tstate/collect_locals.rs index 200aef3b6db..30a93e4db36 100644 --- a/src/comp/middle/tstate/collect_locals.rs +++ b/src/comp/middle/tstate/collect_locals.rs @@ -136,24 +136,25 @@ fn mk_fn_info(ccx: crate_ctxt, /* add the special i_diverge and i_return constraints (see the type definition for auxiliary::fn_info for an explanation) */ - // use the name of the function for the "return" constraint + // use the function name for the "returns" constraint" + let returns_id = ccx.tcx.sess.next_node_id(); + let returns_constr = ninit(returns_id, name); next = - add_constraint(cx.tcx, respan(f_sp, ninit(id, name)), next, res_map); + add_constraint(cx.tcx, respan(f_sp, returns_constr), next, res_map); // and the name of the function, with a '!' appended to it, for the // "diverges" constraint let diverges_id = ccx.tcx.sess.next_node_id(); - let diverges_name = name + "!"; - next = add_constraint(cx.tcx, respan(f_sp, ninit(diverges_id, - diverges_name)), - next, res_map); + let diverges_constr = ninit(diverges_id, name + "!"); + next = add_constraint(cx.tcx, respan(f_sp, diverges_constr), next, + res_map); let v: @mutable [node_id] = @mutable []; let rslt = {constrs: res_map, num_constraints: next, cf: f_decl.cf, - i_return: ninit(id, name), - i_diverge: ninit(diverges_id, diverges_name), + i_return: returns_constr, + i_diverge: diverges_constr, used_vars: v}; ccx.fm.insert(id, rslt); #debug("%s has %u constraints", name, num_constraints(rslt)); diff --git a/src/comp/middle/tstate/states.rs b/src/comp/middle/tstate/states.rs index 2d4f80b7ce6..0c1fbbf8e58 100644 --- a/src/comp/middle/tstate/states.rs +++ b/src/comp/middle/tstate/states.rs @@ -585,7 +585,7 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool { woo! */ let post = false_postcond(num_constrs); alt fcx.enclosing.cf { - noreturn { kill_poststate_(fcx, ninit(fcx.id, fcx.name), post); } + noreturn { kill_poststate_(fcx, fcx.enclosing.i_return, post); } _ { } } ret set_prestate_ann(fcx.ccx, e.id, pres) | |
