diff --git a/src/Makefile b/src/Makefile
index 4d290b10e56a4..5f76f398c1e87 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -402,6 +402,8 @@ TEST_XFAILS_BOOT :=  $(TASK_XFAILS) \
                     test/run-pass/vec-slice.rs \
                     test/run-pass/while-and-do-while.rs \
                     test/run-fail/task-comm-14.rs \
+                    test/compile-fail/import.rs \
+                    test/compile-fail/import2.rs \
                     test/compile-fail/bad-recv.rs \
                     test/compile-fail/bad-send.rs \
                     test/compile-fail/infinite-vec-type-recursion.rs \
@@ -441,6 +443,7 @@ TEST_XFAILS_RUSTC := $(filter-out \
                         i8-incr.rs \
                         import2.rs \
                         import3.rs \
+                        import4.rs \
                         item-name-overload.rs \
                         large-records.rs \
                         lazy-init.rs \
@@ -477,6 +480,8 @@ TEST_XFAILS_RUSTC := $(filter-out \
                       $(addprefix test/compile-fail/, \
                         arg-count-mismatch.rs \
                         arg-type-mismatch.rs \
+                        import.rs \
+                        import2.rs \
                         while-type-error.rs \
                         ), \
                       $(wildcard test/*/*.rs test/*/*.rc))
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index 808637e748c1d..95f84f463e995 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -3,6 +3,7 @@ import front.ast.ident;
 import front.ast.def;
 import front.ast.ann;
 import driver.session;
+import util.common.new_def_hash;
 import util.common.span;
 import std.map.hashmap;
 import std.list.list;
@@ -24,6 +25,8 @@ tag scope {
 type env = rec(list[scope] scopes,
                session.session sess);
 
+type import_map = std.map.hashmap[ast.def_id,def_wrap];
+
 // A simple wrapper over defs that stores a bit more information about modules
 // and uses so that we can use the regular lookup_name when resolving imports.
 tag def_wrap {
@@ -66,23 +69,26 @@ fn unwrap_def(option.t[def_wrap] d_) -> option.t[def] {
 
 // Follow the path of an import and return what it ultimately points to.
 
-fn find_final_def(&env e, vec[ident] idents) -> option.t[def_wrap] {
+fn find_final_def(&env e, &span sp, vec[ident] idents) -> option.t[def_wrap] {
     auto len = _vec.len[ident](idents);
     auto first = idents.(0);
+    auto d_ = lookup_name(e, none[import_map], first);
     if (len == 1u) {
-        ret lookup_name(e, first);
+        ret d_;
     }
-    auto d_ = lookup_name(e, first);
     alt (d_) {
         case (none[def_wrap]) {
+            e.sess.span_err(sp, "unresolved name: " + first);
             ret d_;
         }
         case (some[def_wrap](?d)) {
-            alt(d) {
+            alt (d) {
                 case (def_wrap_mod(?i)) {
-                    auto new_env = update_env_for_item(e, i);
                     auto new_idents = _vec.slice[ident](idents, 1u, len);
-                    ret find_final_def(new_env, new_idents);
+                    auto tmp_e = rec(scopes = nil[scope],
+                                     sess = e.sess);
+                    auto new_e = update_env_for_item(tmp_e, i);
+                    ret find_final_def(new_e, sp, new_idents);
                 }
             }
         }
@@ -90,7 +96,8 @@ fn find_final_def(&env e, vec[ident] idents) -> option.t[def_wrap] {
     fail;
 }
 
-fn lookup_name(&env e, ast.ident i) -> option.t[def_wrap] {
+fn lookup_name(&env e, option.t[import_map] index,
+               ast.ident i) -> option.t[def_wrap] {
 
     // log "resolving name " + i;
 
@@ -134,16 +141,19 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def_wrap] {
         ret none[def_wrap];
     }
 
-    fn found_def_view(&env e, @ast.view_item i) -> option.t[def_wrap] {
+    fn found_def_view(&env e, option.t[import_map] index,
+                      @ast.view_item i) -> option.t[def_wrap] {
         alt (i.node) {
             case (ast.view_item_use(_, _, ?id)) {
                 ret some[def_wrap](def_wrap_use(i));
             }
-            case (ast.view_item_import(?idents,_)) {
-                auto d = find_final_def(e, idents);
-                alt (d) {
-                    case (some[def_wrap](_)) {
-                        ret d;
+            case (ast.view_item_import(?idents,?d)) {
+                alt (index) {
+                    case (some[import_map](?idx)) {
+                        ret idx.find(d);
+                    }
+                    case (none[import_map]) {
+                        ret find_final_def(e, i.span, idents);
                     }
                 }
             }
@@ -151,12 +161,13 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def_wrap] {
         fail;
     }
 
-    fn check_mod(&env e, ast.ident i, ast._mod m) -> option.t[def_wrap] {
+    fn check_mod(&env e, option.t[import_map] index, ast.ident i,
+                 ast._mod m) -> option.t[def_wrap] {
         alt (m.index.find(i)) {
             case (some[ast.mod_index_entry](?ent)) {
                 alt (ent) {
                     case (ast.mie_view_item(?ix)) {
-                        ret found_def_view(e, m.view_items.(ix));
+                        ret found_def_view(e, index, m.view_items.(ix));
                     }
                     case (ast.mie_item(?ix)) {
                         ret found_def_item(m.items.(ix));
@@ -182,11 +193,12 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def_wrap] {
     }
 
 
-    fn in_scope(ast.ident i, env e, &scope s) -> option.t[def_wrap] {
+    fn in_scope(ast.ident i, env e, option.t[import_map] index,
+                &scope s) -> option.t[def_wrap] {
         alt (s) {
 
             case (scope_crate(?c)) {
-                ret check_mod(e, i, c.node.module);
+                ret check_mod(e, index, i, c.node.module);
             }
 
             case (scope_item(?it)) {
@@ -220,7 +232,7 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def_wrap] {
                         }
                     }
                     case (ast.item_mod(_, ?m, _)) {
-                        ret check_mod(e, i, m);
+                        ret check_mod(e, index, i, m);
                     }
                     case (_) { /* fall through */ }
                 }
@@ -248,13 +260,15 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def_wrap] {
         ret none[def_wrap];
     }
 
-    ret std.list.find[scope,def_wrap](e.scopes, bind in_scope(i, e, _));
+    ret std.list.find[scope,def_wrap](e.scopes,
+                                      bind in_scope(i, e, index, _));
 }
 
-fn fold_pat_tag(&env e, &span sp, ident i, vec[@ast.pat] args,
-                option.t[ast.variant_def] old_def, ann a) -> @ast.pat {
+fn fold_pat_tag(&env e, &span sp, import_map index, ident i,
+                vec[@ast.pat] args, option.t[ast.variant_def] old_def,
+                ann a) -> @ast.pat {
     auto new_def;
-    alt (unwrap_def(lookup_name(e, i))) {
+    alt (unwrap_def(lookup_name(e, some(index), i))) {
         case (some[def](?d)) {
             alt (d) {
                 case (ast.def_variant(?did, ?vid)) {
@@ -275,14 +289,14 @@ fn fold_pat_tag(&env e, &span sp, ident i, vec[@ast.pat] args,
     ret @fold.respan[ast.pat_](sp, ast.pat_tag(i, args, new_def, a));
 }
 
-fn fold_expr_name(&env e, &span sp, &ast.name n,
-                  &option.t[def] d, ann a) -> @ast.expr {
+fn fold_expr_name(&env e, &span sp, import_map index,
+                  &ast.name n, &option.t[def] d, ann a) -> @ast.expr {
 
     if (_vec.len[@ast.ty](n.node.types) > 0u) {
         e.sess.unimpl("resolving name expr with ty params");
     }
 
-    auto d_ = unwrap_def(lookup_name(e, n.node.ident));
+    auto d_ = unwrap_def(lookup_name(e, some(index), n.node.ident));
 
     alt (d_) {
         case (some[def](_)) {
@@ -296,7 +310,27 @@ fn fold_expr_name(&env e, &span sp, &ast.name n,
     ret @fold.respan[ast.expr_](sp, ast.expr_name(n, d_, a));
 }
 
-fn fold_ty_path(&env e, &span sp, ast.path p,
+fn fold_view_item_import(&env e, &span sp,
+                         import_map index,
+                         vec[ident] is, ast.def_id id) -> @ast.view_item {
+    // Produce errors for invalid imports
+    auto len = _vec.len[ast.ident](is);
+    auto last_id = is.(len - 1u);
+    auto d = lookup_name(e, none[import_map], last_id);
+    alt (d) {
+        case (none[def_wrap]) {
+            e.sess.span_err(sp, "unresolved name: " + last_id);
+        }
+        case (some[def_wrap](?d2)) {
+            index.insert(id, d2);
+        }
+    }
+
+    ret @fold.respan[ast.view_item_](sp, ast.view_item_import(is, id));
+}
+
+
+fn fold_ty_path(&env e, &span sp, import_map index, ast.path p,
                 &option.t[def] d) -> @ast.ty {
 
     let uint len = _vec.len[ast.name](p);
@@ -311,7 +345,7 @@ fn fold_ty_path(&env e, &span sp, ast.path p,
         e.sess.unimpl("resolving path ty with ty params");
     }
 
-    auto d_ = unwrap_def(lookup_name(e, n.node.ident));
+    auto d_ = unwrap_def(lookup_name(e, some(index), n.node.ident));
 
     alt (d_) {
         case (some[def](_)) {
@@ -345,9 +379,12 @@ fn resolve_crate(session.session sess, @ast.crate crate) -> @ast.crate {
 
     let fold.ast_fold[env] fld = fold.new_identity_fold[env]();
 
-    fld = @rec( fold_pat_tag = bind fold_pat_tag(_,_,_,_,_,_),
-                fold_expr_name = bind fold_expr_name(_,_,_,_,_),
-                fold_ty_path = bind fold_ty_path(_,_,_,_),
+    auto import_index = new_def_hash[def_wrap]();
+    fld = @rec( fold_pat_tag = bind fold_pat_tag(_,_,import_index,_,_,_,_),
+                fold_expr_name = bind fold_expr_name(_,_,import_index,_,_,_),
+                fold_view_item_import
+                    = bind fold_view_item_import(_,_,import_index,_,_),
+                fold_ty_path = bind fold_ty_path(_,_,import_index,_,_),
                 update_env_for_crate = bind update_env_for_crate(_,_),
                 update_env_for_item = bind update_env_for_item(_,_),
                 update_env_for_block = bind update_env_for_block(_,_),
diff --git a/src/test/compile-fail/import.rs b/src/test/compile-fail/import.rs
new file mode 100644
index 0000000000000..71ef0dec9c584
--- /dev/null
+++ b/src/test/compile-fail/import.rs
@@ -0,0 +1,11 @@
+// error-pattern: unresolved name: baz
+import zed.bar;
+import zed.baz;
+mod zed {
+  fn bar() {
+    log "bar";
+  }
+}
+fn main(vec[str] args) {
+   bar();
+}
diff --git a/src/test/compile-fail/import2.rs b/src/test/compile-fail/import2.rs
new file mode 100644
index 0000000000000..5a9ddcbd81513
--- /dev/null
+++ b/src/test/compile-fail/import2.rs
@@ -0,0 +1,12 @@
+// error-pattern: unresolved name: zed
+import baz.zed.bar;
+mod baz {
+}
+mod zed {
+  fn bar() {
+    log "bar3";
+  }
+}
+fn main(vec[str] args) {
+  bar();
+}
diff --git a/src/test/run-pass/import4.rs b/src/test/run-pass/import4.rs
new file mode 100644
index 0000000000000..5b0cb9f331ff0
--- /dev/null
+++ b/src/test/run-pass/import4.rs
@@ -0,0 +1,10 @@
+import zed.bar;
+mod zed {
+  fn bar() {
+    log "bar";
+  }
+}
+fn main(vec[str] args) {
+  auto zed = 42;
+  bar();
+}
diff --git a/src/test/run-pass/use.rs b/src/test/run-pass/use.rs
index 8638d609b16cf..ac46061c40f78 100644
--- a/src/test/run-pass/use.rs
+++ b/src/test/run-pass/use.rs
@@ -3,9 +3,9 @@ use libc();
 use zed(name = "std");
 use bar(name = "std", ver = "0.0.1");
 
-import std._str;
-import x = std._str;
-
+// FIXME: commented out since resolve doesn't know how to handle crates yet.
+// import std._str;
+// import x = std._str;
 
 mod baz {
   use std;
@@ -13,8 +13,8 @@ mod baz {
   use zed(name = "std");
   use bar(name = "std", ver = "0.0.1");
 
-  import std._str;
-  import x = std._str;
+  // import std._str;
+  // import x = std._str;
 }
 
 fn main() {