about summary refs log tree commit diff
path: root/src/comp/middle
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2011-12-22 14:50:52 -0800
committerGraydon Hoare <graydon@mozilla.com>2011-12-22 14:50:52 -0800
commitdcd771cd4815e43558210ad1fcc7d6a219afafa5 (patch)
tree2d5cf78ec849b55bb18e3ec898d76b7b0517552a /src/comp/middle
parent8b580954fe140dd45db61d719a49065c3e31de95 (diff)
parent9587c672301663d46f8d97d34bb82cd0506f8454 (diff)
Merge branch 'master' of github.com:graydon/rust
Diffstat (limited to 'src/comp/middle')
-rw-r--r--src/comp/middle/ast_map.rs6
-rw-r--r--src/comp/middle/debuginfo.rs14
-rw-r--r--src/comp/middle/freevars.rs4
-rw-r--r--src/comp/middle/kind.rs5
-rw-r--r--src/comp/middle/last_use.rs2
-rw-r--r--src/comp/middle/resolve.rs54
-rw-r--r--src/comp/middle/trans.rs66
-rw-r--r--src/comp/middle/trans_closure.rs12
-rw-r--r--src/comp/middle/trans_objects.rs22
-rw-r--r--src/comp/middle/tstate/ck.rs4
-rw-r--r--src/comp/middle/tstate/pre_post_conditions.rs20
-rw-r--r--src/comp/middle/tstate/states.rs2
-rw-r--r--src/comp/middle/typeck.rs109
13 files changed, 156 insertions, 164 deletions
diff --git a/src/comp/middle/ast_map.rs b/src/comp/middle/ast_map.rs
index a18267569a3..f1ecfb29e2a 100644
--- a/src/comp/middle/ast_map.rs
+++ b/src/comp/middle/ast_map.rs
@@ -68,13 +68,13 @@ fn map_item(cx: ctx, i: @item) {
       item_obj(ob, _, ctor_id) {
         cx.map.insert(ctor_id, node_obj_ctor(i));
         for m in ob.methods {
-            cx.map.insert(m.node.id, node_obj_method(m));
+            cx.map.insert(m.id, node_obj_method(m));
         }
       }
       item_impl(_, _, ms) {
-        for m in ms { cx.map.insert(m.node.id, node_method(m)); }
+        for m in ms { cx.map.insert(m.id, node_method(m)); }
       }
-      item_res(_, dtor_id, _, ctor_id) {
+      item_res(_, _, _, dtor_id, ctor_id) {
         cx.map.insert(ctor_id, node_res_ctor(i));
         cx.map.insert(dtor_id, node_item(i));
       }
diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs
index 957250da9fc..1ad7d743b63 100644
--- a/src/comp/middle/debuginfo.rs
+++ b/src/comp/middle/debuginfo.rs
@@ -721,23 +721,23 @@ fn create_function(fcx: @fn_ctxt) -> @metadata<subprogram_md> {
     let (ident, ret_ty, id) = alt cx.ast_map.get(fcx.id) {
       ast_map::node_item(item) {
         alt item.node {
-          ast::item_fn(f, _) | ast::item_res(f, _, _, _) {
-            (item.ident, f.decl.output, item.id)
+          ast::item_fn(decl, _, _) | ast::item_res(decl, _, _, _, _) {
+            (item.ident, decl.output, item.id)
           }
         }
       }
       ast_map::node_obj_method(method) {
-        (method.node.ident, method.node.meth.decl.output, method.node.id)
+        (method.ident, method.decl.output, method.id)
       }
       ast_map::node_res_ctor(item) {
-        alt item.node { ast::item_res(f, _, _, ctor_id) {
-          (item.ident, f.decl.output, ctor_id)
+        alt item.node { ast::item_res(decl, _, _, _, ctor_id) {
+          (item.ident, decl.output, ctor_id)
         }}
       }
       ast_map::node_expr(expr) {
         alt expr.node {
-          ast::expr_fn(f, _) {
-            (dbg_cx.names.next("fn"), f.decl.output, expr.id)
+          ast::expr_fn(decl, _, _) {
+            (dbg_cx.names.next("fn"), decl.output, expr.id)
           }
           ast::expr_fn_block(decl, _) {
             (dbg_cx.names.next("fn"), decl.output, expr.id)
diff --git a/src/comp/middle/freevars.rs b/src/comp/middle/freevars.rs
index f7688d35077..9490b9e9ac1 100644
--- a/src/comp/middle/freevars.rs
+++ b/src/comp/middle/freevars.rs
@@ -38,8 +38,8 @@ fn collect_freevars(def_map: resolve::def_map, blk: ast::blk)
     let walk_expr =
         lambda (expr: @ast::expr, &&depth: int, v: visit::vt<int>) {
             alt expr.node {
-              ast::expr_fn(f, captures) {
-                if f.proto != ast::proto_bare {
+              ast::expr_fn(decl, _, captures) {
+                if decl.proto != ast::proto_bare {
                     visit::visit_expr(expr, depth + 1, v);
                 }
               }
diff --git a/src/comp/middle/kind.rs b/src/comp/middle/kind.rs
index 5784a328d42..241ca951e24 100644
--- a/src/comp/middle/kind.rs
+++ b/src/comp/middle/kind.rs
@@ -178,8 +178,9 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
         }
       }
       expr_ternary(_, a, b) { maybe_copy(cx, a); maybe_copy(cx, b); }
-      expr_fn(_, cap_clause) { check_fn_cap_clause(cx, e.id, *cap_clause); }
-
+      expr_fn(_, _, cap_clause) {
+        check_fn_cap_clause(cx, e.id, *cap_clause);
+      }
       _ { }
     }
     visit::visit_expr(e, cx, v);
diff --git a/src/comp/middle/last_use.rs b/src/comp/middle/last_use.rs
index 7423cc70f0e..3f5454700c1 100644
--- a/src/comp/middle/last_use.rs
+++ b/src/comp/middle/last_use.rs
@@ -136,7 +136,7 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
         for arg in args {
             alt arg.node {
               //NDM--register captured as uses
-              expr_fn(_, captured) { fns += [arg]; }
+              expr_fn(_, _, captured) { fns += [arg]; }
               expr_fn_block(_, _) { fns += [arg]; }
               _ {
                 alt arg_ts[i].mode {
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index 3fb9c4a3798..68736bc744c 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -337,7 +337,7 @@ fn resolve_names(e: @env, c: @ast::crate) {
           visit_ty: bind walk_ty(e, _, _, _),
           visit_constr: bind walk_constr(e, _, _, _, _, _),
           visit_fn_proto:
-              bind visit_fn_proto_with_scope(e, _, _, _, _, _, _, _),
+              bind visit_fn_proto_with_scope(e, _, _, _, _, _, _, _, _),
           visit_fn_block:
               bind visit_fn_block_with_scope(e, _, _, _, _, _, _)
           with *visit::default_visitor()};
@@ -353,7 +353,7 @@ fn resolve_names(e: @env, c: @ast::crate) {
                          lookup_path_strict(*e, sc, exp.span, p.node,
                                             ns_value));
           }
-          ast::expr_fn(_, cap_clause) {
+          ast::expr_fn(_, _, cap_clause) {
             let rci = bind resolve_capture_item(e, sc, _);
             vec::iter(cap_clause.copies, rci);
             vec::iter(cap_clause.moves, rci);
@@ -404,8 +404,8 @@ fn visit_item_with_scope(i: @ast::item, sc: scopes, v: vt<scopes>) {
       ast::item_impl(tps, sty, methods) {
         visit::visit_ty(sty, sc, v);
         for m in methods {
-            v.visit_fn_proto(m.node.meth, tps + m.node.tps, m.span,
-                             some(m.node.ident), m.node.id, sc, v);
+            v.visit_fn_proto(m.decl, tps + m.tps, m.body, m.span,
+                             some(m.ident), m.id, sc, v);
         }
       }
       _ { visit::visit_item(i, sc, v); }
@@ -417,9 +417,9 @@ fn visit_native_item_with_scope(ni: @ast::native_item, sc: scopes,
     visit::visit_native_item(ni, cons(scope_native_item(ni), @sc), v);
 }
 
-fn visit_fn_proto_with_scope(e: @env, f: ast::_fn, tp: [ast::ty_param],
-                             sp: span, name: fn_ident, id: node_id,
-                             sc: scopes, v: vt<scopes>) {
+fn visit_fn_proto_with_scope(e: @env, decl: ast::fn_decl, tp: [ast::ty_param],
+                             body: ast::blk, sp: span, name: fn_ident,
+                             id: node_id, sc: scopes, v: vt<scopes>) {
     // is this a main fn declaration?
     alt name {
       some(nm) {
@@ -434,13 +434,13 @@ fn visit_fn_proto_with_scope(e: @env, f: ast::_fn, tp: [ast::ty_param],
 
     // here's where we need to set up the mapping
     // for f's constrs in the table.
-    for c: @ast::constr in f.decl.constraints { resolve_constr(e, c, sc, v); }
-    let scope = alt f.proto {
-      ast::proto_bare. { scope_bare_fn(f.decl, id, tp) }
-      _ { scope_fn_expr(f.decl, id, tp) }
+    for c: @ast::constr in decl.constraints { resolve_constr(e, c, sc, v); }
+    let scope = alt decl.proto {
+      ast::proto_bare. { scope_bare_fn(decl, id, tp) }
+      _ { scope_fn_expr(decl, id, tp) }
     };
 
-    visit::visit_fn_proto(f, tp, sp, name, id, cons(scope, @sc), v);
+    visit::visit_fn_proto(decl, tp, body, sp, name, id, cons(scope, @sc), v);
 }
 
 fn visit_fn_block_with_scope(_e: @env, decl: fn_decl, blk: ast::blk,
@@ -1053,9 +1053,9 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option::t<def> {
       ast::item_const(_, _) {
         if ns == ns_value { ret some(ast::def_const(local_def(i.id))); }
       }
-      ast::item_fn(f, _) {
+      ast::item_fn(decl, _, _) {
         if ns == ns_value {
-            ret some(ast::def_fn(local_def(i.id), f.decl.purity));
+            ret some(ast::def_fn(local_def(i.id), decl.purity));
         }
       }
       ast::item_mod(_) {
@@ -1067,7 +1067,7 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option::t<def> {
       ast::item_ty(_, _) {
         if ns == ns_type { ret some(ast::def_ty(local_def(i.id))); }
       }
-      ast::item_res(_, _, _, ctor_id) {
+      ast::item_res(_, _, _, _, ctor_id) {
         alt ns {
           ns_value. {
             ret some(ast::def_fn(local_def(ctor_id), ast::impure_fn));
@@ -1319,9 +1319,9 @@ fn index_mod(md: ast::_mod) -> mod_index {
     }
     for it: @ast::item in md.items {
         alt it.node {
-          ast::item_const(_, _) | ast::item_fn(_, _) | ast::item_mod(_) |
+          ast::item_const(_, _) | ast::item_fn(_, _, _) | ast::item_mod(_) |
           ast::item_native_mod(_) | ast::item_ty(_, _) |
-          ast::item_res(_, _, _, _) | ast::item_obj(_, _, _) |
+          ast::item_res(_, _, _, _, _) | ast::item_obj(_, _, _) |
           ast::item_impl(_, _, _) {
             add_to_index(index, it.ident, mie_item(it));
           }
@@ -1479,8 +1479,8 @@ fn check_item(e: @env, i: @ast::item, &&x: (), v: vt<()>) {
     }
     visit::visit_item(i, x, v);
     alt i.node {
-      ast::item_fn(f, ty_params) {
-        check_fn(*e, i.span, f);
+      ast::item_fn(decl, ty_params, _) {
+        check_fn(*e, i.span, decl);
         ensure_unique(*e, i.span, typaram_names(ty_params), ident_id,
                       "type parameter");
       }
@@ -1488,7 +1488,7 @@ fn check_item(e: @env, i: @ast::item, &&x: (), v: vt<()>) {
         fn field_name(field: ast::obj_field) -> ident { ret field.ident; }
         ensure_unique(*e, i.span, ob.fields, field_name, "object field");
         for m: @ast::method in ob.methods {
-            check_fn(*e, m.span, m.node.meth);
+            check_fn(*e, m.span, m.decl);
         }
         ensure_unique(*e, i.span, typaram_names(ty_params), ident_id,
                       "type parameter");
@@ -1568,11 +1568,11 @@ fn check_block(e: @env, b: ast::blk, &&x: (), v: vt<()>) {
                   ast::item_mod(_) | ast::item_native_mod(_) {
                     add_name(mods, it.span, it.ident);
                   }
-                  ast::item_const(_, _) | ast::item_fn(_, _) {
+                  ast::item_const(_, _) | ast::item_fn(_, _, _) {
                     add_name(values, it.span, it.ident);
                   }
                   ast::item_ty(_, _) { add_name(types, it.span, it.ident); }
-                  ast::item_res(_, _, _, _) | ast::item_obj(_, _, _) {
+                  ast::item_res(_, _, _, _, _) | ast::item_obj(_, _, _) {
                     add_name(types, it.span, it.ident);
                     add_name(values, it.span, it.ident);
                   }
@@ -1586,9 +1586,9 @@ fn check_block(e: @env, b: ast::blk, &&x: (), v: vt<()>) {
     }
 }
 
-fn check_fn(e: env, sp: span, f: ast::_fn) {
+fn check_fn(e: env, sp: span, decl: ast::fn_decl) {
     fn arg_name(a: ast::arg) -> ident { ret a.ident; }
-    ensure_unique(e, sp, f.decl.inputs, arg_name, "argument");
+    ensure_unique(e, sp, decl.inputs, arg_name, "argument");
 }
 
 fn check_expr(e: @env, ex: @ast::expr, &&x: (), v: vt<()>) {
@@ -1775,9 +1775,9 @@ fn find_impls_in_item(i: @ast::item, &impls: [@_impl],
             impls += [@{did: local_def(i.id),
                         ident: i.ident,
                         methods: vec::map(mthds, {|m|
-                            @{did: local_def(m.node.id),
-                              n_tps: vec::len(m.node.tps),
-                              ident: m.node.ident}
+                            @{did: local_def(m.id),
+                              n_tps: vec::len(m.tps),
+                              ident: m.ident}
                         })}];
         }
       }
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index b9741645231..81d848460f9 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -3554,17 +3554,16 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
         assert op != ast::deref; // lvals are handled above
         ret trans_unary(bcx, op, x, e.id, dest);
       }
-      ast::expr_fn(f, cap_clause) {
+      ast::expr_fn(decl, body, cap_clause) {
         ret trans_closure::trans_expr_fn(
-            bcx, f, e.span, e.id, *cap_clause, dest);
+            bcx, decl, body, e.span, e.id, *cap_clause, dest);
       }
       ast::expr_fn_block(decl, body) {
         alt ty::struct(tcx, ty::expr_ty(tcx, e)) {
           ty::ty_fn(proto, _, _, _, _) {
-            let f: ast::_fn = { decl: decl, proto: proto, body: body };
             let cap_clause = { copies: [], moves: [] };
             ret trans_closure::trans_expr_fn(
-                bcx, f, e.span, e.id, cap_clause, dest);
+                bcx, decl, body, e.span, e.id, cap_clause, dest);
           }
           _ {
             fail "Type of fn block is not a function!";
@@ -4516,14 +4515,15 @@ tag self_arg { obj_self(ty::t); impl_self(ty::t); no_self; }
 // trans_closure: Builds an LLVM function out of a source function.
 // If the function closes over its environment a closure will be
 // returned.
-fn trans_closure(cx: @local_ctxt, sp: span, f: ast::_fn, llfndecl: ValueRef,
+fn trans_closure(cx: @local_ctxt, sp: span, decl: ast::fn_decl,
+                 body: ast::blk, llfndecl: ValueRef,
                  ty_self: self_arg, ty_params: [ast::ty_param],
                  id: ast::node_id, maybe_load_env: block(@fn_ctxt)) {
     set_uwtable(llfndecl);
 
     // Set up arguments to the function.
-    let fcx = new_fn_ctxt_w_id(cx, sp, llfndecl, id, f.decl.cf);
-    create_llargs_for_fn_args(fcx, ty_self, f.decl.inputs, ty_params);
+    let fcx = new_fn_ctxt_w_id(cx, sp, llfndecl, id, decl.cf);
+    create_llargs_for_fn_args(fcx, ty_self, decl.inputs, ty_params);
     alt ty_self {
       obj_self(_) {
           populate_fn_ctxt_from_llself(fcx, option::get(fcx.llself));
@@ -4535,10 +4535,10 @@ fn trans_closure(cx: @local_ctxt, sp: span, f: ast::_fn, llfndecl: ValueRef,
     //  pass to finish_fn later.
     let bcx = new_top_block_ctxt(fcx);
     let lltop = bcx.llbb;
-    let block_ty = node_id_type(cx.ccx, f.body.node.id);
+    let block_ty = node_id_type(cx.ccx, body.node.id);
 
     let arg_tys = arg_tys_of_fn(fcx.lcx.ccx, id);
-    bcx = copy_args_to_allocas(fcx, bcx, f.decl.inputs, arg_tys);
+    bcx = copy_args_to_allocas(fcx, bcx, decl.inputs, arg_tys);
 
     maybe_load_env(fcx);
 
@@ -4548,14 +4548,14 @@ fn trans_closure(cx: @local_ctxt, sp: span, f: ast::_fn, llfndecl: ValueRef,
     // (trans_block, trans_expr, et cetera).
     if ty::type_is_bot(cx.ccx.tcx, block_ty) ||
        ty::type_is_nil(cx.ccx.tcx, block_ty) ||
-       option::is_none(f.body.node.expr) {
-        bcx = trans_block_dps(bcx, f.body, ignore);
+       option::is_none(body.node.expr) {
+        bcx = trans_block_dps(bcx, body, ignore);
     } else if ty::type_is_immediate(cx.ccx.tcx, block_ty) {
         let cell = empty_dest_cell();
-        bcx = trans_block_dps(bcx, f.body, by_val(cell));
+        bcx = trans_block_dps(bcx, body, by_val(cell));
         Store(bcx, *cell, fcx.llretptr);
     } else {
-        bcx = trans_block_dps(bcx, f.body, save_in(fcx.llretptr));
+        bcx = trans_block_dps(bcx, body, save_in(fcx.llretptr));
     }
 
     // FIXME: until LLVM has a unit type, we are moving around
@@ -4567,13 +4567,13 @@ fn trans_closure(cx: @local_ctxt, sp: span, f: ast::_fn, llfndecl: ValueRef,
 
 // trans_fn: creates an LLVM function corresponding to a source language
 // function.
-fn trans_fn(cx: @local_ctxt, sp: span, f: ast::_fn, llfndecl: ValueRef,
-            ty_self: self_arg, ty_params: [ast::ty_param],
+fn trans_fn(cx: @local_ctxt, sp: span, decl: ast::fn_decl, body: ast::blk,
+            llfndecl: ValueRef, ty_self: self_arg, ty_params: [ast::ty_param],
             id: ast::node_id) {
     let do_time = cx.ccx.sess.get_opts().stats;
     let start = do_time ? time::get_time() : {sec: 0u32, usec: 0u32};
     let fcx = option::none;
-    trans_closure(cx, sp, f, llfndecl, ty_self, ty_params, id,
+    trans_closure(cx, sp, decl, body, llfndecl, ty_self, ty_params, id,
                   {|new_fcx| fcx = option::some(new_fcx);});
     if cx.ccx.sess.get_opts().extra_debuginfo {
         debuginfo::create_function(option::get(fcx));
@@ -4584,7 +4584,7 @@ fn trans_fn(cx: @local_ctxt, sp: span, f: ast::_fn, llfndecl: ValueRef,
     }
 }
 
-fn trans_res_ctor(cx: @local_ctxt, sp: span, dtor: ast::_fn,
+fn trans_res_ctor(cx: @local_ctxt, sp: span, dtor: ast::fn_decl,
                   ctor_id: ast::node_id, ty_params: [ast::ty_param]) {
     let ccx = cx.ccx;
 
@@ -4596,12 +4596,12 @@ fn trans_res_ctor(cx: @local_ctxt, sp: span, dtor: ast::_fn,
     }
     let fcx = new_fn_ctxt(cx, sp, llctor_decl);
     let ret_t = ty::ret_ty_of_fn(cx.ccx.tcx, ctor_id);
-    create_llargs_for_fn_args(fcx, no_self, dtor.decl.inputs, ty_params);
+    create_llargs_for_fn_args(fcx, no_self, dtor.inputs, ty_params);
     let bcx = new_top_block_ctxt(fcx);
     let lltop = bcx.llbb;
     let arg_t = arg_tys_of_fn(ccx, ctor_id)[0].ty;
     let tup_t = ty::mk_tup(ccx.tcx, [ty::mk_int(ccx.tcx), arg_t]);
-    let arg = alt fcx.llargs.find(dtor.decl.inputs[0].id) {
+    let arg = alt fcx.llargs.find(dtor.inputs[0].id) {
       some(local_mem(x)) { x }
     };
     let llretptr = fcx.llretptr;
@@ -4706,11 +4706,11 @@ fn trans_impl(cx: @local_ctxt, name: ast::ident, methods: [@ast::method],
               id: ast::node_id, tps: [ast::ty_param]) {
     let sub_cx = extend_path(cx, name);
     for m in methods {
-        alt cx.ccx.item_ids.find(m.node.id) {
+        alt cx.ccx.item_ids.find(m.id) {
           some(llfn) {
-            trans_fn(extend_path(sub_cx, m.node.ident), m.span, m.node.meth,
+            trans_fn(extend_path(sub_cx, m.ident), m.span, m.decl, m.body,
                      llfn, impl_self(ty::node_id_to_monotype(cx.ccx.tcx, id)),
-                     tps + m.node.tps, m.node.id);
+                     tps + m.tps, m.id);
           }
         }
     }
@@ -4996,11 +4996,12 @@ fn trans_native_mod(lcx: @local_ctxt, native_mod: ast::native_mod,
 
 fn trans_item(cx: @local_ctxt, item: ast::item) {
     alt item.node {
-      ast::item_fn(f, tps) {
+      ast::item_fn(decl, tps, body) {
         let sub_cx = extend_path(cx, item.ident);
         alt cx.ccx.item_ids.find(item.id) {
           some(llfndecl) {
-            trans_fn(sub_cx, item.span, f, llfndecl, no_self, tps, item.id);
+            trans_fn(sub_cx, item.span, decl, body, llfndecl, no_self, tps,
+                     item.id);
           }
           _ {
             cx.ccx.sess.span_fatal(item.span,
@@ -5017,13 +5018,14 @@ fn trans_item(cx: @local_ctxt, item: ast::item) {
       ast::item_impl(tps, _, ms) {
         trans_impl(cx, item.ident, ms, item.id, tps);
       }
-      ast::item_res(dtor, dtor_id, tps, ctor_id) {
-        trans_res_ctor(cx, item.span, dtor, ctor_id, tps);
+      ast::item_res(decl, tps, body, dtor_id, ctor_id) {
+        trans_res_ctor(cx, item.span, decl, ctor_id, tps);
 
         // Create a function for the destructor
         alt cx.ccx.item_ids.find(item.id) {
           some(lldtor_decl) {
-            trans_fn(cx, item.span, dtor, lldtor_decl, no_self, tps, dtor_id);
+            trans_fn(cx, item.span, decl, body, lldtor_decl, no_self,
+                     tps, dtor_id);
           }
           _ {
             cx.ccx.sess.span_fatal(item.span, "unbound dtor in trans_item");
@@ -5329,7 +5331,7 @@ fn collect_item_2(ccx: @crate_ctxt, i: @ast::item, &&pt: [str],
     let new_pt = pt + [i.ident];
     visit::visit_item(i, new_pt, v);
     alt i.node {
-      ast::item_fn(f, tps) {
+      ast::item_fn(_, tps, _) {
         if !ccx.obj_methods.contains_key(i.id) {
             register_fn(ccx, i.span, new_pt, "fn", tps, i.id);
         }
@@ -5337,17 +5339,17 @@ fn collect_item_2(ccx: @crate_ctxt, i: @ast::item, &&pt: [str],
       ast::item_obj(ob, tps, ctor_id) {
         register_fn(ccx, i.span, new_pt, "obj_ctor", tps, ctor_id);
         for m: @ast::method in ob.methods {
-            ccx.obj_methods.insert(m.node.id, ());
+            ccx.obj_methods.insert(m.id, ());
         }
       }
       ast::item_impl(tps, _, methods) {
         let name = ccx.names.next(i.ident);
         for m in methods {
-            register_fn(ccx, i.span, pt + [name, m.node.ident],
-                        "impl_method", tps + m.node.tps, m.node.id);
+            register_fn(ccx, i.span, pt + [name, m.ident],
+                        "impl_method", tps + m.tps, m.id);
         }
       }
-      ast::item_res(_, dtor_id, tps, ctor_id) {
+      ast::item_res(_, tps, _, dtor_id, ctor_id) {
         register_fn(ccx, i.span, new_pt, "res_ctor", tps, ctor_id);
         // Note that the destructor is associated with the item's id, not
         // the dtor_id. This is a bit counter-intuitive, but simplifies
diff --git a/src/comp/middle/trans_closure.rs b/src/comp/middle/trans_closure.rs
index c61c7a4ff93..72315130022 100644
--- a/src/comp/middle/trans_closure.rs
+++ b/src/comp/middle/trans_closure.rs
@@ -372,7 +372,8 @@ fn load_environment(enclosing_cx: @block_ctxt,
 }
 
 fn trans_expr_fn(bcx: @block_ctxt,
-                 f: ast::_fn,
+                 decl: ast::fn_decl,
+                 body: ast::blk,
                  sp: span,
                  id: ast::node_id,
                  cap_clause: ast::capture_clause,
@@ -389,21 +390,22 @@ fn trans_expr_fn(bcx: @block_ctxt,
 
     let trans_closure_env = lambda(ck: ty::closure_kind) -> ValueRef {
         let cap_vars = capture::compute_capture_vars(
-            ccx.tcx, id, f.proto, cap_clause);
+            ccx.tcx, id, decl.proto, cap_clause);
         let {llbox, box_ty, bcx} = build_closure(bcx, cap_vars, ck);
-        trans_closure(sub_cx, sp, f, llfn, no_self, [], id, {|fcx|
+        trans_closure(sub_cx, sp, decl, body, llfn, no_self, [], id, {|fcx|
             load_environment(bcx, fcx, box_ty, cap_vars, ck);
         });
         llbox
     };
 
-    let closure = alt f.proto {
+    let closure = alt decl.proto {
       ast::proto_block. { trans_closure_env(ty::closure_block) }
       ast::proto_shared(_) { trans_closure_env(ty::closure_shared) }
       ast::proto_send. { trans_closure_env(ty::closure_send) }
       ast::proto_bare. {
         let closure = C_null(T_opaque_boxed_closure_ptr(ccx));
-        trans_closure(sub_cx, sp, f, llfn, no_self, [], id, {|_fcx|});
+        trans_closure(sub_cx, sp, decl, body, llfn, no_self, [],
+                      id, {|_fcx|});
         closure
       }
     };
diff --git a/src/comp/middle/trans_objects.rs b/src/comp/middle/trans_objects.rs
index b8c80da9ac7..963ec8e67b2 100644
--- a/src/comp/middle/trans_objects.rs
+++ b/src/comp/middle/trans_objects.rs
@@ -386,7 +386,7 @@ tag vtbl_mthd {
 
 // Alphabetize ast::methods by ident.  A helper for create_vtbl.
 fn ast_mthd_lteq(&&a: @ast::method, &&b: @ast::method) -> bool {
-    ret str::lteq(a.node.ident, b.node.ident);
+    ret str::lteq(a.ident, b.ident);
 }
 
 // Alphabetize vtbl_mthds by ident.  A helper for create_vtbl.
@@ -394,13 +394,13 @@ fn vtbl_mthd_lteq(a: vtbl_mthd, b: vtbl_mthd) -> bool {
     alt a {
       normal_mthd(ma) {
         alt b {
-          normal_mthd(mb) { ret str::lteq(ma.node.ident, mb.node.ident); }
-          fwding_mthd(mb) { ret str::lteq(ma.node.ident, mb.ident); }
+          normal_mthd(mb) { ret str::lteq(ma.ident, mb.ident); }
+          fwding_mthd(mb) { ret str::lteq(ma.ident, mb.ident); }
         }
       }
       fwding_mthd(ma) {
         alt b {
-          normal_mthd(mb) { ret str::lteq(ma.ident, mb.node.ident); }
+          normal_mthd(mb) { ret str::lteq(ma.ident, mb.ident); }
           fwding_mthd(mb) { ret str::lteq(ma.ident, mb.ident); }
         }
       }
@@ -420,7 +420,7 @@ fn filtering_fn(cx: @local_ctxt, m: vtbl_mthd, addtl_meths: [@ast::method]) ->
     alt m {
       fwding_mthd(fm) {
         for am: @ast::method in addtl_meths {
-            if str::eq(am.node.ident, fm.ident) { ret none; }
+            if str::eq(am.ident, fm.ident) { ret none; }
         }
         ret some(fwding_mthd(fm));
       }
@@ -876,7 +876,7 @@ fn process_normal_mthd(cx: @local_ctxt, m: @ast::method, self_ty: ty::t,
 
     let llfnty = T_nil();
     let ccx = cx.ccx;
-    alt ty::struct(cx.ccx.tcx, node_id_type(cx.ccx, m.node.id)) {
+    alt ty::struct(cx.ccx.tcx, node_id_type(cx.ccx, m.id)) {
       ty::ty_fn(_, inputs, output, rs, _) {
         check non_ty_var(ccx, output);
         llfnty = type_of_fn(ccx, m.span, true, inputs, output,
@@ -884,17 +884,17 @@ fn process_normal_mthd(cx: @local_ctxt, m: @ast::method, self_ty: ty::t,
       }
     }
     let mcx: @local_ctxt =
-        @{path: cx.path + ["method", m.node.ident] with *cx};
+        @{path: cx.path + ["method", m.ident] with *cx};
     let s: str = mangle_internal_name_by_path(mcx.ccx, mcx.path);
     let llfn: ValueRef = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
 
     // Every method on an object gets its node_id inserted into the crate-wide
     // item_ids map, together with the ValueRef that points to where that
     // method's definition will be in the executable.
-    ccx.item_ids.insert(m.node.id, llfn);
-    ccx.item_symbols.insert(m.node.id, s);
-    trans_fn(mcx, m.span, m.node.meth, llfn, obj_self(self_ty), ty_params,
-             m.node.id);
+    ccx.item_ids.insert(m.id, llfn);
+    ccx.item_symbols.insert(m.id, s);
+    trans_fn(mcx, m.span, m.decl, m.body, llfn, obj_self(self_ty), ty_params,
+             m.id);
 
     ret llfn;
 }
diff --git a/src/comp/middle/tstate/ck.rs b/src/comp/middle/tstate/ck.rs
index ea5d666f0f0..058b68fc928 100644
--- a/src/comp/middle/tstate/ck.rs
+++ b/src/comp/middle/tstate/ck.rs
@@ -1,8 +1,6 @@
 
 import syntax::ast;
-import ast::{_fn, stmt,
-             fn_ident, node_id, crate, return_val, noreturn,
-             expr};
+import ast::{stmt, fn_ident, node_id, crate, return_val, noreturn, expr};
 import syntax::{visit, print};
 import syntax::codemap::span;
 import middle::ty::{type_is_nil, ret_ty_of_fn};
diff --git a/src/comp/middle/tstate/pre_post_conditions.rs b/src/comp/middle/tstate/pre_post_conditions.rs
index db2c6a7d9ba..6ac6daaa3fc 100644
--- a/src/comp/middle/tstate/pre_post_conditions.rs
+++ b/src/comp/middle/tstate/pre_post_conditions.rs
@@ -27,13 +27,13 @@ fn find_pre_post_native_mod(_m: native_mod) -> native_mod {
 }
 
 fn find_pre_post_method(ccx: crate_ctxt, m: @method) {
-    assert (ccx.fm.contains_key(m.node.id));
+    assert (ccx.fm.contains_key(m.id));
     let fcx: fn_ctxt =
-        {enclosing: ccx.fm.get(m.node.id),
-         id: m.node.id,
-         name: m.node.ident,
+        {enclosing: ccx.fm.get(m.id),
+         id: m.id,
+         name: m.ident,
          ccx: ccx};
-    find_pre_post_fn(fcx, m.node.meth.body);
+    find_pre_post_fn(fcx, m.body);
 }
 
 fn find_pre_post_item(ccx: crate_ctxt, i: item) {
@@ -56,23 +56,23 @@ fn find_pre_post_item(ccx: crate_ctxt, i: item) {
              ccx: ccx};
         find_pre_post_expr(fake_fcx, e);
       }
-      item_fn(f, _) {
+      item_fn(_, _, body) {
         assert (ccx.fm.contains_key(i.id));
         let fcx =
             {enclosing: ccx.fm.get(i.id), id: i.id, name: i.ident, ccx: ccx};
-        find_pre_post_fn(fcx, f.body);
+        find_pre_post_fn(fcx, body);
       }
       item_mod(m) { find_pre_post_mod(m); }
       item_native_mod(nm) { find_pre_post_native_mod(nm); }
       item_ty(_, _) { ret; }
       item_tag(_, _) { ret; }
-      item_res(dtor, dtor_id, _, _) {
+      item_res(_, _, body, dtor_id, _) {
         let fcx =
             {enclosing: ccx.fm.get(dtor_id),
              id: dtor_id,
              name: i.ident,
              ccx: ccx};
-        find_pre_post_fn(fcx, dtor.body);
+        find_pre_post_fn(fcx, body);
       }
       item_obj(o, _, _) {for m in o.methods { find_pre_post_method(ccx, m); }}
       item_impl(_, _, ms) { for m in ms { find_pre_post_method(ccx, m); } }
@@ -347,7 +347,7 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) {
       expr_log(_, lvl, arg) {
         find_pre_post_exprs(fcx, [lvl, arg], e.id);
       }
-      expr_fn(f, cap_clause) {
+      expr_fn(_, _, cap_clause) {
         find_pre_post_expr_fn_upvars(fcx, e);
 
         let use_cap_item = lambda(&&cap_item: @capture_item) {
diff --git a/src/comp/middle/tstate/states.rs b/src/comp/middle/tstate/states.rs
index a0f264e921a..e1f802954d1 100644
--- a/src/comp/middle/tstate/states.rs
+++ b/src/comp/middle/tstate/states.rs
@@ -371,7 +371,7 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool {
       }
       expr_mac(_) { fcx.ccx.tcx.sess.bug("unexpanded macro"); }
       expr_lit(l) { ret pure_exp(fcx.ccx, e.id, pres); }
-      expr_fn(_, cap_clause) {
+      expr_fn(_, _, cap_clause) {
         ret find_pre_post_state_cap_clause(fcx, e.id, pres, *cap_clause);
       }
       expr_fn_block(_, _) { ret pure_exp(fcx.ccx, e.id, pres); }
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index f9faa39dbf6..22b55e7994e 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -256,10 +256,10 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
           }
         }
     }
-    fn ast_arg_to_arg(tcx: ty::ctxt, mode: mode, arg: ast::ty_arg)
+    fn ast_arg_to_arg(tcx: ty::ctxt, mode: mode, arg: ast::arg)
         -> {mode: ty::mode, ty: ty::t} {
-        let ty = ast_ty_to_ty(tcx, mode, arg.node.ty);
-        ret {mode: default_arg_mode_for_ty(tcx, arg.node.mode, ty), ty: ty};
+        let ty = ast_ty_to_ty(tcx, mode, arg.ty);
+        ret {mode: default_arg_mode_for_ty(tcx, arg.mode, ty), ty: ty};
     }
     alt tcx.ast_ty_to_ty_cache.find(ast_ty) {
       some(some(ty)) { ret ty; }
@@ -333,18 +333,8 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
         }
         typ = ty::mk_rec(tcx, flds);
       }
-      ast::ty_fn(proto, inputs, output, cf, constrs) {
-        let i = [];
-        for ta: ast::ty_arg in inputs {
-            i += [ast_arg_to_arg(tcx, mode, ta)];
-        }
-        let out_ty = ast_ty_to_ty(tcx, mode, output);
-
-        let out_constrs = [];
-        for constr: @ast::constr in constrs {
-            out_constrs += [ty::ast_constr_to_constr(tcx, constr)];
-        }
-        typ = ty::mk_fn(tcx, proto, i, out_ty, cf, out_constrs);
+      ast::ty_fn(decl) {
+        typ = ty_of_fn_decl(tcx, mode, decl);
       }
       ast::ty_path(path, id) {
         alt tcx.def_map.find(id) {
@@ -366,7 +356,7 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
         let tmeths: [ty::method] = [];
         for m: ast::ty_method in meths {
             let ins = [];
-            for ta: ast::ty_arg in m.node.inputs {
+            for ta: ast::arg in m.node.inputs {
                 ins += [ast_arg_to_arg(tcx, mode, ta)];
             }
             let out = ast_ty_to_ty(tcx, mode, m.node.output);
@@ -414,9 +404,8 @@ fn ty_of_item(tcx: ty::ctxt, mode: mode, it: @ast::item)
         tcx.tcache.insert(local_def(it.id), tpt);
         ret tpt;
       }
-      ast::item_fn(fn_info, tps) {
-        ret ty_of_fn_decl(tcx, mode, fn_info.decl, fn_info.proto,
-                          tps, some(local_def(it.id)));
+      ast::item_fn(decl, tps, _) {
+        ret ty_of_fn(tcx, mode, decl, tps, local_def(it.id));
       }
       ast::item_obj(ob, tps, _) {
         let t_obj = ty_of_obj(tcx, mode, it.ident, ob, tps);
@@ -435,8 +424,8 @@ fn ty_of_item(tcx: ty::ctxt, mode: mode, it: @ast::item)
         tcx.tcache.insert(local_def(it.id), tpt);
         ret tpt;
       }
-      ast::item_res(f, _, tps, _) {
-        let t_arg = ty_of_arg(tcx, mode, f.decl.inputs[0]);
+      ast::item_res(decl, tps, _, _, _) {
+        let t_arg = ty_of_arg(tcx, mode, decl.inputs[0]);
         let t = ty::mk_named(tcx, ty::mk_res(tcx, local_def(it.id), t_arg.ty,
                                              mk_ty_params(tcx, tps)),
                              @it.ident);
@@ -480,9 +469,7 @@ fn ty_of_arg(tcx: ty::ctxt, mode: mode, a: ast::arg) -> ty::arg {
     let ty = ast_ty_to_ty(tcx, mode, a.ty);
     {mode: default_arg_mode_for_ty(tcx, a.mode, ty), ty: ty}
 }
-fn ty_of_fn_decl(tcx: ty::ctxt, mode: mode, decl: ast::fn_decl,
-           proto: ast::proto, ty_params: [ast::ty_param],
-           def_id: option::t<ast::def_id>) -> ty::ty_param_kinds_and_ty {
+fn ty_of_fn_decl(tcx: ty::ctxt, mode: mode, decl: ast::fn_decl) -> ty::t {
     let input_tys = [];
     for a: ast::arg in decl.inputs { input_tys += [ty_of_arg(tcx, mode, a)]; }
     let output_ty = ast_ty_to_ty(tcx, mode, decl.output);
@@ -491,10 +478,14 @@ fn ty_of_fn_decl(tcx: ty::ctxt, mode: mode, decl: ast::fn_decl,
     for constr: @ast::constr in decl.constraints {
         out_constrs += [ty::ast_constr_to_constr(tcx, constr)];
     }
-    let t_fn = ty::mk_fn(tcx, proto, input_tys, output_ty,
-                         decl.cf, out_constrs);
-    let tpt = {kinds: ty_param_kinds(ty_params), ty: t_fn};
-    alt def_id { some(did) { tcx.tcache.insert(did, tpt); } _ { } }
+    ty::mk_fn(tcx, decl.proto, input_tys, output_ty, decl.cf, out_constrs)
+}
+fn ty_of_fn(tcx: ty::ctxt, mode: mode, decl: ast::fn_decl,
+            ty_params: [ast::ty_param], def_id: ast::def_id)
+    -> ty::ty_param_kinds_and_ty {
+    let tpt = {kinds: ty_param_kinds(ty_params),
+               ty: ty_of_fn_decl(tcx, mode, decl)};
+    tcx.tcache.insert(def_id, tpt);
     ret tpt;
 }
 fn ty_of_native_fn_decl(tcx: ty::ctxt, mode: mode, decl: ast::fn_decl,
@@ -510,19 +501,19 @@ fn ty_of_native_fn_decl(tcx: ty::ctxt, mode: mode, decl: ast::fn_decl,
     ret tpt;
 }
 fn ty_of_method(tcx: ty::ctxt, mode: mode, m: @ast::method) -> ty::method {
-    let inputs = vec::map(m.node.meth.decl.inputs,
+    let inputs = vec::map(m.decl.inputs,
                           {|i| ty_of_arg(tcx, mode, i)});
-    let output = ast_ty_to_ty(tcx, mode, m.node.meth.decl.output);
+    let output = ast_ty_to_ty(tcx, mode, m.decl.output);
 
     let out_constrs = [];
-    for constr: @ast::constr in m.node.meth.decl.constraints {
+    for constr: @ast::constr in m.decl.constraints {
         out_constrs += [ty::ast_constr_to_constr(tcx, constr)];
     }
-    ret {proto: m.node.meth.proto,
-         ident: m.node.ident,
+    ret {proto: m.decl.proto,
+         ident: m.ident,
          inputs: inputs,
          output: output,
-         cf: m.node.meth.decl.cf,
+         cf: m.decl.cf,
          constrs: out_constrs};
 }
 fn ty_of_obj(tcx: ty::ctxt, mode: mode, id: ast::ident, ob: ast::_obj,
@@ -691,10 +682,10 @@ mod collect {
             for m in ms {
                 let ty = ty::method_ty_to_fn_ty(
                     cx.tcx, ty_of_method(cx.tcx, m_collect, m));
-                cx.tcx.tcache.insert(local_def(m.node.id),
-                                     {kinds: ty_param_kinds(m.node.tps),
+                cx.tcx.tcache.insert(local_def(m.id),
+                                     {kinds: ty_param_kinds(m.tps),
                                       ty: ty});
-                write::ty_only(cx.tcx, m.node.id, ty);
+                write::ty_only(cx.tcx, m.id, ty);
             }
             write::ty_only(cx.tcx, it.id, ast_ty_to_ty(cx.tcx, m_collect,
                                                        selfty));
@@ -714,7 +705,7 @@ mod collect {
             let method_types = ty_of_obj_methods(cx.tcx, m_collect, object);
             let i = 0u;
             for m in object.methods {
-                write::ty_only(cx.tcx, m.node.id,
+                write::ty_only(cx.tcx, m.id,
                                ty::method_ty_to_fn_ty(cx.tcx,
                                                       method_types[i]));
                 i += 1u;
@@ -731,8 +722,8 @@ mod collect {
                 i += 1u;
             }
           }
-          ast::item_res(f, dtor_id, tps, ctor_id) {
-            let t_arg = ty_of_arg(cx.tcx, m_collect, f.decl.inputs[0]);
+          ast::item_res(decl, tps, _, dtor_id, ctor_id) {
+            let t_arg = ty_of_arg(cx.tcx, m_collect, decl.inputs[0]);
             let t_res =
                 ty::mk_res(cx.tcx, local_def(it.id), t_arg.ty,
                            mk_ty_params(cx.tcx, tps));
@@ -1000,7 +991,7 @@ mod writeback {
         if !wbcx.success { ret; }
         resolve_type_vars_for_node(wbcx, e.span, e.id);
         alt e.node {
-          ast::expr_fn({decl: decl, _}, _) |
+          ast::expr_fn(decl, _, _) |
           ast::expr_fn_block(decl, _) {
             for input in decl.inputs {
                 resolve_type_vars_for_node(wbcx, e.span, input.id);
@@ -1504,14 +1495,12 @@ fn lookup_method(fcx: @fn_ctxt, isc: resolve::iscopes,
 fn check_expr_fn_with_unifier(fcx: @fn_ctxt,
                               expr: @ast::expr,
                               decl: ast::fn_decl,
-                              proto: ast::proto,
                               body: ast::blk,
                               unify: unifier,
                               expected: ty::t) {
     let tcx = fcx.ccx.tcx;
 
-    let fty = ty_of_fn_decl(tcx, m_check_tyvar(fcx), decl,
-                            proto, [], none).ty;
+    let fty = ty_of_fn_decl(tcx, m_check_tyvar(fcx), decl);
 
     log #fmt("check_expr_fn_with_unifier %s fty=%s",
              expr_to_str(expr),
@@ -1525,7 +1514,7 @@ fn check_expr_fn_with_unifier(fcx: @fn_ctxt,
     // record projection work on type inferred arguments.
     unify(fcx, expr.span, expected, fty);
 
-    check_fn1(fcx.ccx, decl, proto, body, expr.id, some(fcx));
+    check_fn1(fcx.ccx, decl, body, expr.id, some(fcx));
 }
 
 fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
@@ -1960,11 +1949,10 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
         if !arm_non_bot { result_ty = ty::mk_bot(tcx); }
         write::ty_only_fixup(fcx, id, result_ty);
       }
-      ast::expr_fn(f, captures) {
-        check_expr_fn_with_unifier(fcx, expr, f.decl,
-                                   f.proto, f.body,
+      ast::expr_fn(decl, body, captures) {
+        check_expr_fn_with_unifier(fcx, expr, decl, body,
                                    unify, expected);
-        capture::check_capture_clause(tcx, expr.id, f.proto, *captures);
+        capture::check_capture_clause(tcx, expr.id, decl.proto, *captures);
       }
       ast::expr_fn_block(decl, body) {
         // Take the prototype from the expected type, but default to block:
@@ -1980,8 +1968,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
         log #fmt("checking expr_fn_block %s expected=%s",
                  expr_to_str(expr),
                  ty_to_str(tcx, expected));
-        check_expr_fn_with_unifier(fcx, expr, decl,
-                                   proto, body,
+        check_expr_fn_with_unifier(fcx, expr, {proto: proto with decl}, body,
                                    unify, expected);
         write::ty_only_fixup(fcx, id, expected);
       }
@@ -2322,7 +2309,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
                option::t<ty::method> {
 
                 for om: @ast::method in outer_obj_methods {
-                    if str::eq(om.node.ident, m.ident) {
+                    if str::eq(om.ident, m.ident) {
                         // We'd better be overriding with one of the same
                         // type.  Check to make sure.
                         let new_type = ty_of_method(ccx.tcx, m_check, om);
@@ -2351,7 +2338,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
         // collect::convert for regular objects.)
         let i = 0u;
         while i < vec::len(ao.methods) {
-            write::ty_only(tcx, ao.methods[i].node.id,
+            write::ty_only(tcx, ao.methods[i].id,
                            ty::method_ty_to_fn_ty(tcx, method_types[i]));
             i += 1u;
         }
@@ -2604,15 +2591,15 @@ fn check_constraints(fcx: @fn_ctxt, cs: [@ast::constr], args: [ast::arg]) {
 }
 
 fn check_fn(ccx: @crate_ctxt,
-            f: ast::_fn,
+            decl: ast::fn_decl,
+            body: ast::blk,
             id: ast::node_id,
             old_fcx: option::t<@fn_ctxt>) {
-    check_fn1(ccx, f.decl, f.proto, f.body, id, old_fcx);
+    check_fn1(ccx, decl, body, id, old_fcx);
 }
 
 fn check_fn1(ccx: @crate_ctxt,
              decl: ast::fn_decl,
-             proto: ast::proto,
              body: ast::blk,
              id: ast::node_id,
              old_fcx: option::t<@fn_ctxt>) {
@@ -2628,7 +2615,7 @@ fn check_fn1(ccx: @crate_ctxt,
     let fcx: @fn_ctxt =
         @{ret_ty: ty::ty_fn_ret(ccx.tcx, ty::node_id_to_type(ccx.tcx, id)),
           purity: purity,
-          proto: proto,
+          proto: decl.proto,
           var_bindings: gather_result.var_bindings,
           locals: gather_result.locals,
           next_var_id: gather_result.next_var_id,
@@ -2665,14 +2652,16 @@ fn check_fn1(ccx: @crate_ctxt,
 }
 
 fn check_method(ccx: @crate_ctxt, method: @ast::method) {
-    check_fn(ccx, method.node.meth, method.node.id, none);
+    check_fn(ccx, method.decl, method.body, method.id, none);
 }
 
 fn check_item(ccx: @crate_ctxt, it: @ast::item) {
     alt it.node {
       ast::item_const(_, e) { check_const(ccx, it.span, e, it.id); }
-      ast::item_fn(f, _) { check_fn(ccx, f, it.id, none); }
-      ast::item_res(f, dtor_id, _, _) { check_fn(ccx, f, dtor_id, none); }
+      ast::item_fn(decl, _, body) { check_fn(ccx, decl, body, it.id, none); }
+      ast::item_res(decl, _, body, dtor_id, _) {
+        check_fn(ccx, decl, body, dtor_id, none);
+      }
       ast::item_obj(ob, _, _) {
         // We're entering an object, so gather up the info we need.
         ccx.self_infos += [self_obj(ob.fields,