about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2011-05-18 15:34:21 -0700
committerGraydon Hoare <graydon@mozilla.com>2011-05-19 11:40:16 -0700
commitf909dd114d675a1d1bd8e0676991f052be85237f (patch)
treeb42e46c6a953b3bdb93f9d35ca158721b57959e8 /src/comp
parentb624b43e4774d1dd421979946a09a36162a0aff1 (diff)
downloadrust-f909dd114d675a1d1bd8e0676991f052be85237f.tar.gz
rust-f909dd114d675a1d1bd8e0676991f052be85237f.zip
Remove dead file (typestate_check is now a bunch of modules under middle/tstate)
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/typestate_check.rs2377
1 files changed, 0 insertions, 2377 deletions
diff --git a/src/comp/middle/typestate_check.rs b/src/comp/middle/typestate_check.rs
deleted file mode 100644
index a183ed3d122..00000000000
--- a/src/comp/middle/typestate_check.rs
+++ /dev/null
@@ -1,2377 +0,0 @@
-import front::ast;
-import front::ast::ann;
-import front::ast::method;
-import front::ast::ty;
-import front::ast::mutability;
-import front::ast::item;
-import front::ast::block;
-import front::ast::block_;
-import front::ast::obj_field;
-import front::ast::decl;
-import front::ast::arm;
-import front::ast::stmt;
-import front::ast::stmt_;
-import front::ast::stmt_decl;
-import front::ast::stmt_expr;
-import front::ast::stmt_crate_directive;
-import front::ast::decl_local;
-import front::ast::decl_item;
-import front::ast::ident;
-import front::ast::def_id;
-import front::ast::ann;
-import front::ast::field;
-import front::ast::expr;
-import front::ast::expr_call;
-import front::ast::expr_vec;
-import front::ast::expr_tup;
-import front::ast::expr_path;
-import front::ast::expr_field;
-import front::ast::expr_index;
-import front::ast::expr_log;
-import front::ast::expr_block;
-import front::ast::expr_rec;
-import front::ast::expr_if;
-import front::ast::expr_binary;
-import front::ast::expr_unary;
-import front::ast::expr_assign;
-import front::ast::expr_assign_op;
-import front::ast::expr_while;
-import front::ast::expr_do_while;
-import front::ast::expr_alt;
-import front::ast::expr_lit;
-import front::ast::expr_ret;
-import front::ast::expr_self_method;
-import front::ast::expr_bind;
-import front::ast::expr_spawn;
-import front::ast::expr_ext;
-import front::ast::expr_fail;
-import front::ast::expr_break;
-import front::ast::expr_cont;
-import front::ast::expr_send;
-import front::ast::expr_recv;
-import front::ast::expr_put;
-import front::ast::expr_port;
-import front::ast::expr_chan;
-import front::ast::expr_be;
-import front::ast::expr_check;
-import front::ast::expr_assert;
-import front::ast::expr_cast;
-import front::ast::expr_for;
-import front::ast::expr_for_each;
-import front::ast::path;
-import front::ast::elt;
-import front::ast::crate_directive;
-import front::ast::fn_decl;
-import front::ast::_obj;
-import front::ast::native_mod;
-import front::ast::variant;
-import front::ast::ty_param;
-import front::ast::ty;
-import front::ast::proto;
-import front::ast::pat;
-import front::ast::binop;
-import front::ast::unop;
-import front::ast::def;
-import front::ast::lit;
-import front::ast::init_op;
-import front::ast::initializer;
-import front::ast::local;
-import front::ast::_fn;
-import front::ast::_obj;
-import front::ast::_mod;
-import front::ast::crate;
-import front::ast::item_fn;
-import front::ast::item_obj;
-import front::ast::def_local;
-
-import middle::fold;
-import middle::fold::respan;
-import driver::session;
-import util::common;
-import util::common::span;
-import util::common::spanned;
-import util::common::new_str_hash;
-import util::common::new_def_hash;
-import util::common::uistr;
-import util::common::elt_exprs;
-import util::common::field_exprs;
-import util::common::log_expr;
-import util::common::log_expr_err;
-import util::common::log_stmt;
-import util::common::log_block;
-import util::common::log_stmt_err;
-import util::common::log_fn_err;
-import util::common::log_fn;
-import util::common::log_block_err;
-import util::common::has_nonlocal_exits;
-import util::common::decl_lhs;
-import util::typestate_ann;
-import util::typestate_ann::ts_ann;
-import util::typestate_ann::empty_pre_post;
-import util::typestate_ann::empty_poststate;
-import util::typestate_ann::true_precond;
-import util::typestate_ann::true_postcond;
-import util::typestate_ann::false_postcond;
-import util::typestate_ann::postcond;
-import util::typestate_ann::precond;
-import util::typestate_ann::poststate;
-import util::typestate_ann::prestate;
-import util::typestate_ann::pre_and_post;
-import util::typestate_ann::get_pre;
-import util::typestate_ann::get_post;
-import util::typestate_ann::ann_precond;
-import util::typestate_ann::ann_prestate;
-import util::typestate_ann::set_precondition;
-import util::typestate_ann::set_postcondition;
-import util::typestate_ann::set_prestate;
-import util::typestate_ann::set_poststate;
-import util::typestate_ann::set_in_postcond;
-import util::typestate_ann::set_in_poststate;
-import util::typestate_ann::implies;
-import util::typestate_ann::pre_and_post_state;
-import util::typestate_ann::empty_states;
-import util::typestate_ann::empty_prestate;
-import util::typestate_ann::empty_ann;
-import util::typestate_ann::extend_prestate;
-import util::typestate_ann::extend_poststate;
-import util::typestate_ann::relax_prestate;
-import util::typestate_ann::intersect;
-import util::typestate_ann::pp_clone;
-import util::typestate_ann::clone;
-
-import middle::ty;
-import middle::ty::ann_to_type;
-import middle::ty::arg;
-import middle::ty::expr_ann;
-import middle::ty::ty_to_str;
-
-import pretty::pprust::print_block;
-import pretty::pprust::print_expr;
-import pretty::pprust::print_decl;
-import pretty::pp::mkstate;
-import std::io::stdout;
-import std::io::str_writer;
-import std::io::string_writer;
-import std::vec::map;
-import std::vec;
-import std::vec::len;
-import std::vec::pop;
-import std::vec::push;
-import std::vec::slice;
-import std::vec::unzip;
-import std::vec::plus_option;
-import std::vec::cat_options;
-import std::option;
-import std::option::t;
-import std::option::some;
-import std::option::none;
-import std::option::from_maybe;
-import std::option::maybe;
-import std::option::is_none;
-import std::option::get;
-import std::map::hashmap;
-import std::list;
-import std::list::list;
-import std::list::cons;
-import std::list::nil;
-import std::list::foldl;
-import std::list::find;
-import std::uint;
-import std::bitv;
-import std::util::fst;
-import std::util::snd;
-
-import util::typestate_ann;
-import util::typestate_ann::difference;
-import util::typestate_ann::union;
-import util::typestate_ann::pps_len;
-import util::typestate_ann::require_and_preserve;
-
-import resolve::def_map;
-
-/**** debugging junk  ****/
-
-fn bitv_to_str(fn_info enclosing, bitv::t v) -> str {
-  auto s = "";
-
-  for each (@tup(def_id, tup(uint, ident)) p in enclosing.items()) {
-    if (bitv::get(v, p._1._0)) {
-      s += " " + p._1._1 + " ";
-    }
-  }
-  ret s;
-}
-
-fn log_bitv(fn_info enclosing, bitv::t v) {
-    log(bitv_to_str(enclosing, v));
-}
-
-fn log_bitv_err(fn_info enclosing, bitv::t v) {
-    log_err(bitv_to_str(enclosing, v));
-}
-
-fn tos (vec[uint] v) -> str {
-  auto res = "";
-  for (uint i in v) {
-    if (i == 0u) {
-      res += "0";
-    }
-    else {
-      res += "1";
-    }
-  }
-  ret res;
-}
-
-fn log_cond(vec[uint] v) -> () {
-    log(tos(v));
-}
-fn log_cond_err(vec[uint] v) -> () {
-    log_err(tos(v));
-}
-
-fn log_pp(&pre_and_post pp) -> () {
-  auto p1 = bitv::to_vec(pp.precondition);
-  auto p2 = bitv::to_vec(pp.postcondition);
-  log("pre:");
-  log_cond(p1);
-  log("post:");
-  log_cond(p2);
-}
-
-fn log_pp_err(&pre_and_post pp) -> () {
-  auto p1 = bitv::to_vec(pp.precondition);
-  auto p2 = bitv::to_vec(pp.postcondition);
-  log_err("pre:");
-  log_cond_err(p1);
-  log_err("post:");
-  log_cond_err(p2);
-}
-
-fn log_states(&pre_and_post_state pp) -> () {
-  auto p1 = bitv::to_vec(pp.prestate);
-  auto p2 = bitv::to_vec(pp.poststate);
-  log("prestate:");
-  log_cond(p1);
-  log("poststate:");
-  log_cond(p2);
-}
-
-fn log_states_err(&pre_and_post_state pp) -> () {
-  auto p1 = bitv::to_vec(pp.prestate);
-  auto p2 = bitv::to_vec(pp.poststate);
-  log_err("prestate:");
-  log_cond_err(p1);
-  log_err("poststate:");
-  log_cond_err(p2);
-}
-
-fn print_ident(&ident i) -> () {
-  log(" " + i + " ");
-}
-
-fn print_idents(vec[ident] idents) -> () {
-  if(len[ident](idents) == 0u) {
-    ret;
-  }
-  else {
-    log("an ident: " + pop[ident](idents));
-    print_idents(idents);
-  }
-}
-/**********************************************************************/
-/* mapping from variable name (def_id is assumed to be for a local
-   variable in a given function) to bit number 
-   (also remembers the ident for error-logging purposes) */
-type var_info     = tup(uint, ident);
-type fn_info      = std::map::hashmap[def_id, var_info];
-/* mapping from function name to fn_info map */
-type fn_info_map = std::map::hashmap[def_id, fn_info];
- 
-fn bit_num(def_id v, fn_info m) -> uint {
-  assert (m.contains_key(v));
-  ret m.get(v)._0;
-}
-fn get_fn_info(fn_info_map fm, def_id did) -> fn_info {
-    assert (fm.contains_key(did));
-    ret fm.get(did);
-}
-
-fn var_is_local(def_id v, fn_info m) -> bool {
-  ret (m.contains_key(v));
-}
-
-fn num_locals(fn_info m) -> uint {
-  ret m.size();
-}
-
-fn collect_local(&@vec[tup(ident, def_id)] vars, &span sp, &@ast::local loc)
-    -> @decl {
-    log("collect_local: pushing " + loc.ident);
-    vec::push[tup(ident, def_id)](*vars, tup(loc.ident, loc.id));
-    ret @respan(sp, decl_local(loc));
-}
-
-fn find_locals(_fn f) -> @vec[tup(ident,def_id)] {
-  auto res = @vec::alloc[tup(ident,def_id)](0u);
-
-  auto fld = fold::new_identity_fold[@vec[tup(ident, def_id)]]();
-  fld = @rec(fold_decl_local = bind collect_local(_,_,_) with *fld);
-  auto ignore = fold::fold_fn[@vec[tup(ident, def_id)]](res, fld, f);
-
-  ret res;
-}
-
-fn add_var(def_id v, ident nm, uint next, fn_info tbl) -> uint {
-    log(nm + " |-> " + util::common::uistr(next));
-  tbl.insert(v, tup(next,nm));
-  ret (next + 1u);
-}
-
-/* builds a table mapping each local var defined in f
- to a bit number in the precondition/postcondition vectors */
-fn mk_fn_info(_fn f) -> fn_info {
-  auto res = new_def_hash[var_info]();
-  let uint next = 0u;
-  let vec[ast::arg] f_args = f.decl.inputs;
-
-  /* ignore args, which we know are initialized;
-     just collect locally declared vars */
-
-  let @vec[tup(ident,def_id)] locals = find_locals(f);
-  log(uistr(vec::len[tup(ident, def_id)](*locals)) + " locals");
-  for (tup(ident,def_id) p in *locals) {
-    next = add_var(p._1, p._0, next, res);
-  }
-
-  ret res;
-}
-
-/* extends mk_fn_info to a function item, side-effecting the map fi from
-   function IDs to fn_info maps */
-fn mk_fn_info_item_fn(&fn_info_map fi, &span sp, &ident i, &ast::_fn f,
-                 &vec[ast::ty_param] ty_params, &def_id id, &ann a) -> @item {
-  fi.insert(id, mk_fn_info(f));
-  log(i + " has " + uistr(num_locals(mk_fn_info(f))) + " local vars");
-  ret @respan(sp, item_fn(i, f, ty_params, id, a));
-}
-
-/* extends mk_fn_info to an obj item, side-effecting the map fi from
-   function IDs to fn_info maps */
-fn mk_fn_info_item_obj(&fn_info_map fi, &span sp, &ident i, &ast::_obj o,
-                       &vec[ast::ty_param] ty_params,
-                       &ast::obj_def_ids odid, &ann a) -> @item {
-    auto all_methods = vec::clone[@method](o.methods);
-    plus_option[@method](all_methods, o.dtor);
-    for (@method m in all_methods) {
-        fi.insert(m.node.id, mk_fn_info(m.node.meth));
-        log(m.node.ident + " has " +
-            uistr(num_locals(mk_fn_info(m.node.meth))) + " local vars");
-    }
-    ret @respan(sp, item_obj(i, o, ty_params, odid, a));
-}
-
-/* initializes the global fn_info_map (mapping each function ID, including
-   nested locally defined functions, onto a mapping from local variable name
-   to bit number) */
-fn mk_f_to_fn_info(@ast::crate c) -> fn_info_map {
-  auto res = new_def_hash[fn_info]();
-
-  auto fld = fold::new_identity_fold[fn_info_map]();
-  fld = @rec(fold_item_fn  = bind mk_fn_info_item_fn(_,_,_,_,_,_,_),
-             fold_item_obj = bind mk_fn_info_item_obj(_,_,_,_,_,_,_)
-               with *fld);
-  fold::fold_crate[fn_info_map](res, fld, c);
-
-  ret res;
-}
-/**** Helpers ****/
-fn ann_to_ts_ann(ann a, uint nv) -> ts_ann {
-    alt (a.ts) {
-        /* Kind of inconsistent. empty_ann()s everywhere
-           or an option of a ts_ann? */
-        case (none[@ts_ann])     { ret empty_ann(nv); }
-        case (some[@ts_ann](?t)) { ret *t; }
-    }
-}
-
-fn ann_to_ts_ann_fail(ann a) -> option::t[@ts_ann] { ret a.ts; }
-
-fn ann_to_ts_ann_fail_more(ann a) -> @ts_ann {
-    assert (! is_none[@ts_ann](a.ts));
-    ret get[@ts_ann](a.ts);
-}
-
-fn ann_to_poststate(ann a) -> poststate {
-    ret (ann_to_ts_ann_fail_more(a)).states.poststate;
-}
-
-fn stmt_to_ann(&stmt s) -> option::t[@ts_ann] {
-  alt (s.node) {
-    case (stmt_decl(_,?a)) {
-        ret ann_to_ts_ann_fail(a);
-    }
-    case (stmt_expr(_,?a)) {
-        ret ann_to_ts_ann_fail(a);
-    }
-    case (stmt_crate_directive(_)) {
-      ret none[@ts_ann];
-    }
-  }
-}
-
-/* fails if e has no annotation */
-fn expr_states(@expr e) -> pre_and_post_state {
-    alt (a.ts) {
-        case (none[@ts_ann]) {
-            log_err "expr_pp: the impossible happened (no pre/post)";
-            fail;
-        }
-        case (some[@ts_ann](?p)) { ret p.states; }
-    }
-}
-
-/* fails if e has no annotation */
-fn expr_pp(@expr e) -> pre_and_post {
-    alt (expr_ann(e).ts) {
-        case (none[@ts_ann]) {
-            log_err "expr_pp: the impossible happened (no pre/post)";
-            fail;
-        }
-        case (some[@ts_ann](?p)) { ret p.conditions; }
-    }
-}
-
-fn stmt_pp(&stmt s) -> pre_and_post {
-    alt (stmt_to_ann(s)) {
-        case (none[@ts_ann]) {
-            log "stmt_pp: the impossible happened (no annotation)";
-            fail;
-        }
-        case (some[@ts_ann](?p)) {
-            ret p.conditions;
-        }
-    }
-}
-
-/* fails if b has no annotation */
-/* FIXME: factor out code in the following two functions (block_ts_ann) */
-fn block_pp(&block b) -> pre_and_post {
-    alt (b.node.a.ts) {
-        case (none[@ts_ann]) {
-            log_err "block_pp: the impossible happened (no ty)";
-            fail;
-        }
-        case (some[@ts_ann](?ts)) { ret ts.conditions; }
-    }
-}
-
-fn block_states(&block b) -> pre_and_post_state {
-    alt (b.node.a.ts) {
-       case (none[@ts_ann]) {
-           log_err "block_states: the impossible happened (no ty)";
-           fail;
-       }
-       case (some[@ts_ann](?ts)) { ret ts.states; }
-    }
-}
-
-fn stmt_states(&stmt s, uint nv) -> pre_and_post_state {
-  alt (stmt_to_ann(s)) {
-    case (none[@ts_ann]) {
-      ret empty_states(nv);
-    }
-    case (some[@ts_ann](?a)) {
-      ret a.states;
-    }
-  }
-}
-
-
-fn expr_precond(@expr e) -> precond {
-  ret (expr_pp(e)).precondition;
-}
-
-fn expr_postcond(@expr e) -> postcond {
-  ret (expr_pp(e)).postcondition;
-}
-
-fn expr_prestate(@expr e) -> prestate {
-  ret (expr_states(e)).prestate;
-}
-
-fn expr_poststate(@expr e) -> poststate {
-  ret (expr_states(e)).poststate;
-}
-
-/*
-fn stmt_precond(&stmt s) -> precond {
-  ret (stmt_pp(s)).precondition;
-}
-
-fn stmt_postcond(&stmt s) -> postcond {
-  ret (stmt_pp(s)).postcondition;
-}
-*/
-
-fn states_to_poststate(&pre_and_post_state ss) -> poststate {
-  ret ss.poststate;
-}
-
-/*
-fn stmt_prestate(&stmt s) -> prestate {
-  ret (stmt_states(s)).prestate;
-}
-*/
-fn stmt_poststate(&stmt s, uint nv) -> poststate {
-  ret (stmt_states(s, nv)).poststate;
-}
-
-fn block_postcond(&block b) -> postcond {
-    ret (block_pp(b)).postcondition;
-}
-
-fn block_poststate(&block b) -> poststate {
-    ret (block_states(b)).poststate;
-}
-
-/* returns a new annotation where the pre_and_post is p */
-fn with_pp(ann a, pre_and_post p) -> ann {
-    ret rec(id=ann.id, ty=ann.ty, tps=ann.tps,
-            ts=some[@ts_ann](@rec(conditions=p,
-                                  states=empty_states(pps_len(p)))));
-}
-
-// Given a list of pres and posts for exprs e0 ... en,
-// return the precondition for evaluating each expr in order.
-// So, if e0's post is {x} and e1's pre is {x, y, z}, the entire
-// precondition shouldn't include x.
-fn seq_preconds(fn_info enclosing, vec[pre_and_post] pps) -> precond {
-  let uint sz = len[pre_and_post](pps);
-  let uint num_vars = num_locals(enclosing);
-
-  if (sz >= 1u) {
-    auto first   = pps.(0);
-    assert (pps_len(first) == num_vars);
-    let precond rest = seq_preconds(enclosing,
-                         slice[pre_and_post](pps, 1u, sz));
-    difference(rest, first.postcondition);
-    auto res = clone(first.precondition);
-    union(res, rest);
-
-    log("seq_preconds:");
-    log("first.postcondition =");
-    log_bitv(enclosing, first.postcondition);
-    log("rest =");
-    log_bitv(enclosing, rest);
-    log("returning");
-    log_bitv(enclosing, res);
-
-    ret res;
-  }
-  else {
-      ret true_precond(num_vars);
-  }
-}
-
-/* works on either postconds or preconds
- should probably rethink the whole type synonym situation */
-fn union_postconds_go(&postcond first, &vec[postcond] rest) -> postcond {
-  auto sz = vec::len[postcond](rest);
-
-  if (sz > 0u) {
-    auto other = rest.(0);
-    union(first, other);
-    union_postconds_go(first, slice[postcond](rest, 1u, len[postcond](rest)));
-  }
-
-  ret first;
-}
-
-fn union_postconds(uint nv, &vec[postcond] pcs) -> postcond {
-  if (len[postcond](pcs) > 0u) {
-      ret union_postconds_go(bitv::clone(pcs.(0)), pcs);
-  }
-  else {
-      ret empty_prestate(nv);
-  }
-}
-
-/* Gee, maybe we could use foldl or something */
-fn intersect_postconds_go(&postcond first, &vec[postcond] rest) -> postcond {
-  auto sz = vec::len[postcond](rest);
-
-  if (sz > 0u) {
-    auto other = rest.(0);
-    intersect(first, other);
-    intersect_postconds_go(first, slice[postcond](rest, 1u,
-                                                  len[postcond](rest)));
-  }
-
-  ret first;
-}
-
-fn intersect_postconds(&vec[postcond] pcs) -> postcond {
-  assert (len[postcond](pcs) > 0u);
-
-  ret intersect_postconds_go(bitv::clone(pcs.(0)), pcs);
-}
-
-/******* AST-traversing code ********/
-
-fn find_pre_post_mod(&_mod m) -> _mod {
-    log("implement find_pre_post_mod!");
-    fail;
-}
-
-fn find_pre_post_state_mod(&_mod m) -> bool {
-    log("implement find_pre_post_state_mod!");
-    fail;
-}
-
-fn find_pre_post_native_mod(&native_mod m) -> native_mod {
-    log("implement find_pre_post_native_mod");
-    fail;
-}
-
-fn find_pre_post_state_native_mod(&native_mod m) -> bool {
-    log("implement find_pre_post_state_native_mod!");
-    fail;
-}
- 
-fn find_pre_post_obj(&def_map dm, &fn_info_map fm, _obj o) -> () {
-    fn do_a_method(def_map dm, fn_info_map fm, &@method m) -> () {
-        assert (fm.contains_key(m.node.id));
-        find_pre_post_fn(dm, fm, fm.get(m.node.id), m.node.meth);
-    }
-    auto f = bind do_a_method(dm, fm, _);
-    vec::map[@method, ()](f, o.methods);
-    option::map[@method, ()](f, o.dtor);
-}
-
-fn find_pre_post_state_obj(&def_map dm, &fn_info_map fm, _obj o) -> bool {
-    fn do_a_method(def_map dm, fn_info_map fm, &@method m) -> bool {
-        assert (fm.contains_key(m.node.id));
-        ret find_pre_post_state_fn(dm, fm, fm.get(m.node.id), m.node.meth);
-    }
-    auto f = bind do_a_method(dm, fm, _);
-    auto flags = vec::map[@method, bool](f, o.methods);
-    auto changed = vec::or(flags);
-    changed = changed || maybe[@method, bool](false, f, o.dtor);
-    ret changed;
-}
-
-fn find_pre_post_item(&def_map dm, &fn_info_map fm, &fn_info enclosing,
-                      &item i) -> () {
-  alt (i.node) {
-    case (ast::item_const(?id, ?t, ?e, ?di, ?a)) {
-        find_pre_post_expr(dm, fm, enclosing, e);
-    }
-    case (ast::item_fn(?id, ?f, ?ps, ?di, ?a)) {
-      assert (fm.contains_key(di));
-      find_pre_post_fn(dm, fm, fm.get(di), f);
-    }
-    case (ast::item_mod(?id, ?m, ?di)) {
-      find_pre_post_mod(m);
-    }
-    case (ast::item_native_mod(?id, ?nm, ?di)) {
-      find_pre_post_native_mod(nm);
-    }
-    case (ast::item_ty(_,_,_,_,_)) {
-      ret;
-    }
-    case (ast::item_tag(_,_,_,_,_)) {
-      ret;
-    }
-    case (ast::item_obj(?id, ?o, ?ps, ?di, ?a)) {
-        find_pre_post_obj(dm, fm, o);
-    }
-  }
-}
-
-/* Finds the pre and postcondition for each expr in <args>;
-   sets the precondition in a to be the result of combining
-   the preconditions for <args>, and the postcondition in a to 
-   be the union of all postconditions for <args> */
-fn find_pre_post_exprs(&def_map dm, &fn_info_map fm, &fn_info enclosing,
-                       &vec[@expr] args, ann a) {
-    auto nv = num_locals(enclosing);
-
-    fn do_one(def_map dm, fn_info_map fm, fn_info enclosing,
-              &@expr e) -> () {
-        find_pre_post_expr(dm, fm, enclosing, e);
-    }
-    auto f = bind do_one(dm, fm, enclosing, _);
-
-    vec::map[@expr, ()](f, args);
-
-    fn get_pp(&@expr e) -> pre_and_post {
-        ret expr_pp(e);
-    }
-    auto g = get_pp;
-    auto pps = vec::map[@expr, pre_and_post](g, args);
-    auto h = get_post;
-
-    set_pre_and_post(a,
-       rec(precondition=seq_preconds(enclosing, pps),
-           postcondition=union_postconds
-           (nv, (vec::map[pre_and_post, postcond](h, pps)))));
-}
-
-fn find_pre_post_loop(&def_map dm, &fn_info_map fm, &fn_info enclosing,
-                      &@decl d, &@expr index, &block body, &ann a) -> () {
-    find_pre_post_expr(dm, fm, enclosing, index);
-    find_pre_post_block(dm, fm, enclosing, body);
-    auto loop_precond = declare_var(enclosing, decl_lhs(d),
-           seq_preconds(enclosing, [expr_pp(index),
-                                       block_pp(body)]));
-    auto loop_postcond = intersect_postconds
-        ([expr_postcond(index), block_postcond(body)]);
-    set_pre_and_post(a, rec(precondition=loop_precond,
-                            postcondition=loop_postcond));
-}
-
-/* Fills in annotations as a side effect. Does not rebuild the expr */
-fn find_pre_post_expr(&def_map dm, &fn_info_map fm, &fn_info enclosing,
-                      @expr e) -> () {
-    auto num_local_vars = num_locals(enclosing);
-
-    log("find_pre_post_expr (num_locals =" +
-        uistr(num_local_vars) + "):");
-    log_expr(*e);
-    
-    alt (e.node) {
-        case (expr_call(?operator, ?operands, ?a)) {
-            auto args = vec::clone[@expr](operands);
-            vec::push[@expr](args, operator);
-            find_pre_post_exprs(dm, fm, enclosing, args, a);
-        }
-        case (expr_spawn(_, _, ?operator, ?operands, ?a)) {
-            auto args = vec::clone[@expr](operands);
-            vec::push[@expr](args, operator);
-            find_pre_post_exprs(dm, fm, enclosing, args, a);
-        }
-        case (expr_vec(?args, _, ?a)) {
-            find_pre_post_exprs(dm, fm, enclosing, args, a);
-        }
-        case (expr_tup(?elts, ?a)) {
-            find_pre_post_exprs(dm, fm, enclosing, elt_exprs(elts), a);
-        }
-        case (expr_path(?p, ?a)) {
-            auto res = empty_pre_post(num_local_vars);
-
-            alt (dm.get(a.id)) {
-                case (def_local(?d_id)) {
-                    auto i = bit_num(d_id, enclosing);
-                    require_and_preserve(i, res);
-                }
-                case (_) { /* nothing to check */ }
-            }
-
-            // Otherwise, variable is global, so it must be initialized
-            set_pre_and_post(a, res);
-        }
-        case (expr_self_method(?v, ?a)) {
-            /* v is a method of the enclosing obj, so it must be
-               initialized, right? */
-            set_pre_and_post(a, empty_pre_post(num_local_vars));
-        }
-        case(expr_log(_, ?arg, ?a)) {
-            find_pre_post_expr(dm, fm, enclosing, arg);
-            set_pre_and_post(a, expr_pp(arg));
-        }
-        case (expr_chan(?arg, ?a)) {
-            find_pre_post_expr(dm, fm, enclosing, arg);
-            set_pre_and_post(a, expr_pp(arg));
-        }
-        case(expr_put(?opt, ?a)) {
-            alt (opt) {
-                case (some[@expr](?arg)) {
-                    find_pre_post_expr(dm, fm, enclosing, arg);
-                    set_pre_and_post(a, expr_pp(arg));
-                }
-                case (none[@expr]) {
-                    set_pre_and_post(a, empty_pre_post(num_local_vars));
-                }
-            }
-        }
-        case (expr_block(?b, ?a)) {
-            find_pre_post_block(dm, fm, enclosing, b);
-            set_pre_and_post(a, block_pp(b));
-        }
-        case (expr_rec(?fields,?maybe_base,?a)) {
-            auto es = field_exprs(fields);
-            vec::plus_option[@expr](es, maybe_base);
-            find_pre_post_exprs(dm, fm, enclosing, es, a);
-        }
-        case (expr_assign(?lhs, ?rhs, ?a)) {
-            alt (lhs.node) {
-                case (expr_path(?p, ?a_lhs)) {
-                    alt (dm.get(a_lhs.id))) {
-                        case (def_local(?d_id)) {
-                            find_pre_post_expr(dm, fm, enclosing, rhs);
-                            set_pre_and_post(a, expr_pp(rhs));
-                            log("gen:");
-                            log_expr(*e);
-                            gen(enclosing, a, d_id);
-                            ret;
-                        }
-                        case (_) {}
-                    }
-                }
-                case (_) {}
-            }
-            // doesn't check that lhs is an lval, but
-            // that's probably ok
-            find_pre_post_exprs(dm, fm, enclosing, [lhs, rhs], a);
-        }
-        case (expr_recv(?lhs, ?rhs, ?a)) {
-            alt (lhs.node) {
-                case (expr_path(?p, ?a_lhs)) {
-                    alt (dm.get(a_lhs.id)) {
-                        case (def_local(?d_id)) {
-                            find_pre_post_expr(dm, fm, enclosing, rhs);
-                            set_pre_and_post(a, expr_pp(rhs));
-                            log("gen:");
-                            log_expr(*e);
-                            gen(enclosing, a, d_id);
-                            ret;
-                        }
-                        case (_) {}
-                    }
-                }
-                case (_) {}
-            }
-            // doesn't check that lhs is an lval, but
-            // that's probably ok
-            find_pre_post_exprs(dm, fm, enclosing, [lhs, rhs], a);
-        }
-        case (expr_assign_op(_, ?lhs, ?rhs, ?a)) {
-            /* Different from expr_assign in that the lhs *must*
-               already be initialized */
-            find_pre_post_exprs(dm, fm, enclosing, [lhs, rhs], a);
-        }
-        case (expr_lit(_,?a)) {
-            set_pre_and_post(a, empty_pre_post(num_local_vars));
-        }
-        case (expr_ret(?maybe_val, ?a)) {
-            alt (maybe_val) {
-                case (none[@expr]) {
-                    set_pre_and_post(a,
-                      rec(precondition=true_precond(num_local_vars),
-                          postcondition=false_postcond(num_local_vars)));
-                }
-                case (some[@expr](?ret_val)) {
-                    find_pre_post_expr(dm, fm, enclosing, ret_val);
-                    let pre_and_post pp =
-                        rec(precondition=expr_precond(ret_val),
-                            postcondition=false_postcond(num_local_vars));
-                    set_pre_and_post(a, pp);
-                }
-            }
-        }
-        case (expr_be(?e, ?a)) {
-            find_pre_post_expr(dm, fm, enclosing, e);
-            set_pre_and_post(a, rec(precondition=expr_prestate(e),
-                          postcondition=false_postcond(num_local_vars)));
-        }
-        case (expr_if(?antec, ?conseq, ?maybe_alt, ?a)) {
-            find_pre_post_expr(dm, fm, enclosing, antec);
-            find_pre_post_block(dm, fm, enclosing, conseq);
-            alt (maybe_alt) {
-                case (none[@expr]) {
-                    auto precond_res = seq_preconds(enclosing,
-                                                    [expr_pp(antec),
-                                                        block_pp(conseq)]);
-                    set_pre_and_post(a, rec(precondition=precond_res,
-                                            postcondition=
-                                            expr_poststate(antec)));
-                }
-                case (some[@expr](?altern)) {
-                    find_pre_post_expr(dm, fm, enclosing, altern);
-                    auto precond_true_case =
-                        seq_preconds(enclosing,
-                                     [expr_pp(antec), block_pp(conseq)]);
-                    auto postcond_true_case = union_postconds
-                        (num_local_vars,
-                         [expr_postcond(antec), block_postcond(conseq)]);
-                    auto precond_false_case = seq_preconds
-                        (enclosing,
-                         [expr_pp(antec), expr_pp(altern)]);
-                    auto postcond_false_case = union_postconds
-                        (num_local_vars,
-                         [expr_postcond(antec), expr_postcond(altern)]);
-                    auto precond_res = union_postconds
-                        (num_local_vars,
-                         [precond_true_case, precond_false_case]);
-                    auto postcond_res = intersect_postconds
-                        ([postcond_true_case, postcond_false_case]);
-                    set_pre_and_post(a, rec(precondition=precond_res,
-                                            postcondition=postcond_res));
-                }
-            }
-        }
-        case (expr_binary(?bop,?l,?r,?a)) {
-            /* *unless* bop is lazy (e.g. and, or)? 
-             FIXME */
-            find_pre_post_exprs(dm, fm, enclosing, [l, r], a);
-        }
-        case (expr_send(?l, ?r, ?a)) {
-            find_pre_post_exprs(dm, fm, enclosing, [l, r], a);
-        }
-        case (expr_unary(_,?operand,?a)) {
-            find_pre_post_expr(dm, fm, enclosing, operand);
-            set_pre_and_post(a, expr_pp(operand));
-        }
-        case (expr_cast(?operand, _, ?a)) {
-            find_pre_post_expr(dm, fm, enclosing, operand);
-            set_pre_and_post(a, expr_pp(operand));
-        }
-        case (expr_while(?test, ?body, ?a)) {
-            find_pre_post_expr(dm, fm, enclosing, test);
-            find_pre_post_block(dm, fm, enclosing, body);
-            set_pre_and_post(a,
-              rec(precondition=
-                  seq_preconds(enclosing,
-                                 [expr_pp(test), 
-                                     block_pp(body)]),
-                  postcondition=
-                  intersect_postconds([expr_postcond(test),
-                                          block_postcond(body)])));
-        }
-        case (expr_do_while(?body, ?test, ?a)) {
-            find_pre_post_block(dm, fm, enclosing, body);
-            find_pre_post_expr(dm, fm, enclosing, test);
-   
-            auto loop_postcond = union_postconds(num_local_vars,
-                            [block_postcond(body), expr_postcond(test)]);
-            /* conservative approximination: if the body
-               could break or cont, the test may never be executed */
-            if (has_nonlocal_exits(body)) {
-                loop_postcond = empty_poststate(num_local_vars);
-            }
-
-            set_pre_and_post(a, 
-                             rec(precondition=seq_preconds(enclosing,
-                                             [block_pp(body),
-                                                 expr_pp(test)]),
-                   postcondition=loop_postcond));
-        }
-        case (expr_for(?d, ?index, ?body, ?a)) {
-            find_pre_post_loop(dm, fm, enclosing, d, index, body, a);
-        }
-        case (expr_for_each(?d, ?index, ?body, ?a)) {
-            find_pre_post_loop(dm, fm, enclosing, d, index, body, a);
-        }
-        case (expr_index(?e, ?sub, ?a)) {
-            find_pre_post_exprs(dm, fm, enclosing, [e, sub], a);
-        }
-        case (expr_alt(?e, ?alts, ?a)) {
-            find_pre_post_expr(dm, fm, enclosing, e);
-            fn do_an_alt(def_map dm, fn_info_map fm, fn_info enc, &arm an_alt)
-                -> pre_and_post {
-                find_pre_post_block(dm, fm, enc, an_alt.block);
-                ret block_pp(an_alt.block);
-            }
-            auto f = bind do_an_alt(dm, fm, enclosing, _);
-            auto alt_pps = vec::map[arm, pre_and_post](f, alts);
-            fn combine_pp(pre_and_post antec, 
-                          fn_info enclosing, &pre_and_post pp,
-                          &pre_and_post next) -> pre_and_post {
-                union(pp.precondition, seq_preconds(enclosing,
-                                         [antec, next]));
-                intersect(pp.postcondition, next.postcondition);
-                ret pp;
-            }
-            auto antec_pp = pp_clone(expr_pp(e)); 
-            auto e_pp  = rec(precondition=empty_prestate(num_local_vars),
-                             postcondition=false_postcond(num_local_vars));
-            auto g = bind combine_pp(antec_pp, enclosing, _, _);
-
-            auto alts_overall_pp = vec::foldl[pre_and_post, pre_and_post]
-                                    (g, e_pp, alt_pps);
-
-            set_pre_and_post(a, alts_overall_pp);
-        }
-        case (expr_field(?operator, _, ?a)) {
-            find_pre_post_expr(dm, fm, enclosing, operator);
-            set_pre_and_post(a, expr_pp(operator));
-        }
-        case (expr_fail(?a)) {
-            set_pre_and_post(a,
-                             /* if execution continues after fail,
-                                then everything is true! */
-               rec(precondition=empty_prestate(num_local_vars),
-                   postcondition=false_postcond(num_local_vars)));
-        }
-        case (expr_assert(?p, ?a)) {
-            find_pre_post_expr(dm, fm, enclosing, p);
-            set_pre_and_post(a, expr_pp(p));
-        }
-        case (expr_check(?p, ?a)) {
-            /* will need to change when we support arbitrary predicates... */
-            find_pre_post_expr(dm, fm, enclosing, p);
-            set_pre_and_post(a, expr_pp(p));
-        }
-        case(expr_bind(?operator, ?maybe_args, ?a)) {
-            auto args = vec::cat_options[@expr](maybe_args);
-            vec::push[@expr](args, operator); /* ??? order of eval? */
-            find_pre_post_exprs(dm, fm, enclosing, args, a);
-        }
-        case (expr_break(?a)) {
-            set_pre_and_post(a, empty_pre_post(num_local_vars));
-        }
-        case (expr_cont(?a)) {
-            set_pre_and_post(a, empty_pre_post(num_local_vars));
-        }
-        case (expr_port(?a)) {
-            set_pre_and_post(a, empty_pre_post(num_local_vars));
-        }
-        case (expr_ext(_, _, _, ?expanded, ?a)) {
-            find_pre_post_expr(dm, fm, enclosing, expanded);
-            set_pre_and_post(a, expr_pp(expanded));
-        }
-    }
-}
-
-fn gen(&fn_info enclosing, &ann a, def_id id) -> bool {
-  assert (enclosing.contains_key(id));
-  let uint i = (enclosing.get(id))._0;
-  ret set_in_postcond(i, (ann_to_ts_ann_fail_more(a)).conditions);
-}
-
-fn declare_var(&fn_info enclosing, def_id id, prestate pre)
-   -> prestate {
-    assert (enclosing.contains_key(id));
-    let uint i = (enclosing.get(id))._0;
-    auto res = clone(pre);
-    relax_prestate(i, res);
-    ret res;
-}
-
-fn gen_poststate(&fn_info enclosing, &ann a, def_id id) -> bool {
-  assert (enclosing.contains_key(id));
-  let uint i = (enclosing.get(id))._0;
-
-  ret set_in_poststate(i, (ann_to_ts_ann_fail_more(a)).states);
-}
-
-fn find_pre_post_stmt(&def_map dm, fn_info_map fm, &fn_info enclosing,
-                      &ast::stmt s) -> () {
-    log("stmt =");
-    log_stmt(s);
-
-  auto num_local_vars = num_locals(enclosing);
-  alt(s.node) {
-    case(ast::stmt_decl(?adecl, ?a)) {
-        alt(adecl.node) {
-            case(ast::decl_local(?alocal)) {
-                alt(alocal.init) {
-                    case(some[ast::initializer](?an_init)) {
-                        find_pre_post_expr(dm, fm, enclosing, an_init.expr);
-                        auto rhs_pp = expr_pp(an_init.expr);
-                        set_pre_and_post(alocal.ann, rhs_pp);
-
-                        /* Inherit ann from initializer, and add var being
-                           initialized to the postcondition */
-                        set_pre_and_post(a, rhs_pp);
-                        /*  log("gen (decl):");
-                            log_stmt(s); */
-                        gen(enclosing, a, alocal.id); 
-                        /*                     log_err("for stmt");
-                        log_stmt(s);
-                        log_err("pp = ");
-                        log_pp(stmt_pp(s)); */
-                    }
-                    case(none[ast::initializer]) {
-                        auto pp = empty_pre_post(num_local_vars);
-                        set_pre_and_post(alocal.ann, pp);
-                        set_pre_and_post(a, pp);
-                    }
-                }
-            }
-            case(decl_item(?anitem)) {
-                auto pp = empty_pre_post(num_local_vars);
-                set_pre_and_post(a, pp);
-                find_pre_post_item(dm, fm, enclosing, *anitem);
-            }
-        }
-    }
-    case(stmt_expr(?e,?a)) {
-        find_pre_post_expr(dm, fm, enclosing, e);
-        set_pre_and_post(a, expr_pp(e));
-    }    
-  }
-}
-
-fn find_pre_post_block(&def_map dm, &fn_info_map fm, &fn_info enclosing,
-                       block b) -> () {
-    /* Want to say that if there is a break or cont in this
-     block, then that invalidates the poststate upheld by
-    any of the stmts after it. 
-    Given that the typechecker has run, we know any break will be in
-    a block that forms a loop body. So that's ok. There'll never be an
-    expr_break outside a loop body, therefore, no expr_break outside a block.
-    */
-
-    /* Conservative approximation for now: This says that if a block contains
-     *any* breaks or conts, then its postcondition doesn't promise anything.
-     This will mean that:
-     x = 0;
-     break;
-
-     won't have a postcondition that says x is initialized, but that's ok.
-     */
-    auto nv = num_locals(enclosing);
-
-    fn do_one_(def_map dm, fn_info_map fm, fn_info i, &@stmt s) -> () {
-        find_pre_post_stmt(dm, fm, i, *s);
-        log("pre_post for stmt:");
-        log_stmt(*s);
-        log("is:");
-        log_pp(stmt_pp(*s));
-    }
-    auto do_one = bind do_one_(dm, fm, enclosing, _);
-    
-    vec::map[@stmt, ()](do_one, b.node.stmts);
-    fn do_inner_(def_map dm, fn_info_map fm, fn_info i, &@expr e) -> () {
-        find_pre_post_expr(dm, fm, i, e);
-    }
-    auto do_inner = bind do_inner_(dm, fm, enclosing, _);
-    option::map[@expr, ()](do_inner, b.node.expr);
-
-    let vec[pre_and_post] pps = [];
-
-    fn get_pp_stmt(&@stmt s) -> pre_and_post {
-        ret stmt_pp(*s);
-    }
-    auto f = get_pp_stmt;
-    pps += vec::map[@stmt, pre_and_post](f, b.node.stmts);
-    fn get_pp_expr(&@expr e) -> pre_and_post {
-        ret expr_pp(e);
-    }
-    auto g = get_pp_expr;
-    plus_option[pre_and_post](pps,
-       option::map[@expr, pre_and_post](g, b.node.expr));
-
-    auto block_precond  = seq_preconds(enclosing, pps);
-    auto h = get_post;
-    auto postconds =  vec::map[pre_and_post, postcond](h, pps);
-    /* A block may be empty, so this next line ensures that the postconds
-       vector is non-empty. */
-    vec::push[postcond](postconds, block_precond);
-    auto block_postcond = empty_poststate(nv);
-    /* conservative approximation */
-    if (! has_nonlocal_exits(b)) {
-        block_postcond = union_postconds(nv, postconds);
-    }
-
-    set_pre_and_post(b.node.a, rec(precondition=block_precond,
-                                   postcondition=block_postcond));
-}
-
-fn find_pre_post_fn(&def_map dm, &fn_info_map fm, &fn_info fi, &_fn f) -> () {
-    find_pre_post_block(dm, fm, fi, f.body);
-}
-
-fn check_item_fn(&def_map dm, &fn_info_map fm, &span sp, &ident i,
-                 &ast::_fn f, &vec[ast::ty_param] ty_params,
-                 &def_id id, &ann a) -> @item {
-
-    log("check_item_fn:");
-    log_fn(f, i, ty_params);
-
-  assert (fm.contains_key(id));
-  find_pre_post_fn(dm, fm, fm.get(id), f);
-
-  ret @respan(sp, ast::item_fn(i, f, ty_params, id, a));
-}
-
-fn find_pre_post_state_item(&def_map dm, &fn_info_map fm, &fn_info enclosing,
-                            @item i) -> bool {
- alt (i.node) {
-    case (ast::item_const(?id, ?t, ?e, ?di, ?a)) {
-        ret find_pre_post_state_expr(dm, fm, enclosing,
-              empty_prestate(num_locals(enclosing)), e);
-    }
-    case (ast::item_fn(?id, ?f, ?ps, ?di, ?a)) {
-      assert (fm.contains_key(di));
-      ret find_pre_post_state_fn(dm, fm, fm.get(di), f);
-    }
-    case (ast::item_mod(?id, ?m, ?di)) {
-      ret find_pre_post_state_mod(m);
-    }
-    case (ast::item_native_mod(?id, ?nm, ?di)) {
-      ret find_pre_post_state_native_mod(nm);
-    }
-    case (ast::item_ty(_,_,_,_,_)) {
-      ret false;
-    }
-    case (ast::item_tag(_,_,_,_,_)) {
-      ret false;
-    }
-    case (ast::item_obj(?id, ?o, ?ps, ?di, ?a)) {
-        ret find_pre_post_state_obj(dm, fm, o);
-    }
-  }
-}
-
-fn set_prestate_ann(@ann a, prestate pre) -> bool {
-    assert (! is_none[@ts_ann](a.ts));
-    ret set_prestate(get[@ts_ann](a.ts), pre);
-}
-
-
-fn extend_prestate_ann(ann a, prestate pre) -> bool {
-    assert (! is_none[@ts_ann](a.ts));
-    ret extend_prestate((get[@ts_ann](a.ts)).states.prestate, pre);
-}
-
-fn set_poststate_ann(ann a, poststate post) -> bool {
-    assert (! is_none[@ts_ann](a.ts));
-    ret set_poststate(get[@ts_ann](a.ts), post);
-}
-
-fn extend_poststate_ann(ann a, poststate post) -> bool {
-    assert (! is_none[@ts_ann](a.ts));
-    ret extend_poststate((*get[@ts_ann](a.ts)).states.poststate, post);
-}
-
-fn set_pre_and_post(&ann a, pre_and_post pp) -> () {
-    assert (! is_none[@ts_ann](a.ts));
-    auto t = *get[@ts_ann](a.ts);
-    /*  log("set_pre_and_post, old =");
-    log_pp(t.conditions);
-    log("new =");
-    log_pp(pp);
-    */
-    set_precondition(t, pp.precondition);
-    set_postcondition(t, pp.postcondition);
-}
-
-fn seq_states(&def_map dm, &fn_info_map fm, &fn_info enclosing,
-    prestate pres, vec[@expr] exprs) -> tup(bool, poststate) {
-  auto changed = false;
-  auto post = pres;
-
-  for (@expr e in exprs) {
-      changed = find_pre_post_state_expr(dm, fm, enclosing, post, e)
-                || changed;
-    post = expr_poststate(e);
-  }
-
-  ret tup(changed, post);
-}
-
-fn find_pre_post_state_exprs(&def_map dm,
-                             &fn_info_map fm,
-                             &fn_info enclosing,
-                             &prestate pres,
-                             &ann a, &vec[@expr] es) -> bool {
-  auto res = seq_states(dm, fm, enclosing, pres, es);
-  auto changed = res._0;
-  changed = extend_prestate_ann(a, pres) || changed;
-  changed = extend_poststate_ann(a, res._1) || changed;
-  ret changed;
-}
-
-fn pure_exp(&ann a, &prestate p) -> bool {
-  auto changed = false;
-  changed = extend_prestate_ann(a, p) || changed;
-  changed = extend_poststate_ann(a, p) || changed;
-  ret changed;
-}
-
-fn find_pre_post_state_loop(&def_map dm, &fn_info_map fm, &fn_info enclosing,
-   &prestate pres, &@decl d, &@expr index, &block body, &ann a) -> bool {
-    auto changed = false;
-
-    /* same issues as while */
-    changed = extend_prestate_ann(a, pres) || changed;
-    changed = find_pre_post_state_expr(dm, fm, enclosing, pres, index)
-        || changed;
-    /* in general, would need the intersection of
-       (poststate of index, poststate of body) */
-    changed = find_pre_post_state_block(dm, fm, enclosing,
-                expr_poststate(index), body) || changed;
-    auto res_p = intersect_postconds([expr_poststate(index),
-                                         block_poststate(body)]);
-  
-    changed = extend_poststate_ann(a, res_p) || changed;
-    ret changed;
-}
-
-fn find_pre_post_state_expr(&def_map dm, &fn_info_map fm, &fn_info enclosing,
-                            &prestate pres, @expr e) -> bool {
-  auto changed = false;
-  auto num_local_vars = num_locals(enclosing);
-
-  /* FIXME could get rid of some of the copy/paste */
-  alt (e.node) {
-    case (expr_vec(?elts, _, ?a)) {
-      ret find_pre_post_state_exprs(dm, fm, enclosing, pres, a, elts); 
-    }
-    case (expr_tup(?elts, ?a)) {
-      ret find_pre_post_state_exprs(dm, fm, enclosing, pres, a,
-                                    elt_exprs(elts));
-    }
-    case (expr_call(?operator, ?operands, ?a)) {
-      /* do the prestate for the rator */
-      changed = find_pre_post_state_expr(dm, fm, enclosing, pres, operator)
-        || changed;
-      /* rands go left-to-right */
-      ret(find_pre_post_state_exprs(dm, fm, enclosing,
-                                    expr_poststate(operator), a, operands)
-          || changed);
-    }
-    case (expr_spawn(_, _, ?operator, ?operands, ?a)) {
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, operator);
-        ret(find_pre_post_state_exprs(dm, fm, enclosing,
-                 expr_poststate(operator), a, operands)
-          || changed);
-    }
-    case (expr_bind(?operator, ?maybe_args, ?a)) {
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, operator)
-            || changed;
-        ret (find_pre_post_state_exprs(dm, fm, enclosing,
-          expr_poststate(operator), a, cat_options[@expr](maybe_args))
-            || changed);
-    }
-    case (expr_path(_,?a)) {
-      ret pure_exp(a, pres);
-    }
-    case (expr_log(_,?e,?a)) {
-        /* factor out the "one exp" pattern */
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, e);
-        changed = extend_prestate_ann(a, pres) || changed;
-        changed = extend_poststate_ann(a, expr_poststate(e)) || changed;
-        ret changed;
-    }
-    case (expr_chan(?e, ?a)) {
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, e);
-        changed = extend_prestate_ann(a, pres) || changed;
-        changed = extend_poststate_ann(a, expr_poststate(e)) || changed;
-        ret changed;
-    }
-    case (expr_ext(_, _, _, ?expanded, ?a)) {
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, expanded);
-        changed = extend_prestate_ann(a, pres) || changed;
-        changed = extend_poststate_ann(a, expr_poststate(expanded))
-           || changed;
-        ret changed;
-    }
-    case (expr_put(?maybe_e, ?a)) {
-        alt (maybe_e) {
-            case (some[@expr](?arg)) {
-                changed = find_pre_post_state_expr(dm, fm, enclosing,
-                                                   pres, arg);
-                changed = extend_prestate_ann(a, pres) || changed;
-                changed = extend_poststate_ann(a, expr_poststate(arg))
-                    || changed;
-                ret changed;
-            }
-            case (none[@expr]) {
-                ret pure_exp(a, pres);
-            }
-        }
-    }
-    case (expr_lit(?l,?a)) {
-        ret pure_exp(a, pres);
-    }
-    case (expr_block(?b,?a)) {
-        changed = find_pre_post_state_block(dm, fm, enclosing, pres, b)
-           || changed;
-        changed = extend_prestate_ann(a, pres) || changed;
-        changed = extend_poststate_ann(a, block_poststate(b)) || changed;
-        ret changed;
-    }
-    case (expr_rec(?fields,?maybe_base,?a)) {
-        changed = find_pre_post_state_exprs(dm, fm, enclosing, pres, a,
-                                            field_exprs(fields)) || changed;
-        alt (maybe_base) {
-            case (none[@expr]) { /* do nothing */ }
-            case (some[@expr](?base)) {
-                changed = find_pre_post_state_expr
-                    (dm, fm, enclosing, pres, base) || changed;
-                changed = extend_poststate_ann(a, expr_poststate(base))
-                    || changed;
-            }
-        }
-        ret changed;
-    }
-    case (expr_assign(?lhs, ?rhs, ?a)) {
-        extend_prestate_ann(a, pres);
-
-        alt (lhs.node) {
-            case (expr_path(_, ?a_lhs)) {
-                alt (dm.get(a_lhs.id)) {
-                    case (def_local(?d_id)) {
-                        // assignment to local var
-                        changed = pure_exp(a_lhs, pres) || changed;
-                        changed = find_pre_post_state_expr
-                            (dm, fm, enclosing, pres, rhs) || changed;
-                        changed = extend_poststate_ann
-                            (a, expr_poststate(rhs)) || changed;
-                        ret gen_poststate(enclosing, a, d_id)
-                            || changed;
-                    }
-                    case (_) {}
-                }
-            }
-            case (_) {}
-        }
-        // assignment to something that must already have been init'd
-        changed = find_pre_post_state_expr
-            (dm, fm, enclosing, pres, lhs) || changed;
-        changed = find_pre_post_state_expr
-            (dm, fm, enclosing, expr_poststate(lhs), rhs) || changed;
-        ret extend_poststate_ann(a, expr_poststate(rhs)) || changed;
-    }
-    case (expr_recv(?lhs, ?rhs, ?a)) {
-        extend_prestate_ann(a, pres);
-
-        alt (lhs.node) {
-            case (expr_path(?p, ?a_lhs)) {
-                alt (dm.get(a_lhs.id)) {
-                    case (def_local(?d_id)) {
-                        // receive to local var
-                        changed = pure_exp(a_lhs, pres) || changed;
-                        changed = find_pre_post_state_expr
-                            (dm, fm, enclosing, pres, rhs) || changed;
-                        changed = extend_poststate_ann(a, expr_poststate(rhs))
-                            || changed;
-                        ret gen_poststate(enclosing, a, d_id) || changed;
-                    }
-                    case (_) {}
-                }
-            }
-            case (_) {}
-        }
-        // receive to something that must already have been init'd
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, lhs)
-            || changed;
-        changed = find_pre_post_state_expr
-            (dm, fm, enclosing, expr_poststate(lhs), rhs) || changed;
-        ret extend_poststate_ann(a, expr_poststate(rhs)) || changed;
-    }
-
-    case (expr_ret(?maybe_ret_val, ?a)) {
-        changed = extend_prestate_ann(a, pres) || changed;
-        set_poststate_ann(a, false_postcond(num_local_vars));
-        alt(maybe_ret_val) {
-            case (none[@expr]) { /* do nothing */ }
-            case (some[@expr](?ret_val)) {
-                changed = find_pre_post_state_expr(dm, fm, enclosing,
-                             pres, ret_val) || changed;
-            }
-        }
-        ret changed;
-    }
-    case (expr_be(?e, ?a)) {
-        changed = extend_prestate_ann(a, pres) || changed;
-        set_poststate_ann(a, false_postcond(num_local_vars));
-        changed = find_pre_post_state_expr
-            (dm, fm, enclosing, pres, e) || changed;
-        ret changed;
-    }
-    case (expr_if(?antec, ?conseq, ?maybe_alt, ?a)) {
-        changed = extend_prestate_ann(a, pres) || changed;
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, antec)
-            || changed;
-        changed = find_pre_post_state_block(dm, fm, enclosing,
-          expr_poststate(antec), conseq) || changed;
-        alt (maybe_alt) {
-            case (none[@expr]) {
-                changed = extend_poststate_ann(a, expr_poststate(antec))
-                    || changed;
-            }
-            case (some[@expr](?altern)) {
-                changed = find_pre_post_state_expr(dm, fm, enclosing,
-                   expr_poststate(antec), altern) || changed;
-                auto poststate_res = intersect_postconds
-                    ([block_poststate(conseq), expr_poststate(altern)]);
-                changed = extend_poststate_ann(a, poststate_res) || changed;
-            }
-        }
-        log("if:");
-        log_expr(*e);
-        log("new prestate:");
-        log_bitv(enclosing, pres);
-        log("new poststate:");
-        log_bitv(enclosing, expr_poststate(e));
-
-        ret changed;
-    }
-    case (expr_binary(?bop, ?l, ?r, ?a)) {
-        /* FIXME: what if bop is lazy? */
-        changed = extend_prestate_ann(a, pres) || changed;
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, l)
-                    || changed;
-        changed = find_pre_post_state_expr(dm, fm,
-                    enclosing, expr_poststate(l), r) || changed;
-        changed = extend_poststate_ann(a, expr_poststate(r)) || changed;
-        ret changed;
-    }
-    case (expr_send(?l, ?r, ?a)) {
-        changed = extend_prestate_ann(a, pres) || changed;
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, l)
-                    || changed;
-        changed = find_pre_post_state_expr(dm, fm,
-                    enclosing, expr_poststate(l), r) || changed;
-        changed = extend_poststate_ann(a, expr_poststate(r)) || changed;
-        ret changed;
-    }
-    case (expr_assign_op(?op, ?lhs, ?rhs, ?a)) {
-        /* quite similar to binary -- should abstract this */
-        changed = extend_prestate_ann(a, pres) || changed;
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, lhs)
-                    || changed;
-        changed = find_pre_post_state_expr(dm, fm,
-                    enclosing, expr_poststate(lhs), rhs) || changed;
-        changed = extend_poststate_ann(a, expr_poststate(rhs)) || changed;
-        ret changed;
-    }
-    case (expr_while(?test, ?body, ?a)) {
-        changed = extend_prestate_ann(a, pres) || changed;
-        /* to handle general predicates, we need to pass in
-            pres `intersect` (poststate(a)) 
-         like: auto test_pres = intersect_postconds(pres, expr_postcond(a));
-         However, this doesn't work right now because we would be passing
-         in an all-zero prestate initially
-           FIXME
-           maybe need a "don't know" state in addition to 0 or 1?
-        */
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, test)
-            || changed;
-        changed = find_pre_post_state_block(dm, fm, 
-                   enclosing, expr_poststate(test), body) || changed; 
-        changed = extend_poststate_ann(a,
-                    intersect_postconds([expr_poststate(test),
-                                        block_poststate(body)])) || changed;
-        ret changed;
-    }
-    case (expr_do_while(?body, ?test, ?a)) {
-        changed = extend_prestate_ann(a, pres) || changed;
-        changed = find_pre_post_state_block(dm, fm, enclosing, pres, body)
-            || changed;
-        changed = find_pre_post_state_expr(dm, fm, enclosing,
-                     block_poststate(body), test) || changed;
-
-        /* conservative approximination: if the body of the loop
-           could break or cont, we revert to the prestate
-           (TODO: could treat cont differently from break, since
-           if there's a cont, the test will execute) */
-        if (has_nonlocal_exits(body)) {
-            changed = set_poststate_ann(a, pres) || changed;
-        }
-        else {
-            changed = extend_poststate_ann(a, expr_poststate(test))
-              || changed;
-        }
-
-        ret changed;
-    }
-    case (expr_for(?d, ?index, ?body, ?a)) {
-        ret find_pre_post_state_loop(dm, fm, enclosing, pres, d, index,
-                                     body, a);
-    }
-    case (expr_for_each(?d, ?index, ?body, ?a)) {
-        ret find_pre_post_state_loop(dm, fm, enclosing, pres, d, index,
-                                     body, a);
-    }
-    case (expr_index(?e, ?sub, ?a)) {
-        changed = extend_prestate_ann(a, pres) || changed; 
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, e)
-                  || changed;
-        changed = find_pre_post_state_expr(dm, fm, enclosing,
-                     expr_poststate(e), sub) || changed;
-        changed = extend_poststate_ann(a, expr_poststate(sub));
-        ret changed;
-    }
-    case (expr_alt(?e, ?alts, ?a)) {
-        changed = extend_prestate_ann(a, pres) || changed; 
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, e)
-                  || changed;
-        auto e_post = expr_poststate(e);
-        auto a_post;
-        if (vec::len[arm](alts) > 0u) {
-            a_post = false_postcond(num_local_vars);
-            for (arm an_alt in alts) {
-                changed = find_pre_post_state_block(dm, fm, enclosing, e_post,
-                                                    an_alt.block) || changed;
-                changed = intersect(a_post, block_poststate(an_alt.block))
-                    || changed; 
-            }
-        }
-        else {
-            // No alts; poststate is the poststate of the test
-            a_post = e_post;
-        }
-        changed = extend_poststate_ann(a, a_post);
-        ret changed;
-    }
-    case (expr_field(?e,_,?a)) {
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, e);
-        changed = extend_prestate_ann(a, pres) || changed;
-        changed = extend_poststate_ann(a, expr_poststate(e)) || changed;
-        ret changed;
-    }
-    case (expr_unary(_,?operand,?a)) {
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, operand)
-          || changed;
-        changed = extend_prestate_ann(a, pres) || changed;
-        changed = extend_poststate_ann(a, expr_poststate(operand))
-          || changed;
-        ret changed;
-    }
-    case (expr_cast(?operand, _, ?a)) {
-          changed = find_pre_post_state_expr(dm, fm, enclosing, pres, operand)
-          || changed;
-        changed = extend_prestate_ann(a, pres) || changed;
-        changed = extend_poststate_ann(a, expr_poststate(operand))
-          || changed;
-        ret changed;
-    }
-    case (expr_fail(?a)) {
-        changed = extend_prestate_ann(a, pres) || changed;
-        /* if execution continues after fail, then everything is true! woo! */
-        changed = set_poststate_ann(a, false_postcond(num_local_vars))
-          || changed;
-        ret changed;
-    }
-    case (expr_assert(?p, ?a)) {
-        ret pure_exp(a, pres);
-    }
-    case (expr_check(?p, ?a)) {
-        changed = extend_prestate_ann(a, pres) || changed;
-        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, p)
-                  || changed;
-        /* FIXME: update the postcondition to reflect that p holds */
-        changed = extend_poststate_ann(a, pres) || changed;
-        ret changed;
-    }
-    case (expr_break(?a)) {
-        ret pure_exp(a, pres);
-    }
-    case (expr_cont(?a)) {
-        ret pure_exp(a, pres);
-    }
-    case (expr_port(?a)) {
-        ret pure_exp(a, pres);
-    }
-    case (expr_self_method(_, ?a)) {
-        ret pure_exp(a, pres);
-    }
-  }
-}
-
-fn find_pre_post_state_stmt(&def_map dm, &fn_info_map fm, &fn_info enclosing,
-                            &prestate pres, @stmt s) -> bool {
-  auto changed = false;
-  auto stmt_ann_ = stmt_to_ann(*s);
-  assert (!is_none[@ts_ann](stmt_ann_));
-  auto stmt_ann = *(get[@ts_ann](stmt_ann_));
-              log("*At beginning: stmt = ");
-              log_stmt(*s);
-              log("*prestate = ");
-              log(bitv::to_str(stmt_ann.states.prestate));
-              log("*poststate =");
-              log(bitv::to_str(stmt_ann.states.poststate));
-              log("*changed =");
-              log(changed);
-  
-  alt (s.node) {
-    case (stmt_decl(?adecl, ?a)) {
-      alt (adecl.node) {
-        case (ast::decl_local(?alocal)) {
-          alt (alocal.init) {
-            case (some[ast::initializer](?an_init)) {
-                changed = extend_prestate(stmt_ann.states.prestate, pres)
-                    || changed;
-                changed = find_pre_post_state_expr
-                    (dm, fm, enclosing, pres, an_init.expr) || changed;
-                changed = extend_poststate(stmt_ann.states.poststate,
-                                           expr_poststate(an_init.expr))
-                    || changed;
-                changed = gen_poststate(enclosing, a, alocal.id) || changed;
-              log("Summary: stmt = ");
-              log_stmt(*s);
-              log("prestate = ");
-              log(bitv::to_str(stmt_ann.states.prestate));
-              log_bitv(enclosing, stmt_ann.states.prestate);
-              log("poststate =");
-              log_bitv(enclosing, stmt_ann.states.poststate);
-              log("changed =");
-              log(changed);
-  
-              ret changed;
-            }
-            case (none[ast::initializer]) {
-              changed = extend_prestate(stmt_ann.states.prestate, pres)
-                  || changed;
-              changed = extend_poststate(stmt_ann.states.poststate, pres)
-                  || changed;
-              ret changed;
-            }
-          }
-        }
-        case (ast::decl_item(?an_item)) {
-            changed = extend_prestate(stmt_ann.states.prestate, pres)
-               || changed;
-            changed = extend_poststate(stmt_ann.states.poststate, pres)
-               || changed;
-            ret find_pre_post_state_item(dm, fm, enclosing, an_item)
-                || changed;
-        }
-      }
-    }
-    case (stmt_expr(?e, _)) {
-      changed = find_pre_post_state_expr(dm, fm, enclosing, pres, e)
-                || changed;
-      changed = extend_prestate(stmt_ann.states.prestate, expr_prestate(e))
-          || changed;
-      changed = extend_poststate(stmt_ann.states.poststate,
-                                 expr_poststate(e)) || changed;
-      /*
-                    log("Summary: stmt = ");
-              log_stmt(*s);
-              log("prestate = ");
-              log(bitv::to_str(stmt_ann.states.prestate));
-              log_bitv(enclosing, stmt_ann.states.prestate);
-              log("poststate =");
-              log(bitv::to_str(stmt_ann.states.poststate));
-              log_bitv(enclosing, stmt_ann.states.poststate);
-              log("changed =");
-              log(changed);
-      */
-      ret changed;
-    }
-    case (_) { ret false; }
-  }
-}
-
-/* Updates the pre- and post-states of statements in the block,
-   returns a boolean flag saying whether any pre- or poststates changed */
-fn find_pre_post_state_block(&def_map dm, &fn_info_map fm, &fn_info enclosing,
-                             &prestate pres0, &block b)
-  -> bool {
-    
-  auto changed = false;
-  auto num_local_vars = num_locals(enclosing);
-
-  /* First, set the pre-states and post-states for every expression */
-  auto pres = pres0;
-  
-  /* Iterate over each stmt. The new prestate is <pres>. The poststate
-   consist of improving <pres> with whatever variables this stmt initializes.
-  Then <pres> becomes the new poststate. */ 
-  for (@stmt s in b.node.stmts) {
-    changed = find_pre_post_state_stmt(dm, fm, enclosing, pres, s) || changed;
-    pres = stmt_poststate(*s, num_local_vars);
-  }
-
-  auto post = pres;
-
-  alt (b.node.expr) {
-    case (none[@expr]) {}
-    case (some[@expr](?e)) {
-      changed = find_pre_post_state_expr(dm,fm, enclosing, pres, e)
-                || changed;
-      post = expr_poststate(e);
-    }
-  }
-
-  /*
-  log_err("block:");
-  log_block_err(b);
-  log_err("has non-local exits?");
-  log_err(has_nonlocal_exits(b));
-  */
-
-  /* conservative approximation: if a block contains a break
-     or cont, we assume nothing about the poststate */
-  if (has_nonlocal_exits(b)) {
-      post = pres0;
-  }
-  
-  set_prestate_ann(@b.node.a, pres0);
-  set_poststate_ann(b.node.a, post);
-
-
-  log("For block:");
-  log_block(b);
-  log("poststate = ");
-  log_states(block_states(b));
-  log("pres0:");
-  log_bitv(enclosing, pres0);
-  log("post:");
-  log_bitv(enclosing, post);
-
-
-  ret changed;
-}
-
-fn find_pre_post_state_fn(&def_map dm, &fn_info_map f_info, &fn_info fi,
-                          &ast::_fn f) -> bool {
-    /* FIXME: where do we set args as being initialized?
-       What about for methods? */
-    auto num_local_vars = num_locals(fi);
-    ret find_pre_post_state_block(dm, f_info, fi,
-                                  empty_prestate(num_local_vars), f.body);
-}
-
-fn check_states_expr(fn_info enclosing, @expr e) -> () {
-  let precond prec    = expr_precond(e);
-  let prestate pres   = expr_prestate(e);
-
-  if (!implies(pres, prec)) {
-      log_err("check_states_expr: Unsatisfied precondition constraint for ");
-      log_expr_err(*e);
-      log_err("Precondition: ");
-      log_bitv_err(enclosing, prec);
-      log_err("Prestate: ");
-      log_bitv_err(enclosing, pres);
-      fail;
-  }
-}
-
-fn check_states_stmt(fn_info enclosing, &stmt s) -> () {
-  alt (stmt_to_ann(s)) {
-    case (none[@ts_ann]) {
-      ret;
-    }
-    case (some[@ts_ann](?a)) {
-      let precond prec    = ann_precond(*a);
-      let prestate pres   = ann_prestate(*a);
-
-      /*
-      log("check_states_stmt:");
-      log_stmt(s);
-      log("prec = ");
-      log_bitv(enclosing, prec);
-      log("pres = ");
-      log_bitv(enclosing, pres);
-      */
-
-      if (!implies(pres, prec)) {
-        log_err("check_states_stmt: "
-              + "Unsatisfied precondition constraint for ");
-        log_stmt_err(s);
-        log_err("Precondition: ");
-        log_bitv_err(enclosing, prec);
-        log_err("Prestate: ");
-        log_bitv_err(enclosing, pres);
-        fail;
-      }
-    }
-  }
-}
-
-fn check_states_against_conditions(fn_info enclosing, &ast::_fn f) -> () {
-  fn do_one_(fn_info i, &@stmt s) -> () {
-    check_states_stmt(i, *s);
-  }
-  auto do_one = bind do_one_(enclosing, _);
- 
-  vec::map[@stmt, ()](do_one, f.body.node.stmts);
-  fn do_inner_(fn_info i, &@expr e) -> () {
-    check_states_expr(i, e);
-  }
-  auto do_inner = bind do_inner_(enclosing, _);
-  option::map[@expr, ()](do_inner, f.body.node.expr);
-  
-}
-
-fn check_fn_states(&def_map dm, &fn_info_map f_info_map, &fn_info f_info,
-                   &ast::_fn f) -> () {
-    /* Compute the pre- and post-states for this function */
-    // (Fixpoint iteration)
-    while (find_pre_post_state_fn(dm, f_info_map, f_info, f)) {}
-    
-  /* Now compare each expr's pre-state to its precondition
-     and post-state to its postcondition */
-    check_states_against_conditions(f_info, f);
-}
-
-fn check_item_fn_state(def_map dm, &fn_info_map f_info_map, &span sp,
-                       &ident i, &ast::_fn f, &vec[ast::ty_param] ty_params,
-                       &def_id id, &ann a) -> @item {
-
-  /* Look up the var-to-bit-num map for this function */
-  assert (f_info_map.contains_key(id));
-  auto f_info = f_info_map.get(id);
-
-  check_fn_states(dm, f_info_map, f_info, f);
-
-  /* Rebuild the same function */
-  ret @respan(sp, ast::item_fn(i, f, ty_params, id, a));
-}
-
-fn check_method_states(&def_map dm, &fn_info_map f_info_map, @method m) {
-    assert (f_info_map.contains_key(m.node.id));
-    auto f_info = f_info_map.get(m.node.id);
-    check_fn_states(dm, f_info_map, f_info, m.node.meth);
-}
-
-fn check_obj_state(def_map dm, &fn_info_map f_info_map,
-                   &vec[obj_field] fields, &vec[@method] methods,
-                   &option::t[@method] dtor) -> ast::_obj {
-    fn one(def_map dm, fn_info_map fm, &@method m) -> () {
-        ret check_method_states(dm, fm, m);
-    }
-    auto f = bind one(dm, f_info_map,_);
-    vec::map[@method, ()](f, methods);
-    option::map[@method, ()](f, dtor);
-    ret rec(fields=fields, methods=methods, dtor=dtor);
-}
-
-fn init_ann(&fn_info fi, &ann a) -> ann {
-    ret rec(id=a.id, ty=a.ty, tps=a.tps,
-            ts=some[@ts_ann](@empty_ann(num_locals(fi))));
-}
-
-fn init_blank_ann(&() ignore, &ann a) -> ann {
-    ret rec(id=a.id, ty=a.ty, tps=a.tps, ts=some[@ts_ann](@empty_ann(0u)));
-}
-
-fn init_block(&fn_info fi, &span sp, &block_ b) -> block {
-    log("init_block:");
-    log_block(respan(sp, b));
-
-    auto fld0 = fold::new_identity_fold[fn_info]();
-
-    fld0 = @rec(fold_ann = bind init_ann(_,_) with *fld0);
-    ret fold::fold_block[fn_info](fi, fld0, respan(sp, b)); 
-}
-
-fn item_fn_anns(&fn_info_map fm, &span sp, ident i, &ast::_fn f,
-                vec[ast::ty_param] ty_params, def_id id, ann a) -> @item {
-
-    assert (fm.contains_key(id));
-    auto f_info = fm.get(id);
-
-    log(i + " has " + uistr(num_locals(f_info)) + " local vars");
-
-    auto fld0 = fold::new_identity_fold[fn_info]();
-
-    fld0 = @rec(fold_ann = bind init_ann(_,_) 
-                    with *fld0);
-
-    ret fold::fold_item[fn_info]
-           (f_info, fld0, @respan(sp, item_fn(i, f, ty_params, id, a))); 
-}
-
-/* This is painstakingly written as an explicit recursion b/c the
-   standard ast::fold doesn't traverse in the correct order:
-   consider
-   fn foo() {
-      fn bar() {
-        auto x = 5;
-        log(x);
-      }
-   }
-   With fold, first bar() would be processed and its subexps would
-   correctly be annotated with length-1 bit vectors.
-   But then, the process would be repeated with (fn bar()...) as
-   a subexp of foo, which has 0 local variables -- so then
-   the body of bar() would be incorrectly annotated with length-0 bit
-   vectors. */
-fn annotate_exprs(&fn_info_map fm, &vec[@expr] es) -> vec[@expr] {
-    fn one(fn_info_map fm, &@expr e) -> @expr {
-        ret annotate_expr(fm, e);
-    }
-    auto f = bind one(fm,_);
-    ret vec::map[@expr, @expr](f, es);
-}
-fn annotate_elts(&fn_info_map fm, &vec[elt] es) -> vec[elt] {
-    fn one(fn_info_map fm, &elt e) -> elt {
-        ret rec(mut=e.mut,
-                expr=annotate_expr(fm, e.expr));
-    }
-    auto f = bind one(fm,_);
-    ret vec::map[elt, elt](f, es);
-}
-fn annotate_fields(&fn_info_map fm, &vec[field] fs) -> vec[field] {
-    fn one(fn_info_map fm, &field f) -> field {
-        ret rec(mut=f.mut,
-                 ident=f.ident,
-                 expr=annotate_expr(fm, f.expr));
-    }
-    auto f = bind one(fm,_);
-    ret vec::map[field, field](f, fs);
-}
-fn annotate_option_exp(&fn_info_map fm, &option::t[@expr] o)
-  -> option::t[@expr] {
-    fn one(fn_info_map fm, &@expr e) -> @expr {
-        ret annotate_expr(fm, e);
-    }
-    auto f = bind one(fm,_);
-    ret option::map[@expr, @expr](f, o);
-}
-fn annotate_option_exprs(&fn_info_map fm, &vec[option::t[@expr]] es)
-  -> vec[option::t[@expr]] {
-    fn one(fn_info_map fm, &option::t[@expr] o) -> option::t[@expr] {
-        ret annotate_option_exp(fm, o);
-    }
-    auto f = bind one(fm,_);
-    ret vec::map[option::t[@expr], option::t[@expr]](f, es);
-}
-fn annotate_decl(&fn_info_map fm, &@decl d) -> @decl {
-    auto d1 = d.node;
-    alt (d.node) {
-        case (decl_local(?l)) {
-            alt(l.init) {
-                case (some[initializer](?init)) {
-                    let option::t[initializer] an_i =
-                        some[initializer]
-                          (rec(expr=annotate_expr(fm, init.expr)
-                                 with init));
-                    let @local new_l = @rec(init=an_i with *l);
-                    d1 = decl_local(new_l);
-                }
-                case (_) { /* do nothing */ }
-            }
-        }
-        case (decl_item(?item)) {
-            d1 = decl_item(annotate_item(fm, item));
-        }
-    }
-    ret @respan(d.span, d1);
-}
-fn annotate_alts(&fn_info_map fm, &vec[arm] alts) -> vec[arm] {
-    fn one(fn_info_map fm, &arm a) -> arm {
-        ret rec(pat=a.pat,
-                 block=annotate_block(fm, a.block));
-    }
-    auto f = bind one(fm,_);
-    ret vec::map[arm, arm](f, alts);
-
-}
-fn annotate_expr(&fn_info_map fm, &@expr e) -> @expr {
-    auto e1 = e.node;
-    alt (e.node) {
-        case (expr_vec(?es, ?m, ?a)) {
-            e1 = expr_vec(annotate_exprs(fm, es), m, a);
-        }
-        case (expr_tup(?es, ?a)) {
-            e1 = expr_tup(annotate_elts(fm, es), a);
-        }
-        case (expr_rec(?fs, ?maybe_e, ?a)) {
-            e1 = expr_rec(annotate_fields(fm, fs),
-                          annotate_option_exp(fm, maybe_e), a);
-        }
-        case (expr_call(?e, ?es, ?a)) {
-            e1 = expr_call(annotate_expr(fm, e),
-                          annotate_exprs(fm, es), a);
-        }
-        case (expr_self_method(_,_)) {
-            // no change
-        }
-        case (expr_bind(?e, ?maybe_es, ?a)) {
-            e1 = expr_bind(annotate_expr(fm, e),
-                           annotate_option_exprs(fm, maybe_es),
-                           a);
-        }
-        case (expr_spawn(?s, ?maybe_s, ?e, ?es, ?a)) {
-            e1 = expr_spawn(s, maybe_s, annotate_expr(fm, e),
-                            annotate_exprs(fm, es), a);
-        }
-        case (expr_binary(?bop, ?w, ?x, ?a)) {
-            e1 = expr_binary(bop, annotate_expr(fm, w),
-                             annotate_expr(fm, x), a);
-        }
-        case (expr_unary(?uop, ?w, ?a)) {
-            e1 = expr_unary(uop, annotate_expr(fm, w), a);
-        }
-        case (expr_lit(_,_)) {
-            /* no change */
-        }
-        case (expr_cast(?e,?t,?a)) {
-            e1 = expr_cast(annotate_expr(fm, e), t, a);
-        }
-        case (expr_if(?e, ?b, ?maybe_e, ?a)) {
-            e1 = expr_if(annotate_expr(fm, e),
-                         annotate_block(fm, b),
-                         annotate_option_exp(fm, maybe_e), a);
-        }
-        case (expr_while(?e, ?b, ?a)) {
-            e1 = expr_while(annotate_expr(fm, e),
-                            annotate_block(fm, b), a);
-        }
-        case (expr_for(?d, ?e, ?b, ?a)) {
-            e1 = expr_for(annotate_decl(fm, d),
-                          annotate_expr(fm, e),
-                          annotate_block(fm, b), a);
-        }
-        case (expr_for_each(?d, ?e, ?b, ?a)) {
-            e1 = expr_for_each(annotate_decl(fm, d),
-                          annotate_expr(fm, e),
-                          annotate_block(fm, b), a);
-        }
-        case (expr_do_while(?b, ?e, ?a)) {
-            e1 = expr_do_while(annotate_block(fm, b),
-                               annotate_expr(fm, e), a);
-        }
-        case (expr_alt(?e, ?alts, ?a)) {
-            e1 = expr_alt(annotate_expr(fm, e),
-                          annotate_alts(fm, alts), a);
-        }
-        case (expr_block(?b, ?a)) {
-            e1 = expr_block(annotate_block(fm, b), a);
-        }
-        case (expr_assign(?l, ?r, ?a)) {
-            e1 = expr_assign(annotate_expr(fm, l), annotate_expr(fm, r), a);
-        }
-        case (expr_assign_op(?bop, ?l, ?r, ?a)) {
-            e1 = expr_assign_op(bop,
-               annotate_expr(fm, l), annotate_expr(fm, r), a);
-        }
-        case (expr_send(?l, ?r, ?a)) {
-            e1 = expr_send(annotate_expr(fm, l),
-                           annotate_expr(fm, r), a);
-        }
-        case (expr_recv(?l, ?r, ?a)) {
-           e1 = expr_recv(annotate_expr(fm, l),
-                           annotate_expr(fm, r), a);
-        }
-        case (expr_field(?e, ?i, ?a)) {
-            e1 = expr_field(annotate_expr(fm, e),
-                            i, a);
-        }
-        case (expr_index(?e, ?sub, ?a)) {
-            e1 = expr_index(annotate_expr(fm, e),
-                            annotate_expr(fm, sub), a);
-        }
-        case (expr_path(_,_)) {
-            /* no change */
-        }
-        case (expr_ext(?p, ?es, ?s_opt, ?e, ?a)) {
-            e1 = expr_ext(p, annotate_exprs(fm, es),
-                          s_opt,
-                          annotate_expr(fm, e), a);
-        }
-        /* no change, next 3 cases */
-        case (expr_fail(_)) { }
-        case (expr_break(_)) { }
-        case (expr_cont(_)) { }
-        case (expr_ret(?maybe_e, ?a)) {
-            e1 = expr_ret(annotate_option_exp(fm, maybe_e), a);
-        }
-        case (expr_put(?maybe_e, ?a)) {
-            e1 = expr_put(annotate_option_exp(fm, maybe_e), a);
-        }
-        case (expr_be(?e, ?a)) {
-            e1 = expr_be(annotate_expr(fm, e), a);
-        }
-        case (expr_log(?n, ?e, ?a)) {
-            e1 = expr_log(n, annotate_expr(fm, e), a);
-        }
-        case (expr_assert(?e, ?a)) {
-            e1 = expr_assert(annotate_expr(fm, e), a);
-        }
-        case (expr_check(?e, ?a)) {
-            e1 = expr_check(annotate_expr(fm, e), a);
-        }
-        case (expr_port(_)) { /* no change */ }
-        case (expr_chan(?e, ?a)) {
-            e1 = expr_chan(annotate_expr(fm, e), a);
-        }
-    }
-    ret @respan(e.span, e1);
-}
-
-fn annotate_stmt(&fn_info_map fm, &@stmt s) -> @stmt {
-    alt (s.node) {
-        case (stmt_decl(?d, ?a)) {
-            ret @respan(s.span, stmt_decl(annotate_decl(fm, d), a));
-        }
-        case (stmt_expr(?e, ?a)) {
-            ret @respan(s.span, stmt_expr(annotate_expr(fm, e), a));
-        }
-    }
-}
-fn annotate_block(&fn_info_map fm, &block b) -> block {
-    let vec[@stmt] new_stmts = [];
-
-    for (@stmt s in b.node.stmts) {
-        auto new_s = annotate_stmt(fm, s);
-        vec::push[@stmt](new_stmts, new_s);
-    }
-    fn ann_e(fn_info_map fm, &@expr e) -> @expr {
-        ret annotate_expr(fm, e);
-    }
-    auto f = bind ann_e(fm,_);
-
-    auto new_e = option::map[@expr, @expr](f, b.node.expr);
-
-    ret respan(b.span,
-          rec(stmts=new_stmts, expr=new_e with b.node));
-}
-fn annotate_fn(&fn_info_map fm, &ast::_fn f) -> ast::_fn {
-    // subexps have *already* been annotated based on
-    // f's number-of-locals
-    ret rec(body=annotate_block(fm, f.body) with f);
-}
-fn annotate_mod(&fn_info_map fm, &ast::_mod m) -> ast::_mod {
-    let vec[@item] new_items = [];
-
-    for (@item i in m.items) {
-        auto new_i = annotate_item(fm, i);
-        vec::push[@item](new_items, new_i);
-    }
-    ret rec(items=new_items with m);
-}
-fn annotate_method(&fn_info_map fm, &@method m) -> @method {
-    auto f_info = get_fn_info(fm, m.node.id);
-    auto fld0 = fold::new_identity_fold[fn_info]();
-    fld0 = @rec(fold_ann = bind init_ann(_,_) 
-                with *fld0);
-    auto outer = fold::fold_method[fn_info](f_info, fld0, m);
-    auto new_fn = annotate_fn(fm, outer.node.meth);
-    ret @respan(m.span,
-                rec(meth=new_fn with m.node));
-}
-
-fn annotate_obj(&fn_info_map fm, &ast::_obj o) -> ast::_obj {
-    fn one(fn_info_map fm, &@method m) -> @method {
-        ret annotate_method(fm, m);
-    }
-    auto f = bind one(fm,_);
-    auto new_methods = vec::map[@method, @method](f, o.methods);
-    auto new_dtor    = option::map[@method, @method](f, o.dtor);
-    ret rec(methods=new_methods, dtor=new_dtor with o);
-}
-
- 
-// Only annotates the components of the item recursively.
-fn annotate_item_inner(&fn_info_map fm, &@ast::item item) -> @ast::item {
-    alt (item.node) {
-        /* FIXME can't skip this case -- exprs contain blocks contain stmts,
-         which contain decls */
-        case (ast::item_const(_,_,_,_,_)) {
-            // this has already been annotated by annotate_item
-            ret item;
-        }
-        case (ast::item_fn(?ident, ?ff, ?tps, ?id, ?ann)) {
-            ret @respan(item.span,
-                        ast::item_fn(ident, annotate_fn(fm, ff),
-                                     tps, id, ann));
-        }
-        case (ast::item_mod(?ident, ?mm, ?id)) {
-            ret @respan(item.span,
-                       ast::item_mod(ident, annotate_mod(fm, mm), id));
-        }
-        case (ast::item_native_mod(?ident, ?mm, ?id)) {
-            ret item;
-        }
-        case (ast::item_ty(_,_,_,_,_)) {
-            ret item;
-        }
-        case (ast::item_tag(_,_,_,_,_)) {
-            ret item;
-        }
-        case (ast::item_obj(?ident, ?ob, ?tps, ?odid, ?ann)) {
-            ret @respan(item.span,
-              ast::item_obj(ident, annotate_obj(fm, ob), tps, odid, ann));
-        }
-    } 
-}
-
-fn annotate_item(&fn_info_map fm, &@ast::item item) -> @ast::item {
-    // Using a fold, recursively set all anns in this item
-    // to be blank.
-    // *Then*, call annotate_item recursively to do the right
-    // thing for any nested items inside this one.
-    
-    alt (item.node) {
-        case (ast::item_const(_,_,_,_,_)) {
-            auto fld0 = fold::new_identity_fold[()]();
-            fld0 = @rec(fold_ann = bind init_blank_ann(_,_) 
-                        with *fld0);
-            ret fold::fold_item[()]((), fld0, item);
-        }
-        case (ast::item_fn(?i,?ff,?tps,?id,?ann)) {
-            auto f_info = get_fn_info(fm, id);
-            auto fld0 = fold::new_identity_fold[fn_info]();
-            fld0 = @rec(fold_ann = bind init_ann(_,_) 
-                        with *fld0);
-            auto outer = fold::fold_item[fn_info](f_info, fld0, item);
-            // now recurse into any nested items
-            ret annotate_item_inner(fm, outer);
-         }
-        case (ast::item_mod(?i, ?mm, ?id)) {
-            auto fld0 = fold::new_identity_fold[()]();
-            fld0 = @rec(fold_ann = bind init_blank_ann(_,_) 
-                        with *fld0);
-            auto outer = fold::fold_item[()]((), fld0, item);
-            ret annotate_item_inner(fm, outer);
-        }
-        case (ast::item_native_mod(?i, ?nm, ?id)) {
-            ret item;
-        }
-        case (ast::item_ty(_,_,_,_,_)) {
-            ret item;
-        }
-        case (ast::item_tag(_,_,_,_,_)) {
-            ret item;
-        }
-        case (ast::item_obj(?i,?ob,?tps,?odid,?ann)) {
-            auto fld0 = fold::new_identity_fold[()]();
-            fld0 = @rec(fold_ann = bind init_blank_ann(_,_) 
-                        with *fld0);
-            auto outer = fold::fold_item[()]((), fld0, item);
-            ret annotate_item_inner(fm, outer);
-        }
-    }
-}
-
-fn annotate_module(&fn_info_map fm, &ast::_mod module) -> ast::_mod {
-    let vec[@item] new_items = [];
-
-    for (@item i in module.items) {
-        auto new_item = annotate_item(fm, i);
-        vec::push[@item](new_items, new_item);
-    }
-
-    ret rec(items = new_items with module);
-}
-
-fn annotate_crate(&fn_info_map fm, &@ast::crate crate) -> @ast::crate {
-    ret @respan(crate.span,
-               rec(module = annotate_module(fm, crate.node.module)
-                   with crate.node));
-}
-
-fn check_crate(@ast::crate crate, def_map dm) -> @ast::crate {
-  /* Build the global map from function id to var-to-bit-num-map */
-  auto fm = mk_f_to_fn_info(crate);
-
-  /* Add a blank ts_ann to every statement (and expression) */
-  auto with_anns = annotate_crate(fm, crate);
-
-  /* Compute the pre and postcondition for every subexpression */
-  auto fld = fold::new_identity_fold[fn_info_map]();
-  fld = @rec(fold_item_fn = bind check_item_fn(dm,_,_,_,_,_,_,_) with *fld);
-  auto with_pre_postconditions = fold::fold_crate[fn_info_map]
-    (fm, fld, with_anns);
-
-  auto fld1 = fold::new_identity_fold[fn_info_map]();
-
-  fld1 = @rec(fold_item_fn = bind check_item_fn_state(dm,_,_,_,_,_,_,_),
-              fold_obj     = bind check_obj_state(dm,_,_,_,_)
-              with *fld1);
-
-  ret fold::fold_crate[fn_info_map](fm, fld1,
-                                    with_pre_postconditions);
-}
-
-//
-// Local Variables:
-// mode: rust
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
-// End:
-//