about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-05-30 13:35:12 -0700
committerBrian Anderson <banderson@mozilla.com>2012-05-30 17:48:05 -0700
commit02dde781eb71b9acc42447edcba12a3c380c3269 (patch)
treec3327ebbfe5993696ab0ac50e8b1fbfa17a834ac /src/rustc
parent6b4cf00552ba2632ff35dfa90f8dab88137feb31 (diff)
downloadrust-02dde781eb71b9acc42447edcba12a3c380c3269.tar.gz
rust-02dde781eb71b9acc42447edcba12a3c380c3269.zip
rustc: Don't typestate fns that don't have constrained function calls
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/middle/tstate/ck.rs20
-rw-r--r--src/rustc/middle/tstate/pre_post_conditions.rs48
2 files changed, 52 insertions, 16 deletions
diff --git a/src/rustc/middle/tstate/ck.rs b/src/rustc/middle/tstate/ck.rs
index 1cc3a7df9dc..2d998de2b00 100644
--- a/src/rustc/middle/tstate/ck.rs
+++ b/src/rustc/middle/tstate/ck.rs
@@ -115,14 +115,18 @@ fn check_fn_states(fcx: fn_ctxt,
 fn fn_states(fk: visit::fn_kind, f_decl: ast::fn_decl, f_body: ast::blk,
              sp: span, id: node_id,
              ccx: crate_ctxt, v: visit::vt<crate_ctxt>) {
-    visit::visit_fn(fk, f_decl, f_body, sp, id, ccx, v);
-    /* Look up the var-to-bit-num map for this function */
-
-    assert (ccx.fm.contains_key(id));
-    let f_info = ccx.fm.get(id);
-    let name = visit::name_of_fn(fk);
-    let fcx = {enclosing: f_info, id: id, name: name, ccx: ccx};
-    check_fn_states(fcx, fk, f_decl, f_body, sp, id)
+
+    // We may not care about typestate for this function if it contains
+    // no constrained calls
+    if ccx.fm.contains_key(id) {
+        visit::visit_fn(fk, f_decl, f_body, sp, id, ccx, v);
+        /* Look up the var-to-bit-num map for this function */
+
+        let f_info = ccx.fm.get(id);
+        let name = visit::name_of_fn(fk);
+        let fcx = {enclosing: f_info, id: id, name: name, ccx: ccx};
+        check_fn_states(fcx, fk, f_decl, f_body, sp, id)
+    }
 }
 
 fn check_crate(cx: ty::ctxt, crate: @crate) {
diff --git a/src/rustc/middle/tstate/pre_post_conditions.rs b/src/rustc/middle/tstate/pre_post_conditions.rs
index fd8e9ddaf22..c453d610603 100644
--- a/src/rustc/middle/tstate/pre_post_conditions.rs
+++ b/src/rustc/middle/tstate/pre_post_conditions.rs
@@ -618,17 +618,49 @@ fn find_pre_post_fn(fcx: fn_ctxt, body: blk) {
     }
 }
 
+fn contains_constrained_calls(tcx: ty::ctxt, body: blk) -> bool {
+    type cx = @{
+        tcx: ty::ctxt,
+        mut has: bool
+    };
+    let cx = @{
+        tcx: tcx,
+        mut has: false
+    };
+    let vtor = visit::default_visitor::<cx>();
+    let vtor = @{visit_expr: visit_expr with *vtor};
+    visit::visit_block(body, cx, visit::mk_vt(vtor));
+    ret cx.has;
+
+    fn visit_expr(e: @expr, &&cx: cx, v: visit::vt<cx>) {
+        import syntax::print::pprust;
+        #debug("visiting %?", pprust::expr_to_str(e));
+
+        visit::visit_expr(e, cx, v);
+
+        if constraints_expr(cx.tcx, e).is_not_empty() {
+            #debug("has constraints");
+            cx.has = true;
+        } else {
+            #debug("has not constraints");
+        }
+    }
+}
+
 fn fn_pre_post(fk: visit::fn_kind, decl: fn_decl, body: blk, sp: span,
                id: node_id,
                ccx: crate_ctxt, v: visit::vt<crate_ctxt>) {
-    visit::visit_fn(fk, decl, body, sp, id, ccx, v);
-    assert (ccx.fm.contains_key(id));
-    let fcx =
-        {enclosing: ccx.fm.get(id),
-         id: id,
-         name: visit::name_of_fn(fk),
-         ccx: ccx};
-    find_pre_post_fn(fcx, body);
+
+    if contains_constrained_calls(ccx.tcx, body) {
+        visit::visit_fn(fk, decl, body, sp, id, ccx, v);
+        assert (ccx.fm.contains_key(id));
+        let fcx =
+            {enclosing: ccx.fm.get(id),
+             id: id,
+             name: visit::name_of_fn(fk),
+             ccx: ccx};
+        find_pre_post_fn(fcx, body);
+    }
 }
 
 //