From d242edb57b5ffb83bf0536471d0cc174f1a5c28b Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 19 Jan 2012 19:07:29 -0800 Subject: 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 --- src/comp/middle/tstate/collect_locals.rs | 17 +++++++++-------- src/comp/middle/tstate/states.rs | 2 +- src/test/run-pass/issue-933.rs | 2 ++ 3 files changed, 12 insertions(+), 9 deletions(-) create mode 100644 src/test/run-pass/issue-933.rs (limited to 'src') 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) | diff --git a/src/test/run-pass/issue-933.rs b/src/test/run-pass/issue-933.rs new file mode 100644 index 00000000000..53d94d31506 --- /dev/null +++ b/src/test/run-pass/issue-933.rs @@ -0,0 +1,2 @@ +pure fn c() -> bool { check c(); true } +fn main() {} -- cgit 1.4.1-3-g733a5