about summary refs log tree commit diff
path: root/src/comp/middle
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-12-13 13:19:56 +0100
committerMarijn Haverbeke <marijnh@gmail.com>2011-12-16 11:46:57 +0100
commit888bc80025262286f2270442cea86e20e60d5430 (patch)
treea3669ada9d5903e378b0a44c5ff608dfe0234779 /src/comp/middle
parentd5af61d6799ee8c1af583ba1fed0b9e3ce162f2c (diff)
downloadrust-888bc80025262286f2270442cea86e20e60d5430.tar.gz
rust-888bc80025262286f2270442cea86e20e60d5430.zip
Parse and resolve implementations.
Issue #1227
Diffstat (limited to 'src/comp/middle')
-rw-r--r--src/comp/middle/alias.rs2
-rw-r--r--src/comp/middle/mut.rs1
-rw-r--r--src/comp/middle/resolve.rs201
-rw-r--r--src/comp/middle/trans.rs4
-rw-r--r--src/comp/middle/tstate/pre_post_conditions.rs22
-rw-r--r--src/comp/middle/ty.rs20
-rw-r--r--src/comp/middle/typeck.rs14
7 files changed, 198 insertions, 66 deletions
diff --git a/src/comp/middle/alias.rs b/src/comp/middle/alias.rs
index 6600bf566af..f5bebd344cc 100644
--- a/src/comp/middle/alias.rs
+++ b/src/comp/middle/alias.rs
@@ -532,7 +532,7 @@ fn ty_can_unsafely_include(cx: ctx, needle: unsafe_ty, haystack: ty::t,
 fn def_is_local(d: ast::def, objfields_count: bool) -> bool {
     ret alt d {
           ast::def_local(_, _) | ast::def_arg(_, _) | ast::def_binding(_) |
-          ast::def_upvar(_, _, _) {
+          ast::def_upvar(_, _, _) | ast::def_self(_) {
             true
           }
           ast::def_obj_field(_, _) { objfields_count }
diff --git a/src/comp/middle/mut.rs b/src/comp/middle/mut.rs
index 1c12566f9f1..8d952679678 100644
--- a/src/comp/middle/mut.rs
+++ b/src/comp/middle/mut.rs
@@ -264,6 +264,7 @@ fn is_immutable_def(def: def) -> option::t<str> {
       def_arg(_, by_ref.) | def_arg(_, by_val.) |
       def_arg(_, mode_infer.) { some("argument") }
       def_obj_field(_, imm.) { some("immutable object field") }
+      def_self(_) { some("self argument") }
       def_upvar(_, inner, mut) {
         if !mut { some("upvar") } else { is_immutable_def(*inner) }
       }
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index 73a12b56907..4121771e8b6 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -19,9 +19,7 @@ import option::{some, none, is_none, is_some};
 import syntax::print::pprust::*;
 
 export resolve_crate;
-export def_map;
-export ext_map;
-export exp_map;
+export def_map, ext_map, exp_map, impl_map;
 
 // Resolving happens in two passes. The first pass collects defids of all
 // (internal) imports and modules, so that they can be looked up when needed,
@@ -45,14 +43,23 @@ type scopes = list<scope>;
 
 tag import_state {
     todo(ast::node_id, ast::ident, @[ast::ident], codemap::span, scopes);
+    is_glob(@[ast::ident], scopes, codemap::span);
     resolving(span);
     resolved(option::t<def>, /* value */
              option::t<def>, /* type */
              option::t<def>, /* module */
+             @[def_id],
              /* used for reporting unused import warning */
              ast::ident, codemap::span);
 }
 
+tag glob_import_state {
+    glob_resolving(span);
+    glob_resolved(option::t<def>,  /* value */
+                  option::t<def>,  /* type */
+                  option::t<def>); /* module */
+}
+
 type ext_hash = hashmap<{did: def_id, ident: str, ns: namespace}, def>;
 
 fn new_ext_hash() -> ext_hash {
@@ -89,7 +96,7 @@ type indexed_mod = {
     m: option::t<ast::_mod>,
     index: mod_index,
     mutable glob_imports: [glob_imp_def],
-    glob_imported_names: hashmap<str, import_state>,
+    glob_imported_names: hashmap<str, glob_import_state>,
     path: str
 };
 
@@ -99,6 +106,7 @@ type indexed_mod = {
 type def_map = hashmap<node_id, def>;
 type ext_map = hashmap<def_id, [ident]>;
 type exp_map = hashmap<str, def>;
+type impl_map = hashmap<node_id, iscopes>;
 
 type env =
     {cstore: cstore::cstore,
@@ -109,6 +117,7 @@ type env =
      mod_map: hashmap<ast::node_id, @indexed_mod>,
      block_map: hashmap<ast::node_id, [glob_imp_def]>,
      ext_map: ext_map,
+     impl_map: impl_map,
      ext_cache: ext_hash,
      used_imports: {mutable track: bool,
                     mutable data: [ast::node_id]},
@@ -124,7 +133,8 @@ tag dir { inside; outside; }
 tag namespace { ns_value; ns_type; ns_module; }
 
 fn resolve_crate(sess: session, amap: ast_map::map, crate: @ast::crate) ->
-   {def_map: def_map, ext_map: ext_map, exp_map: exp_map} {
+   {def_map: def_map, ext_map: ext_map,
+    exp_map: exp_map, impl_map: impl_map} {
     let e =
         @{cstore: sess.get_cstore(),
           def_map: new_int_hash(),
@@ -134,6 +144,7 @@ fn resolve_crate(sess: session, amap: ast_map::map, crate: @ast::crate) ->
           mod_map: new_int_hash(),
           block_map: new_int_hash(),
           ext_map: new_def_hash(),
+          impl_map: new_int_hash(),
           ext_cache: new_ext_hash(),
           used_imports: {mutable track: false, mutable data:  []},
           mutable reported: [],
@@ -144,10 +155,12 @@ fn resolve_crate(sess: session, amap: ast_map::map, crate: @ast::crate) ->
     check_for_collisions(e, *crate);
     check_exports(e);
     resolve_names(e, crate);
+    resolve_impls(e, crate);
     if sess.get_opts().warn_unused_imports {
         check_unused_imports(e);
     }
-    ret {def_map: e.def_map, ext_map: e.ext_map, exp_map: e.exp_map};
+    ret {def_map: e.def_map, ext_map: e.ext_map,
+         exp_map: e.exp_map, impl_map: e.impl_map};
 }
 
 // Locate all modules and imports and index them, so that the next passes can
@@ -166,7 +179,7 @@ fn map_crate(e: @env, c: @ast::crate) {
                      @{m: some(c.node.module),
                        index: index_mod(c.node.module),
                        mutable glob_imports: [],
-                       glob_imported_names: new_str_hash::<import_state>(),
+                       glob_imported_names: new_str_hash(),
                        path: ""});
     fn index_vi(e: @env, i: @ast::view_item, sc: scopes, _v: vt<scopes>) {
         alt i.node {
@@ -181,6 +194,9 @@ fn map_crate(e: @env, c: @ast::crate) {
                                       ident.span, sc));
             }
           }
+          ast::view_item_import_glob(pth, id) {
+            e.imports.insert(id, is_glob(pth, sc, i.span));
+          }
           _ { }
         }
     }
@@ -198,21 +214,19 @@ fn map_crate(e: @env, c: @ast::crate) {
         visit_item_with_scope(i, sc, v);
         alt i.node {
           ast::item_mod(md) {
-            let s = new_str_hash::<import_state>();
             e.mod_map.insert(i.id,
                              @{m: some(md),
                                index: index_mod(md),
                                mutable glob_imports: [],
-                               glob_imported_names: s,
+                               glob_imported_names: new_str_hash(),
                                path: path_from_scope(sc, i.ident)});
           }
           ast::item_native_mod(nmd) {
-            let s = new_str_hash::<import_state>();
             e.mod_map.insert(i.id,
                              @{m: none::<ast::_mod>,
                                index: index_nmod(nmd),
                                mutable glob_imports: [],
-                               glob_imported_names: s,
+                               glob_imported_names: new_str_hash(),
                                path: path_from_scope(sc, i.ident)});
           }
           _ { }
@@ -233,7 +247,7 @@ fn map_crate(e: @env, c: @ast::crate) {
           ast::view_item_import_glob(path, _) {
             let imp = follow_import(*e, sc, *path, vi.span);
             if option::is_some(imp) {
-                let glob = {def: option::get(imp), item: vi};;
+                let glob = {def: option::get(imp), item: vi};
                 alt list::head(sc) {
                   scope_item(i) {
                     e.mod_map.get(i.id).glob_imports += [glob];
@@ -262,7 +276,7 @@ fn resolve_imports(e: env) {
           todo(node_id, name, path, span, scopes) {
             resolve_import(e, local_def(node_id), name, *path, span, scopes);
           }
-          resolved(_, _, _, _, _) { }
+          resolved(_, _, _, _, _, _) | is_glob(_, _, _) { }
         }
     };
     e.used_imports.track = false;
@@ -272,7 +286,7 @@ fn resolve_imports(e: env) {
 fn check_unused_imports(e: @env) {
     e.imports.items {|k, v|
         alt v {
-            resolved(val, ty, md, name, sp) {
+            resolved(_, _, _, _, name, sp) {
               if !vec::member(k, e.used_imports.data) {
                 e.sess.span_warn(sp, "unused import " + name);
               }
@@ -472,13 +486,14 @@ fn resolve_constr(e: @env, c: @ast::constr, sc: scopes, _v: vt<scopes>) {
 fn resolve_import(e: env, defid: ast::def_id, name: ast::ident,
                   ids: [ast::ident], sp: codemap::span, sc: scopes) {
     fn register(e: env, id: node_id, cx: ctxt, sp: codemap::span,
-                name: ast::ident, lookup: block(namespace) -> option::t<def>){
+                name: ast::ident, lookup: block(namespace) -> option::t<def>,
+                impls: [def_id]) {
         let val = lookup(ns_value), typ = lookup(ns_type),
             md = lookup(ns_module);
         if is_none(val) && is_none(typ) && is_none(md) {
             unresolved_err(e, cx, sp, name, "import");
         } else {
-            e.imports.insert(id, resolved(val, typ, md, name, sp));
+            e.imports.insert(id, resolved(val, typ, md, @impls, name, sp));
         }
     }
     // Temporarily disable this import and the imports coming after during
@@ -527,7 +542,7 @@ fn resolve_import(e: env, defid: ast::def_id, name: ast::ident,
     let end_id = ids[n_idents - 1u];
     if n_idents == 1u {
         register(e, defid.node, in_scope(sc), sp, name,
-                 {|ns| lookup_in_scope(e, sc, sp, end_id, ns) });
+                 {|ns| lookup_in_scope(e, sc, sp, end_id, ns) }, []);
     } else {
         alt lookup_in_scope(e, sc, sp, ids[0], ns_module) {
           none. {
@@ -537,9 +552,11 @@ fn resolve_import(e: env, defid: ast::def_id, name: ast::ident,
             let dcur = dcur_, i = 1u;
             while true {
                 if i == n_idents - 1u {
+                    let impls = [];
+                    find_impls_in_mod(e, dcur, impls, some(end_id));
                     register(e, defid.node, in_mod(dcur), sp, name, {|ns|
                         lookup_in_mod(e, dcur, sp, end_id, ns, outside)
-                    });
+                    }, impls);
                     break;
                 } else {
                     dcur = alt lookup_in_mod(e, dcur, sp, ids[i], ns_module,
@@ -563,7 +580,7 @@ fn resolve_import(e: env, defid: ast::def_id, name: ast::ident,
     // import
     alt e.imports.find(defid.node) {
       some(resolving(sp)) {
-        e.imports.insert(defid.node, resolved(none, none, none, "", sp));
+        e.imports.insert(defid.node, resolved(none, none, none, @[], "", sp));
       }
       _ { }
     }
@@ -726,6 +743,11 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace)
               ast::item_obj(ob, ty_params, _) {
                 ret lookup_in_obj(name, ob, ty_params, ns);
               }
+              ast::item_impl(_, _, _) {
+                if (name == "self" && ns == ns_value) {
+                    ret some(ast::def_self(local_def(it.id)));
+                }
+              }
               ast::item_tag(_, ty_params) {
                 if ns == ns_type { ret lookup_in_ty_params(name, ty_params); }
               }
@@ -819,7 +841,6 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace)
         }
     }
     e.sess.bug("reached unreachable code in lookup_in_scope"); // sigh
-
 }
 
 fn lookup_in_ty_params(name: ident, ty_params: [ast::ty_param]) ->
@@ -999,7 +1020,7 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option::t<def> {
       }
       _ { }
     }
-    ret none::<def>;
+    ret none;
 }
 
 fn lookup_in_mod_strict(e: env, m: def, sp: span, name: ident,
@@ -1060,11 +1081,12 @@ fn lookup_import(e: env, defid: def_id, ns: namespace) -> option::t<def> {
         e.sess.span_err(sp, "cyclic import");
         ret none;
       }
-      resolved(val, typ, md, _, _) {
+      resolved(val, typ, md, _, _, _) {
         if e.used_imports.track {
             e.used_imports.data += [defid.node];
         }
-        ret alt ns { ns_value. { val } ns_type. { typ } ns_module. { md } };
+        ret alt ns { ns_value. { val } ns_type. { typ }
+                     ns_module. { md } };
       }
     }
 }
@@ -1136,22 +1158,20 @@ fn lookup_glob_in_mod(e: env, info: @indexed_mod, sp: span, id: ident,
     // since we don't know what names we have in advance,
     // absence takes the place of todo()
     if !info.glob_imported_names.contains_key(id) {
-        info.glob_imported_names.insert(id, resolving(sp));
+        info.glob_imported_names.insert(id, glob_resolving(sp));
         let val = lookup_in_globs(e, info.glob_imports, sp, id, ns_value, dr);
         let typ = lookup_in_globs(e, info.glob_imports, sp, id, ns_type, dr);
         let md = lookup_in_globs(e, info.glob_imports, sp, id, ns_module, dr);
-        info.glob_imported_names.insert(id, resolved(val, typ, md, id, sp));
+        info.glob_imported_names.insert(id, glob_resolved(val, typ, md));
     }
     alt info.glob_imported_names.get(id) {
-      todo(_, _, _, _, _) { e.sess.bug("Shouldn't've put a todo in."); }
-      //circularity is okay in import globs
-      resolving(sp) { ret none::<def>; }
-      resolved(val, typ, md, _, _) {
+      glob_resolving(sp) { ret none::<def>; }
+      glob_resolved(val, typ, md) {
         ret alt wanted_ns {
-              ns_value. { val }
-              ns_type. { typ }
-              ns_module. { md }
-            };
+          ns_value. { val }
+          ns_type. { typ }
+          ns_module. { md }
+        };
       }
     }
 }
@@ -1229,7 +1249,8 @@ fn index_mod(md: ast::_mod) -> mod_index {
         alt it.node {
           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));
           }
           ast::item_tag(variants, _) {
@@ -1289,6 +1310,7 @@ fn ns_for_def(d: def) -> namespace {
           ast::def_use(_) { ns_module }
           ast::def_native_ty(_) { ns_type }
           ast::def_native_fn(_, _) { ns_value }
+          ast::def_self(_) { ns_value }
         };
 }
 
@@ -1558,7 +1580,7 @@ fn check_exports(e: @env) {
                 alt x {
                   mie_import_ident(id, _) {
                     alt e.imports.get(id) {
-                      resolved(v, t, m, rid, _) {
+                      resolved(v, t, m, _, rid, _) {
                         maybe_add_reexport(e, val.path + rid, v);
                         maybe_add_reexport(e, val.path + rid, t);
                         maybe_add_reexport(e, val.path + rid, m);
@@ -1596,6 +1618,115 @@ fn check_exports(e: @env) {
     };
 }
 
+// Impl resolution
+
+fn resolve_impls(e: @env, c: @ast::crate) {
+    visit::visit_crate(*c, nil, visit::mk_vt(@{
+        visit_block: bind visit_block_with_impl_scope(e, _, _, _),
+        visit_item: bind visit_item_with_impl_scope(e, _, _, _),
+        visit_expr: bind resolve_impl_in_expr(e, _, _, _)
+        with *visit::default_visitor()
+    }));
+}
+
+fn find_impls_in_view_item(e: env, vi: @ast::view_item, &impls: [def_id]) {
+    alt vi.node {
+      ast::view_item_import(ident, _, id) {
+        // FIXME if single name, simply look in our own iscope
+        alt e.imports.get(id) {
+          resolved(_, _, _, is, _, _) { impls += *is; }
+        }
+      }
+      ast::view_item_import_from(base, names, _) {
+        for nm in names {
+            alt e.imports.get(nm.node.id) {
+              resolved(_, _, _, is, _, _) { impls += *is; }
+            }
+        }
+      }
+      ast::view_item_import_glob(ids, id) {
+          alt e.imports.get(id) {
+            is_glob(path, sc, sp) {
+              alt follow_import(e, sc, *path, sp) {
+                some(def) { find_impls_in_mod(e, def, impls, none); }
+                _ {}
+              }
+            }
+          }
+      }
+      _ {}
+    }
+}
+
+fn find_impls_in_item(i: @ast::item, &impls: [def_id],
+                      name: option::t<ident>, _dir: dir) {
+    // FIXME check exports
+    alt i.node {
+      ast::item_impl(_, _, _) {
+        if alt name { some(n) { n == i.ident } _ { true } } {
+            impls += [local_def(i.id)];
+        }
+      }
+      _ {}
+    }
+}
+
+fn find_impls_in_mod(e: env, m: def, &impls: [def_id],
+                     name: option::t<ident>) {
+    alt m {
+      ast::def_mod(defid) {
+        // FIXME external importing of impls
+        if defid.crate == ast::local_crate {
+            for i in option::get(e.mod_map.get(defid.node).m).items {
+                find_impls_in_item(i, impls, name, outside);
+            }
+        }
+      }
+      _ {}
+    }
+}
+
+type iscopes = list<@[def_id]>;
+
+fn visit_block_with_impl_scope(e: @env, b: ast::blk, sc: iscopes,
+                               v: vt<iscopes>) {
+    let impls = [];
+    for vi in b.node.view_items { find_impls_in_view_item(*e, vi, impls); }
+    for st in b.node.stmts {
+        alt st.node {
+          ast::stmt_decl(@{node: ast::decl_item(i), _}, _) {
+            find_impls_in_item(i, impls, none, inside);
+          }
+          _ {}
+        }
+    }
+    let sc = vec::len(impls) > 0u ? cons(@impls, @sc) : sc;
+    visit::visit_block(b, sc, v);
+}
+
+fn visit_item_with_impl_scope(e: @env, i: @ast::item, sc: iscopes,
+                              v: vt<iscopes>) {
+    let sc = sc;
+    alt i.node {
+      ast::item_mod(m) {
+        let impls = [];
+        for vi in m.view_items { find_impls_in_view_item(*e, vi, impls); }
+        for i in m.items { find_impls_in_item(i, impls, none, inside); }
+        if vec::len(impls) > 0u { sc = cons(@impls, @sc); }
+      }
+      _ {}
+    }
+    visit::visit_item(i, sc, v);
+}
+
+fn resolve_impl_in_expr(e: @env, x: @ast::expr, sc: iscopes, v: vt<iscopes>) {
+    alt x.node {
+      ast::expr_field(_, _) { e.impl_map.insert(x.id, sc); }
+      _ {}
+    }
+    visit::visit_expr(x, sc, v);
+}
+
 // Local Variables:
 // mode: rust
 // fill-column: 78;
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 79dc9448316..bd25cc4e9bf 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -2678,6 +2678,9 @@ fn trans_local_var(cx: @block_ctxt, def: ast::def) -> local_var_result {
         assert (cx.fcx.llobjfields.contains_key(did.node));
         ret { val: cx.fcx.llobjfields.get(did.node), kind: owned };
       }
+      ast::def_self(did) {
+        ret lval_owned(cx, cx.fcx.llenv);
+      }
       _ {
         bcx_ccx(cx).sess.span_unimpl
             (cx.sp, "unsupported def type in trans_local_def");
@@ -4946,6 +4949,7 @@ fn trans_item(cx: @local_ctxt, item: ast::item) {
                  with *extend_path(cx, item.ident)};
         trans_obj(sub_cx, item.span, ob, ctor_id, tps);
       }
+      ast::item_impl(_, _, _) { fail "FIXME[impl]"; }
       ast::item_res(dtor, dtor_id, tps, ctor_id) {
         trans_res_ctor(cx, item.span, dtor, ctor_id, tps);
 
diff --git a/src/comp/middle/tstate/pre_post_conditions.rs b/src/comp/middle/tstate/pre_post_conditions.rs
index ce759abf74d..f622acb7040 100644
--- a/src/comp/middle/tstate/pre_post_conditions.rs
+++ b/src/comp/middle/tstate/pre_post_conditions.rs
@@ -26,17 +26,14 @@ fn find_pre_post_native_mod(_m: native_mod) -> native_mod {
     fail;
 }
 
-fn find_pre_post_obj(ccx: crate_ctxt, o: _obj) {
-    fn do_a_method(ccx: crate_ctxt, m: @method) {
-        assert (ccx.fm.contains_key(m.node.id));
-        let fcx: fn_ctxt =
-            {enclosing: ccx.fm.get(m.node.id),
-             id: m.node.id,
-             name: m.node.ident,
-             ccx: ccx};
-        find_pre_post_fn(fcx, m.node.meth);
-    }
-    for m: @method in o.methods { do_a_method(ccx, m); }
+fn find_pre_post_method(ccx: crate_ctxt, m: @method) {
+    assert (ccx.fm.contains_key(m.node.id));
+    let fcx: fn_ctxt =
+        {enclosing: ccx.fm.get(m.node.id),
+         id: m.node.id,
+         name: m.node.ident,
+         ccx: ccx};
+    find_pre_post_fn(fcx, m.node.meth);
 }
 
 fn find_pre_post_item(ccx: crate_ctxt, i: item) {
@@ -77,7 +74,8 @@ fn find_pre_post_item(ccx: crate_ctxt, i: item) {
              ccx: ccx};
         find_pre_post_fn(fcx, dtor);
       }
-      item_obj(o, _, _) { find_pre_post_obj(ccx, o); }
+      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); } }
     }
 }
 
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 2ff7f0b1b74..1c5bdcb18f5 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -2702,20 +2702,12 @@ fn substitute_type_params(cx: ctxt, substs: [ty::t], typ: t) -> t {
 
 fn def_has_ty_params(def: ast::def) -> bool {
     alt def {
-      ast::def_fn(_, _) { ret true; }
-      ast::def_obj_field(_, _) { ret false; }
-      ast::def_mod(_) { ret false; }
-      ast::def_const(_) { ret false; }
-      ast::def_arg(_, _) { ret false; }
-      ast::def_local(_, _) { ret false; }
-      ast::def_upvar(_, _, _) { ret false; }
-      ast::def_variant(_, _) { ret true; }
-      ast::def_ty(_) { ret false; }
-      ast::def_ty_param(_, _) { ret false; }
-      ast::def_binding(_) { ret false; }
-      ast::def_use(_) { ret false; }
-      ast::def_native_ty(_) { ret false; }
-      ast::def_native_fn(_, _) { ret true; }
+      ast::def_obj_field(_, _) | ast::def_mod(_) | ast::def_const(_) |
+      ast::def_arg(_, _) | ast::def_local(_, _) | ast::def_upvar(_, _, _) |
+      ast::def_ty_param(_, _) | ast::def_binding(_) | ast::def_use(_) |
+      ast::def_native_ty(_) | ast::def_self(_) | ast::def_ty(_) { false }
+      ast::def_fn(_, _) | ast::def_variant(_, _) |
+      ast::def_native_fn(_, _) { true }
     }
 }
 
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index e4d1674fd86..1150f4637de 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -33,7 +33,9 @@ tag obj_info {
     anon_obj([ast::obj_field], option::t<ty::sty>);
 }
 
-type crate_ctxt = {mutable obj_infos: [obj_info], tcx: ty::ctxt};
+type crate_ctxt = {mutable obj_infos: [obj_info],
+                   impl_map: resolve::impl_map,
+                   tcx: ty::ctxt};
 
 type fn_ctxt =
     // var_bindings, locals and next_var_id are shared
@@ -89,6 +91,7 @@ fn ty_param_kinds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) ->
         let typ = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, sp, id.node));
         ret {kinds: no_kinds, ty: typ};
       }
+      ast::def_self(id) { fail "FIXME[impl]"; }
       ast::def_fn(id, _) { ret ty::lookup_item_type(fcx.ccx.tcx, id); }
       ast::def_native_fn(id, _) { ret ty::lookup_item_type(fcx.ccx.tcx, id); }
       ast::def_const(id) { ret ty::lookup_item_type(fcx.ccx.tcx, id); }
@@ -686,7 +689,7 @@ mod collect {
     }
     fn convert(cx: @ctxt, it: @ast::item) {
         alt it.node {
-          ast::item_mod(_) {
+          ast::item_mod(_) | ast::item_impl(_, _, _) {
             // ignore item_mod, it has no type.
           }
           ast::item_native_mod(native_mod) {
@@ -2657,12 +2660,15 @@ fn check_for_main_fn(tcx: ty::ctxt, crate: @ast::crate) {
     }
 }
 
-fn check_crate(tcx: ty::ctxt, crate: @ast::crate) {
+fn check_crate(tcx: ty::ctxt, impl_map: resolve::impl_map,
+               crate: @ast::crate) {
     collect::collect_item_types(tcx, crate);
 
     let obj_infos: [obj_info] = [];
 
-    let ccx = @{mutable obj_infos: obj_infos, tcx: tcx};
+    let ccx = @{mutable obj_infos: obj_infos,
+                impl_map: impl_map,
+                tcx: tcx};
     let visit =
         visit::mk_simple_visitor(@{visit_item: bind check_item(ccx, _)
                                       with *visit::default_simple_visitor()});