about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-05-12 13:25:18 +0200
committerMarijn Haverbeke <marijnh@gmail.com>2011-05-12 15:40:21 +0200
commit358a1aeec99ba6bf3c3f6bc5886e4dddf647a75a (patch)
tree314e23b11b7fed0c6f667dfae66192ffd59566a4 /src
parent2b36e40c58a4b153da593e4da73ba45647b811de (diff)
downloadrust-358a1aeec99ba6bf3c3f6bc5886e4dddf647a75a.tar.gz
rust-358a1aeec99ba6bf3c3f6bc5886e4dddf647a75a.zip
Keep resolve data in external hash table, rather than embedded defs
One step closer to removing fold and having a single, immutable AST.
Resolve still uses fold, because it has to detect and transform
expr_field expressions. If we go through on our plan of moving to a
different syntax for module dereferencing, the parser can spit out
expr_field expressions, and resolve can move to walk.

(I am truly sorry for the things I did in typestate_check.rs. I expect
we'll want to change that to walk as well in the near future, at which
point it should probably pass around a context record, which could
hold the def_map.)
Diffstat (limited to 'src')
-rw-r--r--src/comp/driver/rustc.rs26
-rw-r--r--src/comp/front/ast.rs18
-rw-r--r--src/comp/front/eval.rs9
-rw-r--r--src/comp/front/extfmt.rs2
-rw-r--r--src/comp/front/parser.rs24
-rw-r--r--src/comp/middle/capture.rs16
-rw-r--r--src/comp/middle/fold.rs33
-rw-r--r--src/comp/middle/resolve.rs81
-rw-r--r--src/comp/middle/trans.rs206
-rw-r--r--src/comp/middle/ty.rs14
-rw-r--r--src/comp/middle/typeck.rs55
-rw-r--r--src/comp/middle/typestate_check.rs507
-rw-r--r--src/comp/middle/walk.rs2
-rw-r--r--src/comp/pretty/pprust.rs4
14 files changed, 516 insertions, 481 deletions
diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs
index 1c9698bd4cd..b38b8c9b75c 100644
--- a/src/comp/driver/rustc.rs
+++ b/src/comp/driver/rustc.rs
@@ -86,19 +86,21 @@ fn compile_input(session.session sess,
                  str input, str output) {
     auto time_passes = sess.get_opts().time_passes;
     auto def = tup(ast.local_crate, 0);
-    auto p = parser.new_parser(sess, env, def, input, 0u);
-    auto crate = time[@ast.crate](time_passes, "parsing",
-                                  bind parse_input(sess, p, input));
+    auto p = parser.new_parser(sess, env, def, input, 0u, 0u);
+    auto crate = time(time_passes, "parsing",
+                      bind parse_input(sess, p, input));
     if (sess.get_opts().output_type == Link.output_type_none) {ret;}
 
-    crate = time[@ast.crate](time_passes, "external crate reading",
-                             bind creader.read_crates(sess, crate));
-    crate = time[@ast.crate](time_passes, "resolution",
-                             bind resolve.resolve_crate(sess, crate));
+    crate = time(time_passes, "external crate reading",
+                 bind creader.read_crates(sess, crate));
+    auto res = time(time_passes, "resolution",
+                    bind resolve.resolve_crate(sess, crate));
+    crate = res._0;
+    auto def_map = res._1;
     time[()](time_passes, "capture checking",
-             bind capture.check_for_captures(sess, crate));
+             bind capture.check_for_captures(sess, crate, def_map));
 
-    auto ty_cx = ty.mk_ctxt(sess);
+    auto ty_cx = ty.mk_ctxt(sess, def_map);
     auto typeck_result =
         time[typeck.typecheck_result](time_passes, "typechecking",
                                       bind typeck.check_crate(ty_cx, crate));
