about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2010-10-18 18:19:16 -0700
committerGraydon Hoare <graydon@mozilla.com>2010-10-18 18:19:16 -0700
commit4a3edb320dd515fd98431997d4bdb1ffa31446bd (patch)
tree40c4741c51e070a326cbc7643657cd288260bcbb /src/comp
parent865bbae685fbf9bd1583a3f1715dd8093c0cbda2 (diff)
downloadrust-4a3edb320dd515fd98431997d4bdb1ffa31446bd.tar.gz
rust-4a3edb320dd515fd98431997d4bdb1ffa31446bd.zip
Store items and decls in vecs to preserve input order, index externally. Implement block-local name lookup.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/ast.rs24
-rw-r--r--src/comp/front/parser.rs123
-rw-r--r--src/comp/middle/fold.rs141
-rw-r--r--src/comp/middle/resolve.rs57
-rw-r--r--src/comp/middle/trans.rs15
-rw-r--r--src/comp/util/common.rs9
6 files changed, 232 insertions, 137 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index 04c64bea0b1..047bdd06bed 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -29,7 +29,8 @@ type crate = spanned[crate_];
 type crate_ = rec(_mod module);
 
 type block = spanned[block_];
-type block_ = vec[@stmt];
+type block_ = rec(vec[@stmt] stmts,
+                  hashmap[ident,uint] index);
 
 tag binop {
     add;
@@ -69,10 +70,16 @@ tag stmt_ {
     stmt_expr(@expr);
 }
 
+type local = rec(option[@ty] ty,
+                 bool infer,
+                 ident ident,
+                 option[@expr] init,
+                 def_id id);
+
 type decl = spanned[decl_];
 tag decl_ {
-    decl_local(ident, option[@ty], option[@expr]);
-    decl_item(ident, @item);
+    decl_local(local);
+    decl_item(@item);
 }
 
 type expr = spanned[expr_];
@@ -125,16 +132,17 @@ tag mode {
 
 type arg = rec(mode mode, @ty ty, ident ident, def_id id);
 type _fn = rec(vec[arg] inputs,
-               ty output,
+               @ty output,
                block body);
 
-type _mod = hashmap[ident,@item];
+type _mod = rec(vec[@item] items,
+                hashmap[ident,uint] index);
 
 type item = spanned[item_];
 tag item_ {
-    item_fn(_fn, def_id);
-    item_mod(_mod, def_id);
-    item_ty(@ty, def_id);
+    item_fn(ident, _fn, def_id);
+    item_mod(ident, _mod, def_id);
+    item_ty(ident, @ty, def_id);
 }
 
 
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index 1d07299b9a8..4aa71743e92 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -2,9 +2,11 @@ import std._io;
 import std.util.option;
 import std.util.some;
 import std.util.none;
+import std.map.hashmap;
 
 import driver.session;
 import util.common;
+import util.common.append;
 import util.common.span;
 import util.common.new_str_hash;
 
@@ -610,13 +612,38 @@ io fn parse_let(parser p) -> @ast.decl {
 
     expect(p, token.LET);
     auto ty = parse_ty(p);
-    auto id = parse_ident(p);
+    auto ident = parse_ident(p);
     auto init = parse_initializer(p);
 
     auto hi = p.get_span();
     expect(p, token.SEMI);
 
-    ret @spanned(lo, hi, ast.decl_local(id, some(ty), init));
+    let ast.local local = rec(ty = some(ty),
+                              infer = false,
+                              ident = ident,
+                              init = init,
+                              id = p.next_def_id());
+
+    ret @spanned(lo, hi, ast.decl_local(local));
+}
+
+io fn parse_auto(parser p) -> @ast.decl {
+    auto lo = p.get_span();
+
+    expect(p, token.AUTO);
+    auto ident = parse_ident(p);
+    auto init = parse_initializer(p);
+
+    auto hi = p.get_span();
+    expect(p, token.SEMI);
+
+    let ast.local local = rec(ty = none[@ast.ty],
+                              infer = true,
+                              ident = ident,
+                              init = init,
+                              id = p.next_def_id());
+
+    ret @spanned(lo, hi, ast.decl_local(local));
 }
 
 io fn parse_stmt(parser p) -> @ast.stmt {
@@ -632,20 +659,15 @@ io fn parse_stmt(parser p) -> @ast.stmt {
         }
 
         case (token.LET) {
-            auto leht = parse_let(p);
+            auto decl = parse_let(p);
             auto hi = p.get_span();
-            ret @spanned(lo, hi, ast.stmt_decl(leht));
+            ret @spanned(lo, hi, ast.stmt_decl(decl));
         }
 
         case (token.AUTO) {
-            p.bump();
-            auto id = parse_ident(p);
-            auto init = parse_initializer(p);
+            auto decl = parse_auto(p);
             auto hi = p.get_span();
-            expect(p, token.SEMI);
-
-            auto decl = ast.decl_local(id, none[@ast.ty], init);
-            ret @spanned(lo, hi, ast.stmt_decl(@spanned(lo, hi, decl)));
+            ret @spanned(lo, hi, ast.stmt_decl(decl));
         }
 
         // Handle the (few) block-expr stmts first.
@@ -677,10 +699,41 @@ io fn parse_stmt(parser p) -> @ast.stmt {
 io fn parse_block(parser p) -> ast.block {
     auto f = parse_stmt;
     // FIXME: passing parse_stmt as an lval doesn't work at the moment.
-    ret parse_seq[@ast.stmt](token.LBRACE,
-                             token.RBRACE,
-                             none[token.token],
-                             f, p);
+    auto stmts = parse_seq[@ast.stmt](token.LBRACE,
+                                      token.RBRACE,
+                                      none[token.token],
+                                      f, p);
+    auto index = new_str_hash[uint]();
+    auto u = 0u;
+    for (@ast.stmt s in stmts.node) {
+        // FIXME: typestate bug requires we do this up top, not
+        // down below loop. Sigh.
+        u += 1u;
+        alt (s.node) {
+            case (ast.stmt_decl(?d)) {
+                alt (d.node) {
+                    case (ast.decl_local(?loc)) {
+                        index.insert(loc.ident, u-1u);
+                    }
+                    case (ast.decl_item(?it)) {
+                        alt (it.node) {
+                            case (ast.item_fn(?i, _, _)) {
+                                index.insert(i, u-1u);
+                            }
+                            case (ast.item_mod(?i, _, _)) {
+                                index.insert(i, u-1u);
+                            }
+                            case (ast.item_ty(?i, _, _)) {
+                                index.insert(i, u-1u);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    let ast.block_ b = rec(stmts=stmts.node, index=index);
+    ret spanned(stmts.span, stmts.span, b);
 }
 
 io fn parse_fn(parser p) -> tup(ast.ident, @ast.item) {
@@ -697,12 +750,12 @@ io fn parse_fn(parser p) -> tup(ast.ident, @ast.item) {
          some(token.COMMA),
          pf, p);
 
-    let ast.ty output;
+    let @ast.ty output;
     if (p.peek() == token.RARROW) {
         p.bump();
-        output = *parse_ty(p);
+        output = parse_ty(p);
     } else {
-        output = spanned(lo, inputs.span, ast.ty_nil);
+        output = @spanned(lo, inputs.span, ast.ty_nil);
     }
 
     auto body = parse_block(p);
@@ -711,24 +764,33 @@ io fn parse_fn(parser p) -> tup(ast.ident, @ast.item) {
                         output = output,
                         body = body);
 
-    let @ast.item i = @spanned(lo, body.span,
-                               ast.item_fn(f, p.next_def_id()));
-    ret tup(id, i);
+    auto item = ast.item_fn(id, f, p.next_def_id());
+    ret tup(id, @spanned(lo, body.span, item));
 }
 
+io fn parse_mod_items(parser p, token.token term) -> ast._mod {
+   let vec[@ast.item] items = vec();
+    let hashmap[ast.ident,uint] index = new_str_hash[uint]();
+    let uint u = 0u;
+    while (p.peek() != term) {
+        auto pair = parse_item(p);
+        append[@ast.item](items, pair._1);
+        index.insert(pair._0, u);
+        u += 1u;
+    }
+    ret rec(items=items, index=index);
+ }
+
 io fn parse_mod(parser p) -> tup(ast.ident, @ast.item) {
     auto lo = p.get_span();
     expect(p, token.MOD);
     auto id = parse_ident(p);
     expect(p, token.LBRACE);
-    let ast._mod m = new_str_hash[@ast.item]();
-    while (p.peek() != token.RBRACE) {
-        auto i = parse_item(p);
-        m.insert(i._0, i._1);
-    }
+    auto m = parse_mod_items(p, token.RBRACE);
     auto hi = p.get_span();
     expect(p, token.RBRACE);
-    ret tup(id, @spanned(lo, hi, ast.item_mod(m, p.next_def_id())));
+    auto item = ast.item_mod(id, m, p.next_def_id());
+    ret tup(id, @spanned(lo, hi, item));
 }
 
 io fn parse_item(parser p) -> tup(ast.ident, @ast.item) {
@@ -747,12 +809,7 @@ io fn parse_item(parser p) -> tup(ast.ident, @ast.item) {
 io fn parse_crate(parser p) -> @ast.crate {
     auto lo = p.get_span();
     auto hi = lo;
-    let ast._mod m = new_str_hash[@ast.item]();
-    while (p.peek() != token.EOF) {
-        auto i = parse_item(p);
-        m.insert(i._0, i._1);
-        hi = i._1.span;
-    }
+    auto m = parse_mod_items(p, token.EOF);
     ret @spanned(lo, hi, rec(module=m));
 }
 
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs
index 53614754bb9..2ed93160024 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -7,6 +7,7 @@ import util.common.new_str_hash;
 import util.common.spanned;
 import util.common.span;
 import util.common.ty_mach;
+import util.common.append;
 
 import front.ast;
 import front.ast.ident;
@@ -20,6 +21,7 @@ import front.ast.item;
 import front.ast.arg;
 import front.ast.decl;
 import front.ast.def;
+import front.ast.def_id;
 
 import std._vec;
 
@@ -70,11 +72,11 @@ type ast_fold[ENV] =
          @ast.lit) -> @expr)                      fold_expr_lit,
 
      (fn(&ENV e, &span sp,
-         @expr cond, block thn,
+         @expr cond, &block thn,
          &option[block] els) -> @expr)            fold_expr_if,
 
      (fn(&ENV e, &span sp,
-         block blk) -> @expr)                     fold_expr_block,
+         &block blk) -> @expr)                    fold_expr_block,
 
      (fn(&ENV e, &span sp,
          @expr lhs, @expr rhs) -> @expr)          fold_expr_assign,
@@ -91,11 +93,10 @@ type ast_fold[ENV] =
 
      // Decl folds.
      (fn(&ENV e, &span sp,
-         ident ident, &option[@ty] ty,
-         &option[@expr]) -> @decl)                fold_decl_local,
+         &ast.local local) -> @decl)              fold_decl_local,
 
      (fn(&ENV e, &span sp,
-         ident ident, @item item) -> @decl)        fold_decl_item,
+         @item item) -> @decl)                    fold_decl_item,
 
 
      // Stmt folds.
@@ -112,21 +113,21 @@ type ast_fold[ENV] =
          @expr e) -> @stmt)                       fold_stmt_expr,
 
      // Item folds.
-     (fn(&ENV e, &span sp,
-         &ast._fn f, ast.def_id id) -> @item)     fold_item_fn,
+     (fn(&ENV e, &span sp, ident ident,
+         &ast._fn f, def_id id) -> @item)         fold_item_fn,
 
-     (fn(&ENV e, &span sp,
-         &ast._mod m, ast.def_id id) -> @item)    fold_item_mod,
+     (fn(&ENV e, &span sp, ident ident,
+         &ast._mod m, def_id id) -> @item)        fold_item_mod,
 
-     (fn(&ENV e, &span sp,
-         @ty t, ast.def_id id) -> @item)          fold_item_ty,
+     (fn(&ENV e, &span sp, ident ident,
+         @ty t, def_id id) -> @item)              fold_item_ty,
 
      // Additional nodes.
      (fn(&ENV e, &span sp,
-         vec[@stmt] stmts) -> block)              fold_block,
+         &ast.block_) -> block)                   fold_block,
 
      (fn(&ENV e, vec[arg] inputs,
-         &ty output, block body) -> ast._fn)      fold_fn,
+         @ty output, &block body) -> ast._fn)     fold_fn,
 
      (fn(&ENV e, &ast._mod m) -> ast._mod)        fold_mod,
 
