about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-01-19 19:07:29 -0800
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-01-19 22:53:22 -0800
commitd242edb57b5ffb83bf0536471d0cc174f1a5c28b (patch)
tree50cbc8205857eea3f666855821182b6991b0b273 /src/comp
parentb9d517296aaf8660ef279c83a82d5b0ce0d5b535 (diff)
downloadrust-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.rs17
-rw-r--r--src/comp/middle/tstate/states.rs2
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) |