@@ -106,8 +108,8 @@ fn compile_input(session.session sess,
     auto type_cache = typeck_result._1;
 
     if (sess.get_opts().run_typestate) {
-        crate = time[@ast.crate](time_passes, "typestate checking",
-            bind typestate_check.check_crate(crate));
+        crate = time(time_passes, "typestate checking",
+                     bind typestate_check.check_crate(crate, def_map));
     }
 
     auto llmod = time[llvm.ModuleRef](time_passes, "translation",
@@ -121,7 +123,7 @@ fn pretty_print_input(session.session sess,
                              eval.env env,
                              str input) {
     auto def = tup(ast.local_crate, 0);
-    auto p = front.parser.new_parser(sess, env, def, input, 0u);
+    auto p = front.parser.new_parser(sess, env, def, input, 0u, 0u);
     auto crate = front.parser.parse_crate_from_source_file(p);
     pretty.pprust.print_file(sess, crate.node.module, input, std.IO.stdout());
 }
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index af3ded19550..84dae306a44 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -56,6 +56,14 @@ tag def {
     def_native_fn(def_id);
 }
 
+fn variant_def_ids(&def d) -> tup(def_id, def_id) {
+    alt (d) {
+        case (def_variant(?tag_id, ?var_id)) {
+            ret tup(tag_id, var_id);
+        }
+    }
+}
+
 fn def_id_of_def(def d) -> def_id {
     alt (d) {
         case (def_fn(?id)) { ret id; }
@@ -106,14 +114,12 @@ type block_ = rec(vec[@stmt] stmts,
                   Option.t[@expr] expr,
                   ann a); /* ann is only meaningful for the ts_ann field */
 
-type variant_def = tup(def_id /* tag */, def_id /* variant */);
-
 type pat = spanned[pat_];
 tag pat_ {
     pat_wild(ann);
     pat_bind(ident, def_id, ann);
     pat_lit(@lit, ann);
-    pat_tag(path, vec[@pat], Option.t[variant_def], ann);
+    pat_tag(path, vec[@pat], ann);
 }
 
 tag mutability {
@@ -277,7 +283,7 @@ tag expr_ {
     expr_recv(@expr /* TODO: @expr|is_lval */, @expr, ann);
     expr_field(@expr, ident, ann);
     expr_index(@expr, @expr, ann);
-    expr_path(path, Option.t[def], ann);
+    expr_path(path, ann);
     expr_ext(path, vec[@expr], Option.t[str], @expr, ann);
     expr_fail(ann);
     expr_break(ann);
@@ -333,7 +339,7 @@ tag ty_ {
     ty_rec(vec[ty_field]);
     ty_fn(proto, vec[ty_arg], @ty);
     ty_obj(vec[ty_method]);
-    ty_path(path, Option.t[def]);
+    ty_path(path, ann);
     ty_type;
     ty_constr(@ty, vec[@constr]);
 }
@@ -463,7 +469,7 @@ fn is_constraint_arg(@expr e) -> bool {
         case (expr_lit(_,_)) {
             ret true;
         }
-        case (expr_path(_, Option.some[def](def_local(_)), _)) {
+        case (expr_path(_, _)) {
             ret true;
         }
         case (_) {
diff --git a/src/comp/front/eval.rs b/src/comp/front/eval.rs
index 1d708f17004..c03e313d809 100644
--- a/src/comp/front/eval.rs
+++ b/src/comp/front/eval.rs
@@ -34,7 +34,8 @@ type ctx = @rec(parser p,
                 eval_mode mode,
                 mutable vec[str] deps,
                 session.session sess,
-                mutable uint chpos);
+                mutable uint chpos,
+                mutable uint next_ann);
 
 fn mk_env() -> env {
     let env e = vec();
@@ -113,7 +114,7 @@ fn eval_lit(ctx cx, span sp, @ast.lit lit) -> val {
 
 fn eval_expr(ctx cx, env e, @ast.expr x) -> val {
     alt (x.node) {
-        case (ast.expr_path(?pth, _, _)) {
+        case (ast.expr_path(?pth, _)) {
             if (Vec.len[ident](pth.node.idents) == 1u &&
                 Vec.len[@ast.ty](pth.node.types) == 0u) {
                 ret lookup(cx.sess, e, x.span, pth.node.idents.(0));
@@ -383,12 +384,14 @@ fn eval_crate_directive(ctx cx,
             }
 
             auto start_id = cx.p.next_def_id();
-            auto p0 = new_parser(cx.sess, e, start_id, full_path, cx.chpos);
+            auto p0 = new_parser(cx.sess, e, start_id, full_path, cx.chpos,
+                                 cx.next_ann);
             auto m0 = parse_mod_items(p0, token.EOF);
             auto next_id = p0.next_def_id();
             // Thread defids and chpos through the parsers
             cx.p.set_def(next_id._1);
             cx.chpos = p0.get_chpos();
+            cx.next_ann = p0.next_ann_num();
             auto im = ast.item_mod(id, m0, next_id);
             auto i = @spanned(cdir.span.lo, cdir.span.hi, im);
             Vec.push[@ast.item](items, i);
diff --git a/src/comp/front/extfmt.rs b/src/comp/front/extfmt.rs
index 49c29a1378c..ab0800248ff 100644
--- a/src/comp/front/extfmt.rs
+++ b/src/comp/front/extfmt.rs
@@ -121,7 +121,7 @@ fn pieces_to_expr(parser p, vec[piece] pieces, vec[@ast.expr] args)
         let vec[@ast.ty] types = vec();
         auto path = rec(idents=idents, types=types);
         auto sp_path = rec(node=path, span=sp);
-        auto pathexpr = ast.expr_path(sp_path, none[ast.def], p.get_ann());
+        auto pathexpr = ast.expr_path(sp_path, p.get_ann());
         auto sp_pathexpr = @rec(node=pathexpr, span=sp);
         ret sp_pathexpr;
     }
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index e65532a8d98..fb43188af50 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -43,12 +43,13 @@ state type parser =
           fn get_filemap() -> codemap.filemap;
           fn get_chpos() -> uint;
           fn get_ann() -> ast.ann;
+          fn next_ann_num() -> uint;
     };
 
 fn new_parser(session.session sess,
                      eval.env env,
                      ast.def_id initial_def,
-                     str path, uint pos) -> parser {
+                     str path, uint pos, uint next_ann) -> parser {
     state obj stdio_parser(session.session sess,
                            eval.env env,
                            file_type ftype,
@@ -134,6 +135,9 @@ fn new_parser(session.session sess,
                 next_ann_var += 1u;
                 ret rv;
             }
+            fn next_ann_num() -> uint {
+                ret next_ann_var;
+            }
         }
     auto ftype = SOURCE_FILE;
     if (Str.ends_with(path, ".rc")) {
@@ -148,7 +152,7 @@ fn new_parser(session.session sess,
     auto npos = rdr.get_chpos();
     ret stdio_parser(sess, env, ftype, lexer.next_token(rdr),
                      npos, npos, initial_def._1, UNRESTRICTED, initial_def._0,
-                     rdr, prec_table(), 0u);
+                     rdr, prec_table(), next_ann);
 }
 
 fn unexpected(parser p, token.token t) {
@@ -474,7 +478,7 @@ fn parse_ty(parser p) -> @ast.ty {
 
         case (token.IDENT(_)) {
             auto path = parse_path(p, GREEDY);
-            t = ast.ty_path(path, none[ast.def]);
+            t = ast.ty_path(path, p.get_ann());
             hi = path.span.hi;
         }
 
@@ -693,7 +697,7 @@ fn parse_bottom_expr(parser p) -> @ast.expr {
         case (token.IDENT(_)) {
             auto pth = parse_path(p, MINIMAL);
             hi = pth.span.hi;
-            ex = ast.expr_path(pth, none[ast.def], p.get_ann());
+            ex = ast.expr_path(pth, p.get_ann());
         }
 
         case (token.LPAREN) {
@@ -985,7 +989,7 @@ fn extend_expr_by_ident(parser p, uint lo, uint hi,
                                @ast.expr e, ast.ident i) -> @ast.expr {
     auto e_ = e.node;
     alt (e.node) {
-        case (ast.expr_path(?pth, ?def, ?ann)) {
+        case (ast.expr_path(?pth, ?ann)) {
             if (Vec.len[@ast.ty](pth.node.types) == 0u) {
                 auto idents_ = pth.node.idents;
                 idents_ += vec(i);
@@ -993,7 +997,7 @@ fn extend_expr_by_ident(parser p, uint lo, uint hi,
                 auto pth_ = spanned(pth.span.lo, tys.span.hi,
                                     rec(idents=idents_,
                                         types=tys.node));
-                e_ = ast.expr_path(pth_, def, ann);
+                e_ = ast.expr_path(pth_, ann);
                 ret @spanned(pth_.span.lo, pth_.span.hi, e_);
             } else {
                 e_ = ast.expr_field(e, i, ann);
@@ -1525,8 +1529,7 @@ fn parse_pat(parser p) -> @ast.pat {
                 case (_) { args = vec(); }
             }
 
-            pat = ast.pat_tag(tag_path, args, none[ast.variant_def],
-                              p.get_ann());
+            pat = ast.pat_tag(tag_path, args, p.get_ann());
         }
         case (_) {
             auto lit = parse_lit(p);
@@ -1666,7 +1669,7 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
                 case (ast.expr_recv(_,_,_))     { ret true; }
                 case (ast.expr_field(_,_,_))    { ret true; }
                 case (ast.expr_index(_,_,_))    { ret true; }
-                case (ast.expr_path(_,_,_))     { ret true; }
+                case (ast.expr_path(_,_))       { ret true; }
                 case (ast.expr_fail(_))         { ret true; }
                 case (ast.expr_break(_))        { ret true; }
                 case (ast.expr_cont(_))         { ret true; }
@@ -2496,7 +2499,8 @@ fn parse_crate_from_crate_file(parser p) -> @ast.crate {
                    mode=eval.mode_parse,
                    mutable deps = deps,
                    sess=p.get_session(),
-                   mutable chpos=p.get_chpos());
+                   mutable chpos=p.get_chpos(),
+                   mutable next_ann=p.next_ann_num());
     auto m = eval.eval_crate_directives_to_mod(cx, p.get_env(),
                                                cdirs, prefix);
     auto hi = p.get_hi_pos();
diff --git a/src/comp/middle/capture.rs b/src/comp/middle/capture.rs
index 89948b4df76..7aa64fdb503 100644
--- a/src/comp/middle/capture.rs
+++ b/src/comp/middle/capture.rs
@@ -7,9 +7,11 @@ import std.Option.none;
 import std.Int;
 import std.Vec;
 import util.common;
+import resolve.def_map;
 
 type fn_id_of_local = std.Map.hashmap[ast.def_id, ast.def_id];
 type env = rec(mutable vec[ast.def_id] current_context, // fn or obj
+               def_map def_map,
                fn_id_of_local idmap,
                session.session sess);
 
@@ -22,7 +24,7 @@ fn enter_item(@env e, &@ast.item i) {
         case (ast.item_fn(?name, _, _, ?id, _)) {
             Vec.push(e.current_context, id);
         }
-        case (ast.item_obj(_, _, _, ?ids, _)) {
+        case (ast.item_obj(?name, _, _, ?ids, _)) {
             Vec.push(e.current_context, ids.ty);
         }
         case (_) {}
@@ -59,15 +61,14 @@ fn walk_expr(@env e, &@ast.expr x) {
                 case (_) { }
             }
         }
-        case (ast.expr_path(_, ?def, _)) {
+        case (ast.expr_path(?pt, ?ann)) {
             auto local_id;
-            alt (Option.get(def)) {
+            alt (e.def_map.get(ast.ann_tag(ann))) {
                 case (ast.def_local(?id)) { local_id = id; }
                 case (_) { ret; }
             }
-
-            auto df = ast.def_id_of_def(Option.get(def));
-            auto def_context = Option.get(e.idmap.find(df));
+            auto df = ast.def_id_of_def(e.def_map.get(ast.ann_tag(ann)));
+            auto def_context = e.idmap.get(df);
 
             if (current_context(*e) != def_context) {
                 e.sess.span_err(x.span,
@@ -94,9 +95,10 @@ fn walk_block(@env e, &ast.block b) {
     }
 }
 
-fn check_for_captures(session.session sess, @ast.crate crate) {
+fn check_for_captures(session.session sess, @ast.crate crate, def_map dm) {
     let vec[ast.def_id] curctx = vec();
     auto env = @rec(mutable current_context = curctx,
+                    def_map = dm,
                     idmap = common.new_def_hash[ast.def_id](),
                     sess = sess);
     auto visitor = rec(visit_item_pre = bind enter_item(env, _),
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs
index 06f4bfe5fb4..d3426684cbf 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -67,7 +67,7 @@ type ast_fold[ENV] =
          &@ty output) -> @ty)                     fold_ty_fn,
 
      (fn(&ENV e, &span sp, &ast.path p,
-         &Option.t[def] d) -> @ty)                fold_ty_path,
+         &ann a) -> @ty)                          fold_ty_path,
 
      (fn(&ENV e, &span sp, &@ty t) -> @ty)        fold_ty_chan,
      (fn(&ENV e, &span sp, &@ty t) -> @ty)        fold_ty_port,
@@ -171,7 +171,6 @@ type ast_fold[ENV] =
 
      (fn(&ENV e, &span sp,
          &path p,
-         &Option.t[def] d,
          &ann a) -> @expr)                        fold_expr_path,
 
      (fn(&ENV e, &span sp,
@@ -231,7 +230,6 @@ type ast_fold[ENV] =
 
      (fn(&ENV e, &span sp,
          &path p, &vec[@pat] args,
-         &Option.t[ast.variant_def] d,
          &ann a) -> @pat)                         fold_pat_tag,
 
 
@@ -419,9 +417,9 @@ fn fold_ty[ENV](&ENV env, &ast_fold[ENV] fld, &@ty t) -> @ty {
             ret fld.fold_ty_obj(env_, t.span, meths_);
         }
 
-        case (ast.ty_path(?pth, ?ref_opt)) {
+        case (ast.ty_path(?pth, ?ann)) {
             auto pth_ = fold_path(env, fld, pth);
-            ret fld.fold_ty_path(env_, t.span, pth_, ref_opt);
+            ret fld.fold_ty_path(env_, t.span, pth_, ann);
         }
 
         case (ast.ty_fn(?proto, ?inputs, ?output)) {
@@ -508,7 +506,7 @@ fn fold_pat[ENV](&ENV env, &ast_fold[ENV] fld, &@ast.pat p) -> @ast.pat {
         case (ast.pat_bind(?id, ?did, ?t)) {
             ret fld.fold_pat_bind(env_, p.span, id, did, t);
         }
-        case (ast.pat_tag(?path, ?pats, ?d, ?t)) {
+        case (ast.pat_tag(?path, ?pats, ?t)) {
             auto ppath = fold_path(env, fld, path);
 
             let vec[@ast.pat] ppats = vec();
@@ -516,7 +514,7 @@ fn fold_pat[ENV](&ENV env, &ast_fold[ENV] fld, &@ast.pat p) -> @ast.pat {
                 ppats += vec(fold_pat(env_, fld, pat));
             }
 
-            ret fld.fold_pat_tag(env_, p.span, ppath, ppats, d, t);
+            ret fld.fold_pat_tag(env_, p.span, ppath, ppats, t);
         }
     }
 }
@@ -742,10 +740,10 @@ fn fold_expr[ENV](&ENV env, &ast_fold[ENV] fld, &@expr e) -> @expr {
             ret fld.fold_expr_index(env_, e.span, ee, iix, t2);
         }
 
-        case (ast.expr_path(?p, ?r, ?t)) {
+        case (ast.expr_path(?p, ?t)) {
             auto p_ = fold_path(env_, fld, p);
             auto t2 = fld.fold_ann(env_, t);
-            ret fld.fold_expr_path(env_, e.span, p_, r, t2);
+            ret fld.fold_expr_path(env_, e.span, p_, t2);
         }
 
         case (ast.expr_ext(?p, ?args, ?body, ?expanded, ?t)) {
@@ -1201,8 +1199,8 @@ fn identity_fold_ty_fn[ENV](&ENV env, &span sp,
 }
 
 fn identity_fold_ty_path[ENV](&ENV env, &span sp, &ast.path p,
-                              &Option.t[def] d) -> @ty {
-    ret @respan(sp, ast.ty_path(p, d));
+                              &ann a) -> @ty {
+    ret @respan(sp, ast.ty_path(p, a));
 }
 
 fn identity_fold_ty_chan[ENV](&ENV env, &span sp, &@ty t) -> @ty {
@@ -1349,9 +1347,8 @@ fn identity_fold_expr_index[ENV](&ENV env, &span sp,
 }
 
 fn identity_fold_expr_path[ENV](&ENV env, &span sp,
-                                &path p, &Option.t[def] d,
-                                &ann a) -> @expr {
-    ret @respan(sp, ast.expr_path(p, d, a));
+                                &path p, &ann a) -> @expr {
+    ret @respan(sp, ast.expr_path(p, a));
 }
 
 fn identity_fold_expr_ext[ENV](&ENV env, &span sp,
@@ -1443,8 +1440,8 @@ fn identity_fold_pat_bind[ENV](&ENV e, &span sp, &ident i,
 }
 
 fn identity_fold_pat_tag[ENV](&ENV e, &span sp, &path p, &vec[@pat] args,
-                              &Option.t[ast.variant_def] d, &ann a) -> @pat {
-    ret @respan(sp, ast.pat_tag(p, args, d, a));
+                              &ann a) -> @pat {
+    ret @respan(sp, ast.pat_tag(p, args, a));
 }
 
 
@@ -1692,7 +1689,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
          fold_expr_recv   = bind identity_fold_expr_recv[ENV](_,_,_,_,_),
          fold_expr_field  = bind identity_fold_expr_field[ENV](_,_,_,_,_),
          fold_expr_index  = bind identity_fold_expr_index[ENV](_,_,_,_,_),
-         fold_expr_path   = bind identity_fold_expr_path[ENV](_,_,_,_,_),
+         fold_expr_path   = bind identity_fold_expr_path[ENV](_,_,_,_),
          fold_expr_ext    = bind identity_fold_expr_ext[ENV](_,_,_,_,_,_,_),
          fold_expr_fail   = bind identity_fold_expr_fail[ENV](_,_,_),
          fold_expr_break  = bind identity_fold_expr_break[ENV](_,_,_),
@@ -1715,7 +1712,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
          fold_pat_wild    = bind identity_fold_pat_wild[ENV](_,_,_),
          fold_pat_lit     = bind identity_fold_pat_lit[ENV](_,_,_,_),
          fold_pat_bind    = bind identity_fold_pat_bind[ENV](_,_,_,_,_),
-         fold_pat_tag     = bind identity_fold_pat_tag[ENV](_,_,_,_,_,_),
+         fold_pat_tag     = bind identity_fold_pat_tag[ENV](_,_,_,_,_),
 
          fold_stmt_decl   = bind identity_fold_stmt_decl[ENV](_,_,_,_),
          fold_stmt_expr   = bind identity_fold_stmt_expr[ENV](_,_,_,_),
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index 22c674595f3..1305ad5f539 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -7,6 +7,7 @@ import front.creader;
 import driver.session.session;
 import util.common.new_def_hash;
 import util.common.new_int_hash;
+import util.common.new_uint_hash;
 import util.common.new_str_hash;
 import util.common.span;
 import util.typestate_ann.ts_ann;
@@ -74,7 +75,10 @@ tag native_mod_index_entry {
 type nmod_index = hashmap[ident,native_mod_index_entry];
 type indexed_nmod = rec(ast.native_mod m, nmod_index index);
 
-type env = rec(hashmap[ast.def_num,import_state] imports,
+type def_map = hashmap[uint,def];
+
+type env = rec(def_map def_map,
+               hashmap[ast.def_num,import_state] imports,
                hashmap[ast.def_num,@indexed_mod] mod_map,
                hashmap[ast.def_num,@indexed_nmod] nmod_map,
                hashmap[def_id,vec[ident]] ext_map,
@@ -90,8 +94,10 @@ tag namespace {
     ns_type;
 }
 
-fn resolve_crate(session sess, @ast.crate crate) -> @ast.crate {
-    auto e = @rec(imports = new_int_hash[import_state](),
+fn resolve_crate(session sess, @ast.crate crate)
+    -> tup(@ast.crate, def_map) {
+    auto e = @rec(def_map = new_uint_hash[def](),
+                  imports = new_int_hash[import_state](),
                   mod_map = new_int_hash[@indexed_mod](),
                   nmod_map = new_int_hash[@indexed_nmod](),
                   ext_map = new_def_hash[vec[ident]](),
@@ -99,7 +105,7 @@ fn resolve_crate(session sess, @ast.crate crate) -> @ast.crate {
                   sess = sess);
     map_crate(e, *crate);
     resolve_imports(*e);
-    ret resolve_names(e, *crate);
+    ret tup(resolve_names(e, *crate), e.def_map);
 }
 
 // Locate all modules and imports and index them, so that the next passes can
@@ -165,8 +171,8 @@ fn resolve_imports(&env e) {
 }
 
 fn resolve_names(&@env e, &ast.crate c) -> @ast.crate {
-    auto fld = @rec(fold_pat_tag = bind fold_pat_tag(e,_,_,_,_,_,_),
-                    fold_expr_path = bind fold_expr_path(e,_,_,_,_,_),
+    auto fld = @rec(fold_pat_tag = bind fold_pat_tag(e,_,_,_,_,_),
+                    fold_expr_path = bind fold_expr_path(e,_,_,_,_),
                     fold_ty_path = bind fold_ty_path(e,_,_,_,_),
                     update_env_for_crate = bind update_env_for_crate(_,_),
                     update_env_for_item = bind update_env_for_item(_,_),
@@ -291,8 +297,8 @@ fn resolve_import(&env e, &@ast.view_item it, &list[scope] sc) {
 // and split that off as the 'primary' expr_path, with secondary expr_field
 // expressions tacked on the end.
 
-fn fold_expr_path(@env e, &list[scope] sc, &span sp, &ast.path p,
-                  &Option.t[def] d, &ann a) -> @ast.expr {
+fn fold_expr_path(@env e, &list[scope] sc, &span sp, &ast.path p, &ann a)
+    -> @ast.expr {
     auto idents = p.node.idents;
     auto n_idents = Vec.len(idents);
     assert (n_idents != 0u);
@@ -310,7 +316,10 @@ fn fold_expr_path(@env e, &list[scope] sc, &span sp, &ast.path p,
     }
 
     p = rec(node=rec(idents=Vec.slice(idents, 0u, i) with p.node) with p);
-    auto ex = @fold.respan(sp, ast.expr_path(p, some(dcur), a));
+    auto ex = @fold.respan(sp, ast.expr_path(p, a));
+    e.def_map.insert(ast.ann_tag(a), dcur);
+    // FIXME this duplicates the ann. Is that a problem? How will we deal with
+    // splitting this into path and field exprs when we don't fold?
     while (i < n_idents) {
         ex = @fold.respan(sp, ast.expr_field(ex, idents.(i), a));
         i += 1u;
@@ -319,33 +328,12 @@ fn fold_expr_path(@env e, &list[scope] sc, &span sp, &ast.path p,
 }
 
 
-fn lookup_path_strict(&env e, &list[scope] sc, &span sp, vec[ident] idents,
-                      namespace ns) -> def {
-    auto n_idents = Vec.len(idents);
-    auto dcur = lookup_in_scope_strict(e, sc, sp, idents.(0), ns);
-    auto i = 1u;
-    while (i < n_idents) {
-        if (!is_module(dcur)) {
-            e.sess.span_err(sp, idents.(i-1u) +
-                            " can't be dereferenced as a module");
-        }
-        dcur = lookup_in_mod_strict(e, dcur, sp, idents.(i), ns, outside);
-        i += 1u;
-    }
-    if (is_module(dcur)) {
-        e.sess.span_err(sp, Str.connect(idents, ".") +
-                        " is a module, not a " + ns_name(ns));
-    }
-    ret dcur;
-}
-                      
 fn fold_pat_tag(@env e, &list[scope] sc, &span sp, &ast.path p,
-                &vec[@ast.pat] args, &Option.t[ast.variant_def] old_def,
-                &ann a) -> @ast.pat {
+                &vec[@ast.pat] args, &ann a) -> @ast.pat {
     alt (lookup_path_strict(*e, sc, sp, p.node.idents, ns_value)) {
         case (ast.def_variant(?did, ?vid)) {
-            auto new_def = some[ast.variant_def](tup(did, vid));
-            ret @fold.respan[ast.pat_](sp, ast.pat_tag(p, args, new_def, a));
+            e.def_map.insert(ast.ann_tag(a), ast.def_variant(did, vid));
+            ret @fold.respan[ast.pat_](sp, ast.pat_tag(p, args, a));
         }
         case (_) {
             e.sess.span_err(sp, "not a tag variant: " +
@@ -356,9 +344,10 @@ fn fold_pat_tag(@env e, &list[scope] sc, &span sp, &ast.path p,
 }
 
 fn fold_ty_path(@env e, &list[scope] sc, &span sp, &ast.path p,
-                &Option.t[def] d) -> @ast.ty {
+                &ast.ann a) -> @ast.ty {
     auto new_def = lookup_path_strict(*e, sc, sp, p.node.idents, ns_type);
-    ret @fold.respan[ast.ty_](sp, ast.ty_path(p, some(new_def)));
+    e.def_map.insert(ast.ann_tag(a), new_def);
+    ret @fold.respan[ast.ty_](sp, ast.ty_path(p, a));
 }
 
 fn is_module(def d) -> bool {
@@ -380,6 +369,26 @@ fn unresolved(&env e, &span sp, ident id, str kind) {
     e.sess.span_err(sp, "unresolved " + kind + ": " + id);
 }
 
+fn lookup_path_strict(&env e, &list[scope] sc, &span sp, vec[ident] idents,
+                      namespace ns) -> def {
+    auto n_idents = Vec.len(idents);
+    auto dcur = lookup_in_scope_strict(e, sc, sp, idents.(0), ns);
+    auto i = 1u;
+    while (i < n_idents) {
+        if (!is_module(dcur)) {
+            e.sess.span_err(sp, idents.(i-1u) +
+                            " can't be dereferenced as a module");
+        }
+        dcur = lookup_in_mod_strict(e, dcur, sp, idents.(i), ns, outside);
+        i += 1u;
+    }
+    if (is_module(dcur)) {
+        e.sess.span_err(sp, Str.connect(idents, ".") +
+                        " is a module, not a " + ns_name(ns));
+    }
+    ret dcur;
+}
+                      
 fn lookup_in_scope_strict(&env e, list[scope] sc, &span sp, ident id,
                         namespace ns) -> def {
     alt (lookup_in_scope(e, sc, id, ns)) {
@@ -497,7 +506,7 @@ fn lookup_in_pat(ident id, &ast.pat pat) -> Option.t[def] {
         }
         case (ast.pat_wild(_)) {}
         case (ast.pat_lit(_, _)) {}
-        case (ast.pat_tag(_, ?pats, _, _)) {
+        case (ast.pat_tag(_, ?pats, _)) {
             for (@ast.pat p in pats) {
                 auto found = lookup_in_pat(id, *p);
                 if (found != none[def]) { ret found; }
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 02383f76cb4..d6e86045c4f 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -3621,13 +3621,14 @@ fn collect_upvars(&@block_ctxt cx, &ast.block bloc, &ast.def_id initial_decl)
         -> vec[ast.def_id] {
     type env = @rec(
         mutable vec[ast.def_id] refs,
-        hashmap[ast.def_id,()] decls
+        hashmap[ast.def_id,()] decls,
+        resolve.def_map def_map
     );
 
     fn walk_expr(env e, &@ast.expr expr) {
         alt (expr.node) {
-            case (ast.expr_path(?path, ?d, _)) {
-                alt (Option.get[ast.def](d)) {
+            case (ast.expr_path(?path, ?ann)) {
+                alt (e.def_map.get(ast.ann_tag(ann))) {
                     case (ast.def_arg(?did)) {
                         Vec.push[ast.def_id](e.refs, did);
                     }
@@ -3656,7 +3657,9 @@ fn collect_upvars(&@block_ctxt cx, &ast.block bloc, &ast.def_id initial_decl)
     let vec[ast.def_id] refs = vec();
     let hashmap[ast.def_id,()] decls = new_def_hash[()]();
     decls.insert(initial_decl, ());
-    let env e = @rec(mutable refs=refs, decls=decls);
+    let env e = @rec(mutable refs=refs,
+                     decls=decls,
+                     def_map=cx.fcx.lcx.ccx.tcx.def_map);
 
     auto visitor = @rec(visit_decl_pre = bind walk_decl(e, _),
                         visit_expr_pre = bind walk_expr(e, _)
@@ -3941,7 +3944,7 @@ fn trans_pat_match(&@block_ctxt cx, &@ast.pat pat, ValueRef llval,
             ret res(matched_cx, llval);
         }
 
-        case (ast.pat_tag(?id, ?subpats, ?vdef_opt, ?ann)) {
+        case (ast.pat_tag(?id, ?subpats, ?ann)) {
             auto lltagptr = cx.build.PointerCast(llval,
                 T_opaque_tag_ptr(cx.fcx.lcx.ccx.tn));
 
@@ -3949,16 +3952,16 @@ fn trans_pat_match(&@block_ctxt cx, &@ast.pat pat, ValueRef llval,
                                              vec(C_int(0), C_int(0)));
             auto lldiscrim = cx.build.Load(lldiscrimptr);
 
-            auto vdef = Option.get[ast.variant_def](vdef_opt);
-            auto variant_id = vdef._1;
+            auto vdef = ast.variant_def_ids
+                (cx.fcx.lcx.ccx.tcx.def_map.get(ast.ann_tag(ann)));
             auto variant_tag = 0;
 
             auto variants = tag_variants(cx.fcx.lcx.ccx, vdef._0);
             auto i = 0;
             for (variant_info v in variants) {
                 auto this_variant_id = v.id;
-                if (variant_id._0 == this_variant_id._0 &&
-                    variant_id._1 == this_variant_id._1) {
+                if (vdef._1._0 == this_variant_id._0 &&
+                    vdef._1._1 == this_variant_id._1) {
                     variant_tag = i;
                 }
                 i += 1;
@@ -4021,11 +4024,12 @@ fn trans_pat_binding(&@block_ctxt cx, &@ast.pat pat,
                 ret copy_ty(bcx, INIT, dst, llval, t);
             }
         }
-        case (ast.pat_tag(_, ?subpats, ?vdef_opt, ?ann)) {
+        case (ast.pat_tag(_, ?subpats, ?ann)) {
             if (Vec.len[@ast.pat](subpats) == 0u) { ret res(cx, llval); }
 
             // Get the appropriate variant for this tag.
-            auto vdef = Option.get[ast.variant_def](vdef_opt);
+            auto vdef = ast.variant_def_ids
+                (cx.fcx.lcx.ccx.tcx.def_map.get(ast.ann_tag(ann)));
 
             auto lltagptr = cx.build.PointerCast(llval,
                 T_opaque_tag_ptr(cx.fcx.lcx.ccx.tn));
@@ -4191,109 +4195,103 @@ fn lookup_discriminant(&@local_ctxt lcx, &ast.def_id tid, &ast.def_id vid)
     }
 }
 
-fn trans_path(&@block_ctxt cx, &ast.path p, &Option.t[ast.def] dopt,
-              &ast.ann ann) -> lval_result {
-    alt (dopt) {
-        case (some[ast.def](?def)) {
-            alt (def) {
-                case (ast.def_arg(?did)) {
-                    alt (cx.fcx.llargs.find(did)) {
-                        case (none[ValueRef]) {
-                            assert (cx.fcx.llupvars.contains_key(did));
-                            ret lval_mem(cx, cx.fcx.llupvars.get(did));
-                        }
-                        case (some[ValueRef](?llval)) {
-                            ret lval_mem(cx, llval);
-                        }
-                    }
-                }
-                case (ast.def_local(?did)) {
-                    alt (cx.fcx.lllocals.find(did)) {
-                        case (none[ValueRef]) {
-                            assert (cx.fcx.llupvars.contains_key(did));
-                            ret lval_mem(cx, cx.fcx.llupvars.get(did));
-                        }
-                        case (some[ValueRef](?llval)) {
-                            ret lval_mem(cx, llval);
-                        }
-                    }
+fn trans_path(&@block_ctxt cx, &ast.path p, &ast.ann ann) -> lval_result {
+    alt (cx.fcx.lcx.ccx.tcx.def_map.get(ast.ann_tag(ann))) {
+        case (ast.def_arg(?did)) {
+            alt (cx.fcx.llargs.find(did)) {
+                case (none[ValueRef]) {
+                    assert (cx.fcx.llupvars.contains_key(did));
+                    ret lval_mem(cx, cx.fcx.llupvars.get(did));
                 }
-                case (ast.def_binding(?did)) {
-                    assert (cx.fcx.lllocals.contains_key(did));
-                    ret lval_mem(cx, cx.fcx.lllocals.get(did));
+                case (some[ValueRef](?llval)) {
+                    ret lval_mem(cx, llval);
                 }
-                case (ast.def_obj_field(?did)) {
-                    assert (cx.fcx.llobjfields.contains_key(did));
-                    ret lval_mem(cx, cx.fcx.llobjfields.get(did));
+            }
+        }
+        case (ast.def_local(?did)) {
+            alt (cx.fcx.lllocals.find(did)) {
+                case (none[ValueRef]) {
+                    assert (cx.fcx.llupvars.contains_key(did));
+                    ret lval_mem(cx, cx.fcx.llupvars.get(did));
                 }
-                case (ast.def_fn(?did)) {
-                    auto tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
-                        cx.fcx.lcx.ccx.tcx, cx.fcx.lcx.ccx.type_cache, did);
-                    ret lval_generic_fn(cx, tyt, did, ann);
+                case (some[ValueRef](?llval)) {
+                    ret lval_mem(cx, llval);
                 }
-                case (ast.def_obj(?did)) {
-                    auto tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
-                        cx.fcx.lcx.ccx.tcx, cx.fcx.lcx.ccx.type_cache, did);
-                    ret lval_generic_fn(cx, tyt, did, ann);
+            }
+        }
+        case (ast.def_binding(?did)) {
+            assert (cx.fcx.lllocals.contains_key(did));
+            ret lval_mem(cx, cx.fcx.lllocals.get(did));
+        }
+        case (ast.def_obj_field(?did)) {
+            assert (cx.fcx.llobjfields.contains_key(did));
+            ret lval_mem(cx, cx.fcx.llobjfields.get(did));
+        }
+        case (ast.def_fn(?did)) {
+            auto tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
+                                           cx.fcx.lcx.ccx.tcx,
+                                           cx.fcx.lcx.ccx.type_cache, did);
+            ret lval_generic_fn(cx, tyt, did, ann);
+        }
+        case (ast.def_obj(?did)) {
+            auto tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
+                                           cx.fcx.lcx.ccx.tcx,
+                                           cx.fcx.lcx.ccx.type_cache, did);
+            ret lval_generic_fn(cx, tyt, did, ann);
+        }
+        case (ast.def_variant(?tid, ?vid)) {
+            auto v_tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
+                                             cx.fcx.lcx.ccx.tcx,
+                                             cx.fcx.lcx.ccx.type_cache, vid);
+            alt (ty.struct(cx.fcx.lcx.ccx.tcx, v_tyt._1)) {
+                case (ty.ty_fn(_, _, _)) {
+                    // N-ary variant.
+                    ret lval_generic_fn(cx, v_tyt, vid, ann);
                 }
-                case (ast.def_variant(?tid, ?vid)) {
-                    auto v_tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
-                        cx.fcx.lcx.ccx.tcx, cx.fcx.lcx.ccx.type_cache, vid);
-                    alt (ty.struct(cx.fcx.lcx.ccx.tcx, v_tyt._1)) {
-                        case (ty.ty_fn(_, _, _)) {
-                            // N-ary variant.
-                            ret lval_generic_fn(cx, v_tyt, vid, ann);
-                        }
-                        case (_) {
-                            // Nullary variant.
-                            auto tag_ty = node_ann_type(cx.fcx.lcx.ccx, ann);
-                            auto lldiscrim_gv =
-                                lookup_discriminant(cx.fcx.lcx, tid, vid);
-                            auto lldiscrim = cx.build.Load(lldiscrim_gv);
-
-                            auto alloc_result = alloc_ty(cx, tag_ty);
-                            auto lltagblob = alloc_result.val;
-
-                            auto lltagty;
-                            if (ty.type_has_dynamic_size(cx.fcx.lcx.ccx.tcx,
-                                                         tag_ty)) {
-                                lltagty = T_opaque_tag(cx.fcx.lcx.ccx.tn);
-                            } else {
-                                lltagty = type_of(cx.fcx.lcx.ccx, tag_ty);
-                            }
-                            auto lltagptr = alloc_result.bcx.build.
-                                PointerCast(lltagblob, T_ptr(lltagty));
+                case (_) {
+                    // Nullary variant.
+                    auto tag_ty = node_ann_type(cx.fcx.lcx.ccx, ann);
+                    auto lldiscrim_gv =
+                        lookup_discriminant(cx.fcx.lcx, tid, vid);
+                    auto lldiscrim = cx.build.Load(lldiscrim_gv);
+
+                    auto alloc_result = alloc_ty(cx, tag_ty);
+                    auto lltagblob = alloc_result.val;
+
+                    auto lltagty;
+                    if (ty.type_has_dynamic_size(cx.fcx.lcx.ccx.tcx,
+                                                 tag_ty)) {
+                        lltagty = T_opaque_tag(cx.fcx.lcx.ccx.tn);
+                    } else {
+                        lltagty = type_of(cx.fcx.lcx.ccx, tag_ty);
+                    }
+                    auto lltagptr = alloc_result.bcx.build.
+                        PointerCast(lltagblob, T_ptr(lltagty));
 
-                            auto lldiscrimptr = alloc_result.bcx.build.GEP(
-                                lltagptr, vec(C_int(0), C_int(0)));
-                            alloc_result.bcx.build.Store(lldiscrim,
-                                                         lldiscrimptr);
+                    auto lldiscrimptr = alloc_result.bcx.build.GEP
+                        (lltagptr, vec(C_int(0), C_int(0)));
+                    alloc_result.bcx.build.Store(lldiscrim,
+                                                 lldiscrimptr);
 
-                            ret lval_val(alloc_result.bcx, lltagptr);
-                        }
-                    }
-                }
-                case (ast.def_const(?did)) {
-                    // TODO: externals
-                    assert (cx.fcx.lcx.ccx.consts.contains_key(did));
-                    ret lval_mem(cx, cx.fcx.lcx.ccx.consts.get(did));
-                }
-                case (ast.def_native_fn(?did)) {
-                    auto tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
-                        cx.fcx.lcx.ccx.tcx,
-                        cx.fcx.lcx.ccx.type_cache, did);
-                    ret lval_generic_fn(cx, tyt, did, ann);
-                }
-                case (_) {
-                    cx.fcx.lcx.ccx.sess.unimpl("def variant in trans");
+                    ret lval_val(alloc_result.bcx, lltagptr);
                 }
             }
         }
-        case (none[ast.def]) {
-            cx.fcx.lcx.ccx.sess.err("unresolved expr_path in trans");
+        case (ast.def_const(?did)) {
+            // TODO: externals
+            assert (cx.fcx.lcx.ccx.consts.contains_key(did));
+            ret lval_mem(cx, cx.fcx.lcx.ccx.consts.get(did));
+        }
+        case (ast.def_native_fn(?did)) {
+            auto tyt = ty.lookup_item_type(cx.fcx.lcx.ccx.sess,
+                                           cx.fcx.lcx.ccx.tcx,
+                                           cx.fcx.lcx.ccx.type_cache, did);
+            ret lval_generic_fn(cx, tyt, did, ann);
+        }
+        case (_) {
+            cx.fcx.lcx.ccx.sess.unimpl("def variant in trans");
         }
     }
-    fail;
 }
 
 fn trans_field(&@block_ctxt cx, &ast.span sp, ValueRef v, &ty.t t0,
@@ -4402,8 +4400,8 @@ fn trans_index(&@block_ctxt cx, &ast.span sp, &@ast.expr base,
 
 fn trans_lval(&@block_ctxt cx, &@ast.expr e) -> lval_result {
     alt (e.node) {
-        case (ast.expr_path(?p, ?dopt, ?ann)) {
-            ret trans_path(cx, p, dopt, ann);
+        case (ast.expr_path(?p, ?ann)) {
+            ret trans_path(cx, p, ann);
         }
         case (ast.expr_field(?base, ?ident, ?ann)) {
             auto r = trans_expr(cx, base);
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index eb37b44438e..c749b2208c6 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -55,6 +55,7 @@ type mt = rec(t ty, ast.mutability mut);
 type creader_cache = hashmap[tup(int,uint,uint),ty.t];
 type ctxt = rec(@type_store ts,
                 session.session sess,
+                resolve.def_map def_map,
                 creader_cache rcache,
                 hashmap[t,str] short_names_cache);
 type ty_ctxt = ctxt;    // Needed for disambiguation from Unify.ctxt.
@@ -209,9 +210,10 @@ fn mk_rcache() -> creader_cache {
     ret Map.mk_hashmap[tup(int,uint,uint),t](h, e);
 }
 
-fn mk_ctxt(session.session s) -> ctxt {
+fn mk_ctxt(session.session s, resolve.def_map dm) -> ctxt {
     ret rec(ts = mk_type_store(),
             sess = s,
+            def_map = dm,
             rcache = mk_rcache(),
             short_names_cache =
                 Map.mk_hashmap[ty.t,str](ty.hash_ty, ty.eq_ty));
@@ -1640,7 +1642,7 @@ fn pat_ty(&ctxt cx, &@ast.pat pat) -> t {
         case (ast.pat_wild(?ann))           { ret ann_to_monotype(cx, ann); }
         case (ast.pat_lit(_, ?ann))         { ret ann_to_monotype(cx, ann); }
         case (ast.pat_bind(_, _, ?ann))     { ret ann_to_monotype(cx, ann); }
-        case (ast.pat_tag(_, _, _, ?ann))   { ret ann_to_monotype(cx, ann); }
+        case (ast.pat_tag(_, _, ?ann))      { ret ann_to_monotype(cx, ann); }
     }
     fail;   // not reached
 }
@@ -1713,7 +1715,7 @@ fn expr_ann(&@ast.expr e) -> ast.ann {
         case (ast.expr_index(_,_,?a)) {
             ret a;
         }
-        case (ast.expr_path(_,_,?a)) {
+        case (ast.expr_path(_,?a)) {
             ret a;
         }
         case (ast.expr_ext(_,_,_,_,?a)) {
@@ -1816,9 +1818,9 @@ fn replace_expr_type(&@ast.expr expr,
             ret @fold.respan(expr.span,
                              ast.expr_field(e, i, mkann(a)));
         }
-        case (ast.expr_path(?p, ?dopt, ?a)) {
+        case (ast.expr_path(?p, ?a)) {
             ret @fold.respan(expr.span,
-                             ast.expr_path(p, dopt, mkann(a)));
+                             ast.expr_path(p, mkann(a)));
         }
         case (_) {
             log_err "unhandled expr type in replace_expr_type(): " +
@@ -1897,7 +1899,7 @@ fn is_lval(&@ast.expr expr) -> bool {
     alt (expr.node) {
         case (ast.expr_field(_,_,_))    { ret true;  }
         case (ast.expr_index(_,_,_))    { ret true;  }
-        case (ast.expr_path(_,_,_))     { ret true;  }
+        case (ast.expr_path(_,_))       { ret true;  }
         case (ast.expr_unary(ast.deref,_,_))  { ret true; }
         case (_)                        { ret false; }
     }
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index af6dc024249..a8114cd174a 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -313,9 +313,8 @@ fn ast_ty_to_ty(&ty.ctxt tcx, &ty_getter getter, &@ast.ty ast_ty) -> ty.t {
             typ = ty.mk_fn(tcx, proto, i, out_ty);
         }
 
-        case (ast.ty_path(?path, ?def)) {
-            assert (def != none[ast.def]);
-            alt (Option.get[ast.def](def)) {
+        case (ast.ty_path(?path, ?ann)) {
+            alt (tcx.def_map.get(ast.ann_tag(ann))) {
                 case (ast.def_ty(?id)) {
                     typ = instantiate(tcx, getter, id, path.node.types);
                 }
@@ -1137,7 +1136,7 @@ mod Pushdown {
                                                          none[vec[ty.t]],
                                                          none[@ts_ann]));
             }
-            case (ast.pat_tag(?id, ?subpats, ?vdef_opt, ?ann)) {
+            case (ast.pat_tag(?id, ?subpats, ?ann)) {
                 // Take the variant's type parameters out of the expected
                 // type.
                 auto tag_tps;
@@ -1150,9 +1149,13 @@ mod Pushdown {
                 }
 
                 // Get the types of the arguments of the variant.
-                auto vdef = Option.get[ast.variant_def](vdef_opt);
-                auto arg_tys = variant_arg_types(fcx.ccx, pat.span, vdef._1,
-                                                 tag_tps);
+                auto arg_tys;
+                alt (fcx.ccx.tcx.def_map.get(ast.ann_tag(ann))) {
+                    case (ast.def_variant(_, ?vdefid)) {
+                        arg_tys = variant_arg_types(fcx.ccx, pat.span, vdefid,
+                                                    tag_tps);
+                    }
+                }
 
                 let vec[@ast.pat] subpats_1 = vec();
                 auto i = 0u;
@@ -1162,7 +1165,7 @@ mod Pushdown {
                 }
 
                 // TODO: push down type from "expected".
-                p_1 = ast.pat_tag(id, subpats_1, vdef_opt, ann);
+                p_1 = ast.pat_tag(id, subpats_1, ann);
             }
         }
 
@@ -1387,7 +1390,7 @@ mod Pushdown {
                                           ann_to_type(ann), adk);
                 e_1 = ast.expr_index(base, index, triv_ann(ann, t));
             }
-            case (ast.expr_path(?pth, ?d, ?ann)) {
+            case (ast.expr_path(?pth, ?ann)) {
                 auto tp_substs_0 = ty.ann_to_type_params(ann);
                 auto t_0 = ann_to_type(ann);
 
@@ -1416,7 +1419,7 @@ mod Pushdown {
                     }
                 }
 
-                e_1 = ast.expr_path(pth, d,
+                e_1 = ast.expr_path(pth,
                                     ast.ann_type(ast.ann_tag(ann), t,
                                                  ty_params_opt,
                                                  none[@ts_ann]));
@@ -1634,8 +1637,9 @@ fn check_pat(&@fn_ctxt fcx, &@ast.pat pat) -> @ast.pat {
             auto ann = triv_ann(a, next_ty_var(fcx.ccx));
             new_pat = ast.pat_bind(id, def_id, ann);
         }
-        case (ast.pat_tag(?p, ?subpats, ?vdef_opt, ?old_ann)) {
-            auto vdef = Option.get[ast.variant_def](vdef_opt);
+        case (ast.pat_tag(?p, ?subpats, ?old_ann)) {
+            auto vdef = ast.variant_def_ids
+                (fcx.ccx.tcx.def_map.get(ast.ann_tag(old_ann)));
             auto t = ty.lookup_item_type(fcx.ccx.sess, fcx.ccx.tcx,
                                          fcx.ccx.type_cache, vdef._1)._1;
             auto len = Vec.len[ast.ident](p.node.idents);
@@ -1668,7 +1672,7 @@ fn check_pat(&@fn_ctxt fcx, &@ast.pat pat) -> @ast.pat {
                         new_subpats += vec(check_pat(fcx, subpat));
                     }
 
-                    new_pat = ast.pat_tag(p, new_subpats, vdef_opt, ann);
+                    new_pat = ast.pat_tag(p, new_subpats, ann);
                 }
 
                 // Nullary variants have tag types.
@@ -1686,7 +1690,7 @@ fn check_pat(&@fn_ctxt fcx, &@ast.pat pat) -> @ast.pat {
                         fail;   // TODO: recover
                     }
 
-                    new_pat = ast.pat_tag(p, subpats, vdef_opt, ann);
+                    new_pat = ast.pat_tag(p, subpats, ann);
                 }
             }
         }
@@ -1722,7 +1726,11 @@ fn require_pure_call(@crate_ctxt ccx,
         }
         case (ast.pure_fn) {
             alt (callee.node) {
-                case (ast.expr_path(_, some[ast.def](ast.def_fn(?d_id)), _)) {
+                case (ast.expr_path(_, ?ann)) {
+                    auto d_id;
+                    alt (ccx.tcx.def_map.get(ast.ann_tag(ann))) {
+                        case (ast.def_fn(?_d_id)) { d_id = _d_id; }
+                    }
                     alt (get_function_purity(ccx, d_id)) {
                             case (ast.pure_fn) {
                                 ret;
@@ -1918,10 +1926,9 @@ fn check_expr(&@fn_ctxt fcx, &@ast.expr expr) -> @ast.expr {
                                         ast.expr_unary(unop, oper_1, ann));
         }
 
-        case (ast.expr_path(?pth, ?defopt, ?old_ann)) {
+        case (ast.expr_path(?pth, ?old_ann)) {
             auto t = ty.mk_nil(fcx.ccx.tcx);
-            assert (defopt != none[ast.def]);
-            auto defn = Option.get[ast.def](defopt);
+            auto defn = fcx.ccx.tcx.def_map.get(ast.ann_tag(old_ann));
 
             auto tpt = ty_param_count_and_ty_for_def(fcx, expr.span, defn);
 
@@ -1929,7 +1936,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast.expr expr) -> @ast.expr {
                 auto ann = instantiate_path(fcx, pth, tpt, expr.span,
                                             ast.ann_tag(old_ann));
                 ret @fold.respan[ast.expr_](expr.span,
-                                            ast.expr_path(pth, defopt, ann));
+                                            ast.expr_path(pth, ann));
             }
 
             // The definition doesn't take type parameters. If the programmer
@@ -1940,7 +1947,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast.expr expr) -> @ast.expr {
                 fail;
             }
 
-            auto e = ast.expr_path(pth, defopt, triv_ann(old_ann, tpt._1));
+            auto e = ast.expr_path(pth, triv_ann(old_ann, tpt._1));
             ret @fold.respan[ast.expr_](expr.span, e);
         }
 
@@ -2046,9 +2053,11 @@ fn check_expr(&@fn_ctxt fcx, &@ast.expr expr) -> @ast.expr {
             alt (e.node) {
                 case (ast.expr_call(?operator, ?operands, _)) {
                     alt (operator.node) {
-                        case (ast.expr_path(?oper_name,
-                                some[ast.def](ast.def_fn(?d_id)), _)) {
-
+                        case (ast.expr_path(?oper_name, ?ann)) {
+                            auto d_id;
+                            alt (fcx.ccx.tcx.def_map.get(ast.ann_tag(ann))) {
+                                case (ast.def_fn(?_d_id)) { d_id = _d_id; }
+                            }
                             for (@ast.expr operand in operands) {
                                 if (! ast.is_constraint_arg(operand)) {
                                     fcx.ccx.sess.span_err(expr.span,
diff --git a/src/comp/middle/typestate_check.rs b/src/comp/middle/typestate_check.rs
index 832938f593e..b13364184fe 100644
--- a/src/comp/middle/typestate_check.rs
+++ b/src/comp/middle/typestate_check.rs
@@ -189,6 +189,8 @@ 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 {
@@ -711,36 +713,37 @@ fn find_pre_post_state_native_mod(&native_mod m) -> bool {
     fail;
 }
  
-fn find_pre_post_obj(&fn_info_map fm, _obj o) -> () {
-    fn do_a_method(fn_info_map fm, &@method m) -> () {
+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(fm, fm.get(m.node.id), m.node.meth);
+        find_pre_post_fn(dm, fm, fm.get(m.node.id), m.node.meth);
     }
-    auto f = bind do_a_method(fm,_);
+    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(fn_info_map fm, _obj o) -> bool {
-    fn do_a_method(fn_info_map fm, &@method m) -> bool {
+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(fm, fm.get(m.node.id), m.node.meth);
+        ret find_pre_post_state_fn(dm, fm, fm.get(m.node.id), m.node.meth);
     }
-    auto f = bind do_a_method(fm,_);
+    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(fn_info_map fm, fn_info enclosing, &item i) -> () {
+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(fm, enclosing, e);
+        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(fm, fm.get(di), f);
+      find_pre_post_fn(dm, fm, fm.get(di), f);
     }
     case (ast.item_mod(?id, ?m, ?di)) {
       find_pre_post_mod(m);
@@ -755,7 +758,7 @@ fn find_pre_post_item(fn_info_map fm, fn_info enclosing, &item i) -> () {
       ret;
     }
     case (ast.item_obj(?id, ?o, ?ps, ?di, ?a)) {
-        find_pre_post_obj(fm, o);
+        find_pre_post_obj(dm, fm, o);
     }
   }
 }
@@ -764,15 +767,15 @@ fn find_pre_post_item(fn_info_map fm, fn_info enclosing, &item i) -> () {
    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(&fn_info_map fm, &fn_info enclosing,
+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(fn_info_map fm, fn_info enclosing,
+    fn do_one(def_map dm, fn_info_map fm, fn_info enclosing,
               &@expr e) -> () {
-        find_pre_post_expr(fm, enclosing, e);
+        find_pre_post_expr(dm, fm, enclosing, e);
     }
-    auto f = bind do_one(fm, enclosing, _);
+    auto f = bind do_one(dm, fm, enclosing, _);
 
     Vec.map[@expr, ()](f, args);
 
@@ -789,10 +792,10 @@ fn find_pre_post_exprs(&fn_info_map fm, &fn_info enclosing,
            (nv, (Vec.map[pre_and_post, postcond](h, pps)))));
 }
 
-fn find_pre_post_loop(&fn_info_map fm, &fn_info enclosing, &@decl d,
-     &@expr index, &block body, &ann a) -> () {
-    find_pre_post_expr(fm, enclosing, index);
-    find_pre_post_block(fm, enclosing, body);
+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, vec(expr_pp(index),
                                        block_pp(body))));
@@ -803,48 +806,35 @@ fn find_pre_post_loop(&fn_info_map fm, &fn_info enclosing, &@decl d,
 }
 
 /* Fills in annotations as a side effect. Does not rebuild the expr */
-fn find_pre_post_expr(&fn_info_map fm, &fn_info enclosing, @expr e) -> () {
+fn find_pre_post_expr(&def_map dm, &fn_info_map fm, &fn_info enclosing,
+                      @expr e) -> () {
     auto num_local_vars = num_locals(enclosing);
 
-    fn do_rand_(fn_info_map fm, fn_info enclosing, &@expr e) -> () {
-        find_pre_post_expr(fm, enclosing, e);
-    }
-    fn pp_one(&@expr e) -> pre_and_post {
-        ret expr_pp(e);
-    }
-    
-        log("find_pre_post_expr (num_locals =" +
-             uistr(num_local_vars) + "):");
-        log_expr(*e);
+    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(fm, enclosing, args, a);
+            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(fm, enclosing, args, a);
+            find_pre_post_exprs(dm, fm, enclosing, args, a);
         }
         case (expr_vec(?args, _, ?a)) {
-            find_pre_post_exprs(fm, enclosing, args, a);
+            find_pre_post_exprs(dm, fm, enclosing, args, a);
         }
         case (expr_tup(?elts, ?a)) {
-            find_pre_post_exprs(fm, enclosing, elt_exprs(elts), a);
-        }
-        case (expr_path(?p, ?maybe_def, ?a)) {
-            auto df;
-            alt (maybe_def) {
-                case (none[def])
-                    { log("expr_path should have a def"); fail; }
-                case (some[def](?d)) { df = d; }
-            }
-
+            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 (df) {
+            alt (dm.get(ast.ann_tag(a))) {
                 case (def_local(?d_id)) {
                     auto i = bit_num(d_id, enclosing);
                     require_and_preserve(i, res);
@@ -861,17 +851,17 @@ fn find_pre_post_expr(&fn_info_map fm, &fn_info enclosing, @expr e) -> () {
             set_pre_and_post(a, empty_pre_post(num_local_vars));
         }
         case(expr_log(_, ?arg, ?a)) {
-            find_pre_post_expr(fm, enclosing, arg);
+            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(fm, enclosing, arg);
+            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(fm, enclosing, arg);
+                    find_pre_post_expr(dm, fm, enclosing, arg);
                     set_pre_and_post(a, expr_pp(arg));
                 }
                 case (none[@expr]) {
@@ -880,50 +870,60 @@ fn find_pre_post_expr(&fn_info_map fm, &fn_info enclosing, @expr e) -> () {
             }
         }
         case (expr_block(?b, ?a)) {
-            find_pre_post_block(fm, enclosing, b);
+            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(fm, enclosing, es, a);
+            find_pre_post_exprs(dm, fm, enclosing, es, a);
         }
         case (expr_assign(?lhs, ?rhs, ?a)) {
             alt (lhs.node) {
-                case (expr_path(?p, some[def](def_local(?d_id)), ?a_lhs)) {
-                    find_pre_post_expr(fm, enclosing, rhs);
-                    set_pre_and_post(a, expr_pp(rhs));
-                    log("gen:");
-                    log_expr(*e);
-                    gen(enclosing, a, d_id);
-                }
-                case (_) {
-                    // doesn't check that lhs is an lval, but
-                    // that's probably ok
-                    find_pre_post_exprs(fm, enclosing, vec(lhs, rhs), a);
+                case (expr_path(?p, ?a_lhs)) {
+                    alt (dm.get(ast.ann_tag(a_lhs))) {
+                        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, vec(lhs, rhs), a);
         }
         case (expr_recv(?lhs, ?rhs, ?a)) {
             alt (lhs.node) {
-                case (expr_path(?p, some[def](def_local(?d_id)), ?a_lhs)) {
-                    find_pre_post_expr(fm, enclosing, rhs);
-                    set_pre_and_post(a, expr_pp(rhs));
-                    log("gen:");
-                    log_expr(*e);
-                    gen(enclosing, a, d_id);
-                }
-                case (_) {
-                    // doesn't check that lhs is an lval, but
-                    // that's probably ok
-                    find_pre_post_exprs(fm, enclosing, vec(lhs, rhs), a);
+                case (expr_path(?p, ?a_lhs)) {
+                    alt (dm.get(ast.ann_tag(a_lhs))) {
+                        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, vec(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(fm, enclosing, vec(lhs, rhs), a);
+            find_pre_post_exprs(dm, fm, enclosing, vec(lhs, rhs), a);
         }
         case (expr_lit(_,?a)) {
             set_pre_and_post(a, empty_pre_post(num_local_vars));
@@ -936,7 +936,7 @@ fn find_pre_post_expr(&fn_info_map fm, &fn_info enclosing, @expr e) -> () {
                           postcondition=false_postcond(num_local_vars)));
                 }
                 case (some[@expr](?ret_val)) {
-                    find_pre_post_expr(fm, enclosing, 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));
@@ -945,13 +945,13 @@ fn find_pre_post_expr(&fn_info_map fm, &fn_info enclosing, @expr e) -> () {
             }
         }
         case (expr_be(?e, ?a)) {
-            find_pre_post_expr(fm, enclosing, e);
+            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(fm, enclosing, antec);
-            find_pre_post_block(fm, enclosing, conseq);
+            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,
@@ -962,7 +962,7 @@ fn find_pre_post_expr(&fn_info_map fm, &fn_info enclosing, @expr e) -> () {
                                             expr_poststate(antec)));
                 }
                 case (some[@expr](?altern)) {
-                    find_pre_post_expr(fm, enclosing, altern);
+                    find_pre_post_expr(dm, fm, enclosing, altern);
                     auto precond_true_case =
                         seq_preconds(enclosing,
                                      vec(expr_pp(antec), block_pp(conseq)));
@@ -988,22 +988,22 @@ fn find_pre_post_expr(&fn_info_map fm, &fn_info enclosing, @expr e) -> () {
         case (expr_binary(?bop,?l,?r,?a)) {
             /* *unless* bop is lazy (e.g. and, or)? 
              FIXME */
-            find_pre_post_exprs(fm, enclosing, vec(l, r), a);
+            find_pre_post_exprs(dm, fm, enclosing, vec(l, r), a);
         }
         case (expr_send(?l, ?r, ?a)) {
-            find_pre_post_exprs(fm, enclosing, vec(l, r), a);
+            find_pre_post_exprs(dm, fm, enclosing, vec(l, r), a);
         }
         case (expr_unary(_,?operand,?a)) {
-            find_pre_post_expr(fm, enclosing, operand);
+            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(fm, enclosing, operand);
+            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(fm, enclosing, test);
-            find_pre_post_block(fm, enclosing, body);
+            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,
@@ -1014,8 +1014,8 @@ fn find_pre_post_expr(&fn_info_map fm, &fn_info enclosing, @expr e) -> () {
                                           block_postcond(body)))));
         }
         case (expr_do_while(?body, ?test, ?a)) {
-            find_pre_post_block(fm, enclosing, body);
-            find_pre_post_expr(fm, enclosing, test);
+            find_pre_post_block(dm, fm, enclosing, body);
+            find_pre_post_expr(dm, fm, enclosing, test);
    
             auto loop_postcond = union_postconds(num_local_vars,
                             vec(block_postcond(body), expr_postcond(test)));
@@ -1032,22 +1032,22 @@ fn find_pre_post_expr(&fn_info_map fm, &fn_info enclosing, @expr e) -> () {
                    postcondition=loop_postcond));
         }
         case (expr_for(?d, ?index, ?body, ?a)) {
-            find_pre_post_loop(fm, enclosing, 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(fm, enclosing, 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(fm, enclosing, vec(e, sub), a);
+            find_pre_post_exprs(dm, fm, enclosing, vec(e, sub), a);
         }
         case (expr_alt(?e, ?alts, ?a)) {
-            find_pre_post_expr(fm, enclosing, e);
-            fn do_an_alt(fn_info_map fm, fn_info enc, &arm an_alt)
+            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(fm, enc, an_alt.block);
+                find_pre_post_block(dm, fm, enc, an_alt.block);
                 ret block_pp(an_alt.block);
             }
-            auto f = bind do_an_alt(fm, enclosing, _);
+            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,
@@ -1068,7 +1068,7 @@ fn find_pre_post_expr(&fn_info_map fm, &fn_info enclosing, @expr e) -> () {
             set_pre_and_post(a, alts_overall_pp);
         }
         case (expr_field(?operator, _, ?a)) {
-            find_pre_post_expr(fm, enclosing, operator);
+            find_pre_post_expr(dm, fm, enclosing, operator);
             set_pre_and_post(a, expr_pp(operator));
         }
         case (expr_fail(?a)) {
@@ -1079,18 +1079,18 @@ fn find_pre_post_expr(&fn_info_map fm, &fn_info enclosing, @expr e) -> () {
                    postcondition=false_postcond(num_local_vars)));
         }
         case (expr_assert(?p, ?a)) {
-            find_pre_post_expr(fm, enclosing, p);
+            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(fm, enclosing, p);
+            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(fm, enclosing, args, a);
+            find_pre_post_exprs(dm, fm, enclosing, args, a);
         }
         case (expr_break(?a)) {
             set_pre_and_post(a, empty_pre_post(num_local_vars));
@@ -1102,7 +1102,7 @@ fn find_pre_post_expr(&fn_info_map fm, &fn_info enclosing, @expr e) -> () {
             set_pre_and_post(a, empty_pre_post(num_local_vars));
         }
         case (expr_ext(_, _, _, ?expanded, ?a)) {
-            find_pre_post_expr(fm, enclosing, expanded);
+            find_pre_post_expr(dm, fm, enclosing, expanded);
             set_pre_and_post(a, expr_pp(expanded));
         }
     }
@@ -1130,8 +1130,8 @@ fn gen_poststate(&fn_info enclosing, &ann a, def_id id) -> bool {
   ret set_in_poststate(i, (ann_to_ts_ann_fail_more(a)).states);
 }
 
-fn find_pre_post_stmt(fn_info_map fm, &fn_info enclosing, &ast.stmt s)
-    -> () {
+fn find_pre_post_stmt(&def_map dm, fn_info_map fm, &fn_info enclosing,
+                      &ast.stmt s) -> () {
     log("stmt =");
     log_stmt(s);
 
@@ -1142,7 +1142,7 @@ fn find_pre_post_stmt(fn_info_map fm, &fn_info enclosing, &ast.stmt s)
             case(ast.decl_local(?alocal)) {
                 alt(alocal.init) {
                     case(some[ast.initializer](?an_init)) {
-                        find_pre_post_expr(fm, enclosing, an_init.expr);
+                        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);
 
@@ -1167,19 +1167,19 @@ fn find_pre_post_stmt(fn_info_map fm, &fn_info enclosing, &ast.stmt s)
             case(decl_item(?anitem)) {
                 auto pp = empty_pre_post(num_local_vars);
                 set_pre_and_post(a, pp);
-                find_pre_post_item(fm, enclosing, *anitem);
+                find_pre_post_item(dm, fm, enclosing, *anitem);
             }
         }
     }
     case(stmt_expr(?e,?a)) {
-        find_pre_post_expr(fm, enclosing, e);
+        find_pre_post_expr(dm, fm, enclosing, e);
         set_pre_and_post(a, expr_pp(e));
     }    
   }
 }
 
-fn find_pre_post_block(&fn_info_map fm, &fn_info enclosing, block b)
-    -> () {
+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. 
@@ -1198,20 +1198,20 @@ fn find_pre_post_block(&fn_info_map fm, &fn_info enclosing, block b)
      */
     auto nv = num_locals(enclosing);
 
-    fn do_one_(fn_info_map fm, fn_info i, &@stmt s) -> () {
-        find_pre_post_stmt(fm, i, *s);
+    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_(fm, enclosing, _);
+    auto do_one = bind do_one_(dm, fm, enclosing, _);
     
     Vec.map[@stmt, ()](do_one, b.node.stmts);
-    fn do_inner_(fn_info_map fm, fn_info i, &@expr e) -> () {
-        find_pre_post_expr(fm, i, e);
+    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_(fm, enclosing, _);
+    auto do_inner = bind do_inner_(dm, fm, enclosing, _);
     Option.map[@expr, ()](do_inner, b.node.expr);
 
     let vec[pre_and_post] pps = vec();
@@ -1244,11 +1244,11 @@ fn find_pre_post_block(&fn_info_map fm, &fn_info enclosing, block b)
                                    postcondition=block_postcond));
 }
 
-fn find_pre_post_fn(&fn_info_map fm, &fn_info fi, &_fn f) -> () {
-    find_pre_post_block(fm, fi, f.body);
+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(&fn_info_map fm, &span sp, &ident i, &ast._fn f,
+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 {
 
@@ -1256,21 +1256,21 @@ fn check_item_fn(&fn_info_map fm, &span sp, &ident i, &ast._fn f,
     log_fn(f, i, ty_params);
 
   assert (fm.contains_key(id));
-  find_pre_post_fn(fm, fm.get(id), f);
+  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(fn_info_map fm, fn_info enclosing, @item i)
-   -> bool {
+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(fm, enclosing,
+        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(fm, fm.get(di), f);
+      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);
@@ -1285,7 +1285,7 @@ fn find_pre_post_state_item(fn_info_map fm, fn_info enclosing, @item i)
       ret false;
     }
     case (ast.item_obj(?id, ?o, ?ps, ?di, ?a)) {
-        ret find_pre_post_state_obj(fm, o);
+        ret find_pre_post_state_obj(dm, fm, o);
     }
   }
 }
@@ -1363,24 +1363,26 @@ fn set_pre_and_post(&ann a, pre_and_post pp) -> () {
     }
 }
 
-fn seq_states(&fn_info_map fm, &fn_info enclosing,
+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(fm, enclosing, post, e) || changed;
+      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(&fn_info_map fm,
+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(fm, enclosing, pres, es);
+  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;
@@ -1394,17 +1396,17 @@ fn pure_exp(&ann a, &prestate p) -> bool {
   ret changed;
 }
 
-fn find_pre_post_state_loop(fn_info_map fm, fn_info enclosing,
-   prestate pres, &@decl d, &@expr index, &block body, &ann a) -> bool {
+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(fm, enclosing, pres, index)
+    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(fm, enclosing,
+    changed = find_pre_post_state_block(dm, fm, enclosing,
                 expr_poststate(index), body) || changed;
     auto res_p = intersect_postconds(vec(expr_poststate(index),
                                          block_poststate(body)));
@@ -1413,7 +1415,7 @@ fn find_pre_post_state_loop(fn_info_map fm, fn_info enclosing,
     ret changed;
 }
 
-fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
+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);
@@ -1421,51 +1423,52 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info 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(fm, enclosing, pres, a, elts); 
+      ret find_pre_post_state_exprs(dm, fm, enclosing, pres, a, elts); 
     }
     case (expr_tup(?elts, ?a)) {
-      ret find_pre_post_state_exprs(fm, enclosing, pres, a, elt_exprs(elts));
+      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(fm, enclosing, pres, operator)
+      changed = find_pre_post_state_expr(dm, fm, enclosing, pres, operator)
         || changed;
       /* rands go left-to-right */
-      ret(find_pre_post_state_exprs(fm, enclosing,
+      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(fm, enclosing, pres, operator);
-        ret(find_pre_post_state_exprs(fm, enclosing,
+        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(fm, enclosing, pres, operator)
+        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, operator)
             || changed;
-        ret (find_pre_post_state_exprs(fm, enclosing,
+        ret (find_pre_post_state_exprs(dm, fm, enclosing,
           expr_poststate(operator), a, cat_options[@expr](maybe_args))
             || changed);
     }
-    case (expr_path(_,_,?a)) {
+    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(fm, enclosing, pres, e);
+        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(fm, enclosing, pres, e);
+        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(fm, enclosing, pres, expanded);
+        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;
@@ -1474,7 +1477,8 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
     case (expr_put(?maybe_e, ?a)) {
         alt (maybe_e) {
             case (some[@expr](?arg)) {
-                changed = find_pre_post_state_expr(fm, enclosing, pres, 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;
@@ -1489,20 +1493,20 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
         ret pure_exp(a, pres);
     }
     case (expr_block(?b,?a)) {
-        changed = find_pre_post_state_block(fm, enclosing, pres, b)
+        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(fm, enclosing, pres, 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(fm, enclosing, pres, base)
-                    || changed;
+                changed = find_pre_post_state_expr
+                    (dm, fm, enclosing, pres, base) || changed;
                 changed = extend_poststate_ann(a, expr_poststate(base))
                     || changed;
             }
@@ -1513,51 +1517,56 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
         extend_prestate_ann(a, pres);
 
         alt (lhs.node) {
-            case (expr_path(?p, some[def](def_local(?d_id)), ?a_lhs)) {
-                // assignment to local var
-                changed = pure_exp(a_lhs, pres) || changed;
-                changed = find_pre_post_state_expr(fm, enclosing, pres, rhs)
-                    || changed;
-                changed = extend_poststate_ann(a, expr_poststate(rhs))
-                    || changed;
-                changed = gen_poststate(enclosing, a, d_id) || changed;
-            }
-            case (_) {
-                // assignment to something that must already have been init'd
-                changed = find_pre_post_state_expr(fm, enclosing, pres, lhs)
-                    || changed;
-                changed = find_pre_post_state_expr(fm, enclosing,
-                     expr_poststate(lhs), rhs) || changed;
-                changed = extend_poststate_ann(a, expr_poststate(rhs))
-                    || changed;
+            case (expr_path(_, ?a_lhs)) {
+                alt (dm.get(ast.ann_tag(a_lhs))) {
+                    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 (_) {}
         }
-        ret changed;
+        // 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, some[def](def_local(?d_id)), ?a_lhs)) {
-                // receive to local var
-                changed = pure_exp(a_lhs, pres) || changed;
-                changed = find_pre_post_state_expr(fm, enclosing, pres, rhs)
-                    || changed;
-                changed = extend_poststate_ann(a, expr_poststate(rhs))
-                    || changed;
-                changed = gen_poststate(enclosing, a, d_id) || changed;
-            }
-            case (_) {
-                // receive to something that must already have been init'd
-                changed = find_pre_post_state_expr(fm, enclosing, pres, lhs)
-                    || changed;
-                changed = find_pre_post_state_expr(fm, enclosing,
-                     expr_poststate(lhs), rhs) || changed;
-                changed = extend_poststate_ann(a, expr_poststate(rhs))
-                    || changed;
+            case (expr_path(?p, ?a_lhs)) {
+                alt (dm.get(ast.ann_tag(a_lhs))) {
+                    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 (_) {}
         }
-        ret changed;
+        // 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)) {
@@ -1566,7 +1575,7 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
         alt(maybe_ret_val) {
             case (none[@expr]) { /* do nothing */ }
             case (some[@expr](?ret_val)) {
-                changed = find_pre_post_state_expr(fm, enclosing,
+                changed = find_pre_post_state_expr(dm, fm, enclosing,
                              pres, ret_val) || changed;
             }
         }
@@ -1575,14 +1584,15 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
     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(fm, enclosing, pres, e) || changed;
+        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(fm, enclosing, pres, antec)
+        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, antec)
             || changed;
-        changed = find_pre_post_state_block(fm, enclosing,
+        changed = find_pre_post_state_block(dm, fm, enclosing,
           expr_poststate(antec), conseq) || changed;
         alt (maybe_alt) {
             case (none[@expr]) {
@@ -1590,7 +1600,7 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
                     || changed;
             }
             case (some[@expr](?altern)) {
-                changed = find_pre_post_state_expr(fm, enclosing,
+                changed = find_pre_post_state_expr(dm, fm, enclosing,
                    expr_poststate(antec), altern) || changed;
                 auto poststate_res = intersect_postconds
                     (vec(block_poststate(conseq), expr_poststate(altern)));
@@ -1609,18 +1619,18 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
     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(fm, enclosing, pres, l)
+        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, l)
                     || changed;
-        changed = find_pre_post_state_expr(fm,
+        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(fm, enclosing, pres, l)
+        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, l)
                     || changed;
-        changed = find_pre_post_state_expr(fm,
+        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;
@@ -1628,9 +1638,9 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
     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(fm, enclosing, pres, lhs)
+        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, lhs)
                     || changed;
-        changed = find_pre_post_state_expr(fm,
+        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;
@@ -1645,9 +1655,9 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
            FIXME
            maybe need a "don't know" state in addition to 0 or 1?
         */
-        changed = find_pre_post_state_expr(fm, enclosing, pres, test)
+        changed = find_pre_post_state_expr(dm, fm, enclosing, pres, test)
             || changed;
-        changed = find_pre_post_state_block(fm, 
+        changed = find_pre_post_state_block(dm, fm, 
                    enclosing, expr_poststate(test), body) || changed; 
         changed = extend_poststate_ann(a,
                     intersect_postconds(vec(expr_poststate(test),
@@ -1656,9 +1666,9 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
     }
     case (expr_do_while(?body, ?test, ?a)) {
         changed = extend_prestate_ann(a, pres) || changed;
-        changed = find_pre_post_state_block(fm, enclosing, pres, body)
+        changed = find_pre_post_state_block(dm, fm, enclosing, pres, body)
             || changed;
-        changed = find_pre_post_state_expr(fm, enclosing,
+        changed = find_pre_post_state_expr(dm, fm, enclosing,
                      block_poststate(body), test) || changed;
 
         /* conservative approximination: if the body of the loop
@@ -1676,28 +1686,32 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
         ret changed;
     }
     case (expr_for(?d, ?index, ?body, ?a)) {
-        ret find_pre_post_state_loop(fm, enclosing, pres, 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(fm, enclosing, pres, 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(fm, enclosing, pres, e) || changed;
-        changed = find_pre_post_state_expr(fm, enclosing,
+        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(fm, enclosing, pres, e) || 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(fm, enclosing, e_post,
+                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; 
@@ -1711,13 +1725,13 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
         ret changed;
     }
     case (expr_field(?e,_,?a)) {
-        changed = find_pre_post_state_expr(fm, enclosing, pres, e);
+        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(fm, enclosing, pres, operand)
+        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))
@@ -1725,7 +1739,7 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
         ret changed;
     }
     case (expr_cast(?operand, _, ?a)) {
-           changed = find_pre_post_state_expr(fm, enclosing, pres, operand)
+          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))
@@ -1744,7 +1758,8 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
     }
     case (expr_check(?p, ?a)) {
         changed = extend_prestate_ann(a, pres) || changed;
-        changed = find_pre_post_state_expr(fm, enclosing, pres, p) || 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;
@@ -1764,7 +1779,7 @@ fn find_pre_post_state_expr(&fn_info_map fm, &fn_info enclosing,
   }
 }
 
-fn find_pre_post_state_stmt(&fn_info_map fm, &fn_info enclosing,
+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);
@@ -1788,7 +1803,7 @@ fn find_pre_post_state_stmt(&fn_info_map fm, &fn_info enclosing,
                 changed = extend_prestate(stmt_ann.states.prestate, pres)
                     || changed;
                 changed = find_pre_post_state_expr
-                    (fm, enclosing, pres, an_init.expr) || changed;
+                    (dm, fm, enclosing, pres, an_init.expr) || changed;
                 changed = extend_poststate(stmt_ann.states.poststate,
                                            expr_poststate(an_init.expr))
                     || changed;
@@ -1819,12 +1834,14 @@ fn find_pre_post_state_stmt(&fn_info_map fm, &fn_info enclosing,
                || changed;
             changed = extend_poststate(stmt_ann.states.poststate, pres)
                || changed;
-            ret (find_pre_post_state_item(fm, enclosing, an_item) || changed);
+            ret find_pre_post_state_item(dm, fm, enclosing, an_item)
+                || changed;
         }
       }
     }
     case (stmt_expr(?e, _)) {
-      changed = find_pre_post_state_expr(fm, enclosing, pres, e) || changed;
+      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,
@@ -1849,7 +1866,7 @@ fn find_pre_post_state_stmt(&fn_info_map fm, &fn_info enclosing,
 
 /* 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(&fn_info_map fm, &fn_info enclosing,
+fn find_pre_post_state_block(&def_map dm, &fn_info_map fm, &fn_info enclosing,
                              &prestate pres0, &block b)
   -> bool {
     
@@ -1863,7 +1880,7 @@ fn find_pre_post_state_block(&fn_info_map fm, &fn_info enclosing,
    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(fm, enclosing, pres, s) || changed;
+    changed = find_pre_post_state_stmt(dm, fm, enclosing, pres, s) || changed;
     pres = stmt_poststate(*s, num_local_vars);
   }
 
@@ -1872,7 +1889,8 @@ fn find_pre_post_state_block(&fn_info_map fm, &fn_info enclosing,
   alt (b.node.expr) {
     case (none[@expr]) {}
     case (some[@expr](?e)) {
-      changed = find_pre_post_state_expr(fm, enclosing, pres, e) || changed;
+      changed = find_pre_post_state_expr(dm,fm, enclosing, pres, e)
+                || changed;
       post = expr_poststate(e);
     }
   }
@@ -1907,30 +1925,15 @@ fn find_pre_post_state_block(&fn_info_map fm, &fn_info enclosing,
   ret changed;
 }
 
-fn find_pre_post_state_fn(&fn_info_map f_info, &fn_info fi, &ast._fn f)
-  -> bool {
+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(f_info, fi,
+    ret find_pre_post_state_block(dm, f_info, fi,
                                   empty_prestate(num_local_vars), f.body);
 }
 
-fn fixed_point_states(fn_info_map fm, fn_info f_info,
-                      fn (&fn_info_map, &fn_info, &ast._fn) -> bool f,
-                      &ast._fn start) -> () {
-
-  auto changed = f(fm, f_info, start);
-
-  if (changed) {
-    ret fixed_point_states(fm, f_info, f, start);
-  }
-  else {
-    // we're done!
-    ret;
-  }
-}
-
 fn check_states_expr(fn_info enclosing, @expr e) -> () {
   let precond prec    = expr_precond(e);
   let prestate pres   = expr_prestate(e);
@@ -1993,44 +1996,44 @@ fn check_states_against_conditions(fn_info enclosing, &ast._fn f) -> () {
   
 }
 
-fn check_fn_states(&fn_info_map f_info_map, &fn_info f_info, &ast._fn f)
-    -> () {
-  /* Compute the pre- and post-states for this function */
-    auto g = find_pre_post_state_fn;
-    fixed_point_states(f_info_map, f_info, g, f);
+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(&fn_info_map f_info_map, &span sp, &ident i,
-                       &ast._fn f, &vec[ast.ty_param] ty_params,
+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(f_info_map, f_info, f);
+  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(&fn_info_map f_info_map, @method m) -> () {
+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(f_info_map, f_info, m.node.meth);
+    check_fn_states(dm, f_info_map, f_info, m.node.meth);
 }
 
-fn check_obj_state(&fn_info_map f_info_map, &vec[obj_field] fields,
-                   &vec[@method] methods,
+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(fn_info_map fm, &@method m) -> () {
-        ret check_method_states(fm, m);
+    fn one(def_map dm, fn_info_map fm, &@method m) -> () {
+        ret check_method_states(dm, fm, m);
     }
-    auto f = bind one(f_info_map,_);
+    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);
@@ -2283,7 +2286,7 @@ fn annotate_expr(&fn_info_map fm, &@expr e) -> @expr {
             e1 = expr_index(annotate_expr(fm, e),
                             annotate_expr(fm, sub), a);
         }
-        case (expr_path(_,_,_)) {
+        case (expr_path(_,_)) {
             /* no change */
         }
         case (expr_ext(?p, ?es, ?s_opt, ?e, ?a)) {
@@ -2482,7 +2485,7 @@ fn annotate_crate(&fn_info_map fm, &@ast.crate crate) -> @ast.crate {
                    with crate.node));
 }
 
-fn check_crate(@ast.crate crate) -> @ast.crate {
+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);
 
@@ -2491,14 +2494,14 @@ fn check_crate(@ast.crate crate) -> @ast.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(_,_,_,_,_,_,_) with *fld);
+  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(_,_,_,_,_,_,_),
-              fold_obj     = bind check_obj_state(_,_,_,_)
+  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,
diff --git a/src/comp/middle/walk.rs b/src/comp/middle/walk.rs
index c8f5f43236e..e684924adc7 100644
--- a/src/comp/middle/walk.rs
+++ b/src/comp/middle/walk.rs
@@ -372,7 +372,7 @@ fn walk_expr(&ast_visitor v, @ast.expr e) {
             walk_expr(v, a);
             walk_expr(v, b);
         }
-        case (ast.expr_path(_, _, _)) { }
+        case (ast.expr_path(_, _)) { }
         case (ast.expr_ext(_, ?args, ?body, ?expansion, _)) {
             // Only walk expansion, not args/body.
             walk_expr(v, expansion);
diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs
index 3c417eff423..d380f0b7eea 100644
--- a/src/comp/pretty/pprust.rs
+++ b/src/comp/pretty/pprust.rs
@@ -613,7 +613,7 @@ fn print_expr(ps s, &@ast.expr expr) {
             print_expr(s, index);
             pclose(s);
         }
-        case (ast.expr_path(?path,_,_)) {
+        case (ast.expr_path(?path,_)) {
             print_path(s, path);
         }
         case (ast.expr_fail(_)) {
@@ -768,7 +768,7 @@ fn print_pat(ps s, &@ast.pat pat) {
         case (ast.pat_wild(_)) {wrd(s.s, "_");}
         case (ast.pat_bind(?id,_,_)) {wrd(s.s, "?" + id);}
         case (ast.pat_lit(?lit,_)) {print_literal(s, lit);}
-        case (ast.pat_tag(?path,?args,_,_)) {
+        case (ast.pat_tag(?path,?args,_)) {
             print_path(s, path);
             if (Vec.len[@ast.pat](args) > 0u) {
                 popen_h(s);