@@ -136,7 +137,7 @@ type ast_fold[ENV] =
      // Env updates.
      (fn(&ENV e, @ast.crate c) -> ENV) update_env_for_crate,
      (fn(&ENV e, @item i) -> ENV) update_env_for_item,
-     (fn(&ENV e, block b) -> ENV) update_env_for_block,
+     (fn(&ENV e, &block b) -> ENV) update_env_for_block,
      (fn(&ENV e, @stmt s) -> ENV) update_env_for_stmt,
      (fn(&ENV e, @decl i) -> ENV) update_env_for_decl,
      (fn(&ENV e, @expr x) -> ENV) update_env_for_expr,
@@ -214,39 +215,32 @@ fn fold_decl[ENV](&ENV env, ast_fold[ENV] fld, @decl d) -> @decl {
     }
 
     alt (d.node) {
-        case (ast.decl_local(?id, ?ty_opt, ?expr_opt)) {
-            auto ty_opt_ = none[@ast.ty];
-            auto expr_opt_ = none[@ast.expr];
-            alt (ty_opt) {
+        case (ast.decl_local(?local)) {
+            auto ty_ = none[@ast.ty];
+            auto init_ = none[@ast.expr];
+            alt (local.ty) {
                 case (some[@ast.ty](?t)) {
-                    ty_opt_ = some[@ast.ty](fold_ty(env, fld, t));
+                    ty_ = some[@ast.ty](fold_ty(env, fld, t));
                 }
             }
-            alt (expr_opt) {
+            alt (local.init) {
                 case (some[@ast.expr](?e)) {
-                    expr_opt_ = some[@ast.expr](fold_expr(env, fld, e));
+                    init_ = some[@ast.expr](fold_expr(env, fld, e));
                 }
             }
-            ret fld.fold_decl_local(env_, d.span, id, ty_opt_, expr_opt_);
+            let ast.local local_ = rec(ty=ty_, init=init_ with local);
+            ret fld.fold_decl_local(env_, d.span, local_);
         }
 
-        case (ast.decl_item(?id, ?item)) {
+        case (ast.decl_item(?item)) {
             auto item_ = fold_item(env_, fld, item);
-            ret fld.fold_decl_item(env_, d.span, id, item_);
+            ret fld.fold_decl_item(env_, d.span, item_);
         }
     }
 
     fail;
 }
 
-// FIXME: Weird bug. Due to the way we auto-deref + in +=, we can't append a
-// boxed value to a vector-of-boxes using +=.  Best to figure out a way to fix
-// this. Deref-on-demand or something? It's a hazard of the ambiguity between
-// single-element and vector append.
-fn append[T](&vec[T] v, &T t) {
-    v += t;
-}
-
 fn fold_exprs[ENV](&ENV env, ast_fold[ENV] fld, vec[@expr] es) -> vec[@expr] {
     let vec[@expr] exprs = vec();
     for (@expr e in es) {
@@ -406,10 +400,10 @@ fn fold_block[ENV](&ENV env, ast_fold[ENV] fld, &block blk) -> block {
     }
 
     let vec[@ast.stmt] stmts = vec();
-    for (@ast.stmt s in blk.node) {
+    for (@ast.stmt s in blk.node.stmts) {
         append[@ast.stmt](stmts, fold_stmt[ENV](env_, fld, s));
     }
-    ret respan(blk.span, stmts);
+    ret respan(blk.span, rec(stmts=stmts with blk.node));
 }
 
 fn fold_arg[ENV](&ENV env, ast_fold[ENV] fld, &arg a) -> arg {
@@ -424,10 +418,10 @@ fn fold_fn[ENV](&ENV env, ast_fold[ENV] fld, &ast._fn f) -> ast._fn {
     for (ast.arg a in f.inputs) {
         inputs += fold_arg(env, fld, a);
     }
-    auto output = fold_ty[ENV](env, fld, @f.output);
+    auto output = fold_ty[ENV](env, fld, f.output);
     auto body = fold_block[ENV](env, fld, f.body);
 
-    ret fld.fold_fn(env, inputs, *output, body);
+    ret fld.fold_fn(env, inputs, output, body);
 }
 
 fn fold_item[ENV](&ENV env, ast_fold[ENV] fld, @item i) -> @item {
@@ -440,19 +434,19 @@ fn fold_item[ENV](&ENV env, ast_fold[ENV] fld, @item i) -> @item {
 
     alt (i.node) {
 
-        case (ast.item_fn(?ff, ?id)) {
+        case (ast.item_fn(?ident, ?ff, ?id)) {
             let ast._fn ff_ = fold_fn[ENV](env_, fld, ff);
-            ret fld.fold_item_fn(env_, i.span, ff_, id);
+            ret fld.fold_item_fn(env_, i.span, ident, ff_, id);
         }
 
-        case (ast.item_mod(?mm, ?id)) {
+        case (ast.item_mod(?ident, ?mm, ?id)) {
             let ast._mod mm_ = fold_mod[ENV](env_, fld, mm);
-            ret fld.fold_item_mod(env_, i.span, mm_, id);
+            ret fld.fold_item_mod(env_, i.span, ident, mm_, id);
         }
 
-        case (ast.item_ty(?ty, ?id)) {
+        case (ast.item_ty(?ident, ?ty, ?id)) {
             let @ast.ty ty_ = fold_ty[ENV](env_, fld, ty);
-            ret fld.fold_item_ty(env_, i.span, ty_, id);
+            ret fld.fold_item_ty(env_, i.span, ident, ty_, id);
         }
     }
 
@@ -460,16 +454,15 @@ fn fold_item[ENV](&ENV env, ast_fold[ENV] fld, @item i) -> @item {
 }
 
 
-fn fold_mod[ENV](&ENV e, ast_fold[ENV] fld, &ast._mod m_in) -> ast._mod {
+fn fold_mod[ENV](&ENV e, ast_fold[ENV] fld, &ast._mod m) -> ast._mod {
 
-    auto m_out = new_str_hash[@item]();
+    let vec[@item] items = vec();
 
-    for each (tup(ident, @item) pairs in m_in.items()) {
-        auto i = fold_item[ENV](e, fld, pairs._1);
-        m_out.insert(pairs._0, i);
+    for (@item i in m.items) {
+        append[@item](items, fold_item[ENV](e, fld, i));
     }
 
-    ret fld.fold_mod(e, m_out);
+    ret fld.fold_mod(e, rec(items=items with m));
  }
 
 fn fold_crate[ENV](&ENV env, ast_fold[ENV] fld, @ast.crate c) -> @ast.crate {
@@ -578,12 +571,12 @@ fn identity_fold_expr_lit[ENV](&ENV env, &span sp, @ast.lit lit) -> @expr {
 }
 
 fn identity_fold_expr_if[ENV](&ENV env, &span sp,
-                              @expr cond, block thn,
+                              @expr cond, &block thn,
                               &option[block] els) -> @expr {
     ret @respan(sp, ast.expr_if(cond, thn, els));
 }
 
-fn identity_fold_expr_block[ENV](&ENV env, &span sp, block blk) -> @expr {
+fn identity_fold_expr_block[ENV](&ENV env, &span sp, &block blk) -> @expr {
     ret @respan(sp, ast.expr_block(blk));
 }
 
@@ -611,14 +604,12 @@ fn identity_fold_expr_name[ENV](&ENV env, &span sp,
 // Decl identities.
 
 fn identity_fold_decl_local[ENV](&ENV e, &span sp,
-                                 ident i, &option[@ty] t,
-                                 &option[@expr] init) -> @decl {
-    ret @respan(sp, ast.decl_local(i, t, init));
+                                 &ast.local local) -> @decl {
+    ret @respan(sp, ast.decl_local(local));
 }
 
-fn identity_fold_decl_item[ENV](&ENV e, &span sp,
-                                ident id, @item i) -> @decl {
-    ret @respan(sp, ast.decl_item(id, i));
+fn identity_fold_decl_item[ENV](&ENV e, &span sp, @item i) -> @decl {
+    ret @respan(sp, ast.decl_item(i));
 }
 
 
@@ -644,32 +635,32 @@ fn identity_fold_stmt_expr[ENV](&ENV e, &span sp, @expr x) -> @stmt {
 
 // Item identities.
 
-fn identity_fold_item_fn[ENV](&ENV e, &span sp, &ast._fn f,
-                              ast.def_id id) -> @item {
-    ret @respan(sp, ast.item_fn(f, id));
+fn identity_fold_item_fn[ENV](&ENV e, &span sp, ident i,
+                              &ast._fn f, def_id id) -> @item {
+    ret @respan(sp, ast.item_fn(i, f, id));
 }
 
-fn identity_fold_item_mod[ENV](&ENV e, &span sp, &ast._mod m,
-                               ast.def_id id) -> @item {
-    ret @respan(sp, ast.item_mod(m, id));
+fn identity_fold_item_mod[ENV](&ENV e, &span sp, ident i,
+                               &ast._mod m, def_id id) -> @item {
+    ret @respan(sp, ast.item_mod(i, m, id));
 }
 
-fn identity_fold_item_ty[ENV](&ENV e, &span sp, @ty t,
-                              ast.def_id id) -> @item {
-    ret @respan(sp, ast.item_ty(t, id));
+fn identity_fold_item_ty[ENV](&ENV e, &span sp, ident i,
+                              @ty t, def_id id) -> @item {
+    ret @respan(sp, ast.item_ty(i, t, id));
 }
 
 
 // Additional identities.
 
-fn identity_fold_block[ENV](&ENV e, &span sp, vec[@stmt] stmts) -> block {
-    ret respan(sp, stmts);
+fn identity_fold_block[ENV](&ENV e, &span sp, &ast.block_ blk) -> block {
+    ret respan(sp, blk);
 }
 
 fn identity_fold_fn[ENV](&ENV e,
                          vec[arg] inputs,
-                         &ast.ty output,
-                         block body) -> ast._fn {
+                         @ast.ty output,
+                         &block body) -> ast._fn {
     ret rec(inputs=inputs, output=output, body=body);
 }
 
@@ -692,7 +683,7 @@ fn identity_update_env_for_item[ENV](&ENV e, @item i) -> ENV {
     ret e;
 }
 
-fn identity_update_env_for_block[ENV](&ENV e, block b) -> ENV {
+fn identity_update_env_for_block[ENV](&ENV e, &block b) -> ENV {
     ret e;
 }
 
@@ -751,17 +742,17 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
          fold_expr_index  = bind identity_fold_expr_index[ENV](_,_,_,_),
          fold_expr_name   = bind identity_fold_expr_name[ENV](_,_,_,_),
 
-         fold_decl_local  = bind identity_fold_decl_local[ENV](_,_,_,_,_),
-         fold_decl_item   = bind identity_fold_decl_item[ENV](_,_,_,_),
+         fold_decl_local  = bind identity_fold_decl_local[ENV](_,_,_),
+         fold_decl_item   = bind identity_fold_decl_item[ENV](_,_,_),
 
          fold_stmt_decl   = bind identity_fold_stmt_decl[ENV](_,_,_),
          fold_stmt_ret    = bind identity_fold_stmt_ret[ENV](_,_,_),
          fold_stmt_log    = bind identity_fold_stmt_log[ENV](_,_,_),
          fold_stmt_expr   = bind identity_fold_stmt_expr[ENV](_,_,_),
 
-         fold_item_fn   = bind identity_fold_item_fn[ENV](_,_,_,_),
-         fold_item_mod  = bind identity_fold_item_mod[ENV](_,_,_,_),
-         fold_item_ty   = bind identity_fold_item_ty[ENV](_,_,_,_),
+         fold_item_fn   = bind identity_fold_item_fn[ENV](_,_,_,_,_),
+         fold_item_mod  = bind identity_fold_item_mod[ENV](_,_,_,_,_),
+         fold_item_ty   = bind identity_fold_item_ty[ENV](_,_,_,_,_),
 
          fold_block = bind identity_fold_block[ENV](_,_,_),
          fold_fn = bind identity_fold_fn[ENV](_,_,_,_),
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index ded63bb5fcb..82cdf3fa3c3 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -24,18 +24,29 @@ fn lookup_name(&env e, ast.ident i) -> option[def] {
 
     log "resolving name " + i;
 
-    fn check_mod(ast.ident i, ast._mod m) -> option[def] {
-        alt (m.find(i)) {
-            case (some[@ast.item](?it)) {
-                alt (it.node) {
-                    case (ast.item_fn(_, ?id)) {
-                        ret some[def](ast.def_fn(id));
-                    }
-                    case (ast.item_mod(_, ?id)) {
-                        ret some[def](ast.def_mod(id));
+    fn found_def_item(@ast.item i) -> option[def] {
+        alt (i.node) {
+            case (ast.item_fn(_, _, ?id)) {
+                ret some[def](ast.def_fn(id));
+            }
+            case (ast.item_mod(_, _, ?id)) {
+                ret some[def](ast.def_mod(id));
+            }
+            case (ast.item_ty(_, _, ?id)) {
+                ret some[def](ast.def_ty(id));
+            }
+        }
+    }
+
+    fn found_decl_stmt(@ast.stmt s) -> option[def] {
+        alt (s.node) {
+            case (ast.stmt_decl(?d)) {
+                alt (d.node) {
+                    case (ast.decl_local(?loc)) {
+                        ret some[def](ast.def_local(loc.id));
                     }
-                    case (ast.item_ty(_, ?id)) {
-                        ret some[def](ast.def_ty(id));
+                    case (ast.decl_item(?it)) {
+                        ret found_def_item(it);
                     }
                 }
             }
@@ -43,6 +54,16 @@ fn lookup_name(&env e, ast.ident i) -> option[def] {
         ret none[def];
     }
 
+    fn check_mod(ast.ident i, ast._mod m) -> option[def] {
+        alt (m.index.find(i)) {
+            case (some[uint](?ix)) {
+                ret found_def_item(m.items.(ix));
+            }
+        }
+        ret none[def];
+    }
+
+
     fn in_scope(ast.ident i, &scope s) -> option[def] {
         alt (s) {
 
@@ -52,18 +73,26 @@ fn lookup_name(&env e, ast.ident i) -> option[def] {
 
             case (scope_item(?it)) {
                 alt (it.node) {
-                    case (ast.item_fn(?f, _)) {
+                    case (ast.item_fn(_, ?f, _)) {
                         for (ast.arg a in f.inputs) {
                             if (_str.eq(a.ident, i)) {
                                 ret some[def](ast.def_arg(a.id));
                             }
                         }
                     }
-                    case (ast.item_mod(?m, _)) {
+                    case (ast.item_mod(_, ?m, _)) {
                         ret check_mod(i, m);
                     }
                 }
             }
+
+            case (scope_block(?b)) {
+                alt (b.node.index.find(i)) {
+                    case (some[uint](?ix)) {
+                        ret found_decl_stmt(b.node.stmts.(ix));
+                    }
+                }
+            }
         }
         ret none[def];
     }
@@ -96,7 +125,7 @@ fn update_env_for_item(&env e, @ast.item i) -> env {
     ret cons[scope](scope_item(i), @e);
 }
 
-fn update_env_for_block(&env e, ast.block b) -> env {
+fn update_env_for_block(&env e, &ast.block b) -> env {
     ret cons[scope](scope_block(b), @e);
 }
 
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index a8bb23acde8..095990fa50c 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -688,7 +688,7 @@ fn trans_block_cleanups(@block_ctxt cx) -> @block_ctxt {
 fn trans_block(@block_ctxt cx, &ast.block b) -> result {
     auto bcx = cx;
 
-    for (@ast.stmt s in b.node) {
+    for (@ast.stmt s in b.node.stmts) {
         bcx = trans_stmt(bcx, *s).bcx;
     }
 
@@ -724,21 +724,22 @@ fn trans_fn(@trans_ctxt cx, &ast._fn f) {
     trans_block(new_top_block_ctxt(fcx), f.body);
 }
 
-fn trans_item(@trans_ctxt cx, &str name, &ast.item item) {
-    auto sub_cx = @rec(path=cx.path + "." + name with *cx);
+fn trans_item(@trans_ctxt cx, &ast.item item) {
     alt (item.node) {
-        case (ast.item_fn(?f, _)) {
+        case (ast.item_fn(?name, ?f, _)) {
+            auto sub_cx = @rec(path=cx.path + "." + name with *cx);
             trans_fn(sub_cx, f);
         }
-        case (ast.item_mod(?m, _)) {
+        case (ast.item_mod(?name, ?m, _)) {
+            auto sub_cx = @rec(path=cx.path + "." + name with *cx);
             trans_mod(sub_cx, m);
         }
     }
 }
 
 fn trans_mod(@trans_ctxt cx, &ast._mod m) {
-    for each (tup(str, @ast.item) pair in m.items()) {
-        trans_item(cx, pair._0, *pair._1);
+    for (@ast.item item in m.items) {
+        trans_item(cx, *item);
     }
 }
 
diff --git a/src/comp/util/common.rs b/src/comp/util/common.rs
index cbf7aadfa51..a5b77c0e793 100644
--- a/src/comp/util/common.rs
+++ b/src/comp/util/common.rs
@@ -47,6 +47,15 @@ fn istr(int i) -> str {
     ret _int.to_str(i, 10u);
 }
 
+
+// FIXME: Weird bug. Due to the way we auto-deref + in +=, we can't append a
+// boxed value to a vector-of-boxes using +=.  Best to figure out a way to fix
+// this. Deref-on-demand or something? It's a hazard of the ambiguity between
+// single-element and vector append.
+fn append[T](&vec[T] v, &T t) {
+    v += t;
+}
+
 //
 // Local Variables:
 // mode: rust