about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-12-20 05:52:18 +0000
committerbors <bors@rust-lang.org>2014-12-20 05:52:18 +0000
commit8443b09e361b96d1f9b7f45a65ed0d31c0e86e70 (patch)
tree384f1c2987b838be0a788d10d0958e898044cdbb
parent1c2df5cc3cfc0c9e80adf9fa6504d55056741c5a (diff)
parent948cc666de56d6d1deba55b870e385ffef06a9f3 (diff)
downloadrust-8443b09e361b96d1f9b7f45a65ed0d31c0e86e70.tar.gz
rust-8443b09e361b96d1f9b7f45a65ed0d31c0e86e70.zip
auto merge of #19995 : eddyb/rust/split-resolve, r=nikomatsakis
r? @nikomatsakis
-rw-r--r--mk/crates.mk12
-rw-r--r--mk/tests.mk3
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/metadata/csearch.rs3
-rw-r--r--src/librustc/metadata/decoder.rs7
-rw-r--r--src/librustc/metadata/encoder.rs30
-rw-r--r--src/librustc/middle/check_static_recursion.rs11
-rw-r--r--src/librustc/middle/def.rs37
-rw-r--r--src/librustc/middle/pat_util.rs17
-rw-r--r--src/librustc/middle/privacy.rs104
-rw-r--r--src/librustc/middle/resolve_lifetime.rs3
-rw-r--r--src/librustc/middle/ty.rs12
-rw-r--r--src/librustc_driver/driver.rs13
-rw-r--r--src/librustc_driver/lib.rs1
-rw-r--r--src/librustc_driver/test.rs2
-rw-r--r--src/librustc_resolve/check_unused.rs161
-rw-r--r--src/librustc_resolve/lib.rs (renamed from src/librustc/middle/resolve.rs)420
-rw-r--r--src/librustc_resolve/record_exports.rs157
-rw-r--r--src/librustc_trans/trans/_match.rs3
-rw-r--r--src/librustc_trans/trans/base.rs6
-rw-r--r--src/librustc_trans/trans/context.rs16
-rw-r--r--src/librustc_typeck/lib.rs5
-rw-r--r--src/test/run-pass/issue-14254.rs16
23 files changed, 565 insertions, 475 deletions
diff --git a/mk/crates.mk b/mk/crates.mk
index fafe77c78da..e20cb06e3a8 100644
--- a/mk/crates.mk
+++ b/mk/crates.mk
@@ -53,7 +53,8 @@ TARGET_CRATES := libc std flate arena term \
                  serialize getopts collections test time rand \
                  log regex graphviz core rbml alloc \
                  unicode
-RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_driver rustc_trans rustc_back rustc_llvm 
+RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_resolve rustc_driver \
+                rustc_trans rustc_back rustc_llvm
 HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc regex_macros fmt_macros
 CRATES := $(TARGET_CRATES) $(HOST_CRATES)
 TOOLS := compiletest rustdoc rustc
@@ -67,11 +68,12 @@ DEPS_std := core libc rand alloc collections unicode \
 DEPS_graphviz := std
 DEPS_syntax := std term serialize log fmt_macros arena libc
 DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_borrowck \
-                     rustc_typeck log syntax serialize rustc_llvm rustc_trans
+                     rustc_typeck rustc_resolve log syntax serialize rustc_llvm rustc_trans
 DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back \
 	                log syntax serialize rustc_llvm
 DEPS_rustc_typeck := rustc syntax
 DEPS_rustc_borrowck := rustc log graphviz syntax
+DEPS_rustc_resolve := rustc log syntax
 DEPS_rustc := syntax flate arena serialize getopts rbml \
               time log graphviz rustc_llvm rustc_back
 DEPS_rustc_llvm := native:rustllvm libc std
@@ -118,9 +120,11 @@ DOC_CRATES := $(filter-out rustc, \
               $(filter-out rustc_trans, \
               $(filter-out rustc_typeck, \
               $(filter-out rustc_borrowck, \
+              $(filter-out rustc_resolve, \
               $(filter-out rustc_driver, \
-              $(filter-out syntax, $(CRATES)))))))
-COMPILER_DOC_CRATES := rustc rustc_trans rustc_borrowck rustc_typeck rustc_driver syntax
+              $(filter-out syntax, $(CRATES))))))))
+COMPILER_DOC_CRATES := rustc rustc_trans rustc_borrowck rustc_resolve \
+                       rustc_typeck rustc_driver syntax
 
 # This macro creates some simple definitions for each crate being built, just
 # some munging of all of the parameters above.
diff --git a/mk/tests.mk b/mk/tests.mk
index 3340f9b4969..a5495a44a11 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -21,7 +21,8 @@ $(eval $(call RUST_CRATE,coretest))
 
 TEST_TARGET_CRATES = $(filter-out core unicode,$(TARGET_CRATES)) coretest
 TEST_DOC_CRATES = $(DOC_CRATES)
-TEST_HOST_CRATES = $(filter-out rustc_typeck rustc_borrowck rustc_trans,$(HOST_CRATES))
+TEST_HOST_CRATES = $(filter-out rustc_typeck rustc_borrowck rustc_resolve rustc_trans,\
+                     $(HOST_CRATES))
 TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES)
 
 ######################################################################
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 90e9973c3f3..669a5144970 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -90,7 +90,6 @@ pub mod middle {
     pub mod reachable;
     pub mod region;
     pub mod recursion_limit;
-    pub mod resolve;
     pub mod resolve_lifetime;
     pub mod stability;
     pub mod subst;
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index a474af7c6e1..b702f4925d8 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -19,7 +19,6 @@ use metadata::cstore;
 use metadata::decoder;
 use middle::def;
 use middle::lang_items;
-use middle::resolve;
 use middle::ty;
 
 use rbml;
@@ -148,7 +147,7 @@ pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
 }
 
 pub fn get_trait_item_name_and_kind(cstore: &cstore::CStore, def: ast::DefId)
-                                    -> (ast::Name, resolve::TraitItemKind) {
+                                    -> (ast::Name, def::TraitItemKind) {
     let cdata = cstore.get_crate_data(def.krate);
     decoder::get_trait_item_name_and_kind(cstore.intr.clone(),
                                           &*cdata,
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index b89c5dbcd08..d8168814c6c 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -27,7 +27,6 @@ use metadata::tydecode::{parse_ty_data, parse_region_data, parse_def_id,
                          parse_predicate_data};
 use middle::def;
 use middle::lang_items;
-use middle::resolve::{TraitItemKind, TypeTraitItemKind};
 use middle::subst;
 use middle::ty::{ImplContainer, TraitContainer};
 use middle::ty::{mod, Ty};
@@ -785,15 +784,15 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
 pub fn get_trait_item_name_and_kind(intr: Rc<IdentInterner>,
                                     cdata: Cmd,
                                     id: ast::NodeId)
-                                    -> (ast::Name, TraitItemKind) {
+                                    -> (ast::Name, def::TraitItemKind) {
     let doc = lookup_item(id, cdata.data());
     let name = item_name(&*intr, doc);
     match item_sort(doc) {
         'r' | 'p' => {
             let explicit_self = get_explicit_self(doc);
-            (name, TraitItemKind::from_explicit_self_category(explicit_self))
+            (name, def::TraitItemKind::from_explicit_self_category(explicit_self))
         }
-        't' => (name, TypeTraitItemKind),
+        't' => (name, def::TypeTraitItemKind),
         c => {
             panic!("get_trait_item_name_and_kind(): unknown trait item kind \
                    in metadata: `{}`", c)
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index cc383aa217a..deb86397eda 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -21,10 +21,10 @@ use metadata::common::*;
 use metadata::cstore;
 use metadata::decoder;
 use metadata::tyencode;
+use middle::def;
 use middle::ty::{lookup_item_type};
 use middle::ty::{mod, Ty};
 use middle::stability;
-use middle;
 use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
 
 use serialize::Encodable;
@@ -66,7 +66,7 @@ pub type EncodeInlinedItem<'a> = |ecx: &EncodeContext,
 pub struct EncodeParams<'a, 'tcx: 'a> {
     pub diag: &'a SpanHandler,
     pub tcx: &'a ty::ctxt<'tcx>,
-    pub reexports2: &'a middle::resolve::ExportMap2,
+    pub reexports: &'a def::ExportMap,
     pub item_symbols: &'a RefCell<NodeMap<String>>,
     pub link_meta: &'a LinkMeta,
     pub cstore: &'a cstore::CStore,
@@ -77,7 +77,7 @@ pub struct EncodeParams<'a, 'tcx: 'a> {
 pub struct EncodeContext<'a, 'tcx: 'a> {
     pub diag: &'a SpanHandler,
     pub tcx: &'a ty::ctxt<'tcx>,
-    pub reexports2: &'a middle::resolve::ExportMap2,
+    pub reexports: &'a def::ExportMap,
     pub item_symbols: &'a RefCell<NodeMap<String>>,
     pub link_meta: &'a LinkMeta,
     pub cstore: &'a cstore::CStore,
@@ -379,7 +379,7 @@ fn encode_path<PI: Iterator<PathElem>>(rbml_w: &mut Encoder, path: PI) {
 }
 
 fn encode_reexported_static_method(rbml_w: &mut Encoder,
-                                   exp: &middle::resolve::Export2,
+                                   exp: &def::Export,
                                    method_def_id: DefId,
                                    method_name: ast::Name) {
     debug!("(encode reexported static method) {}::{}",
@@ -398,7 +398,7 @@ fn encode_reexported_static_method(rbml_w: &mut Encoder,
 
 fn encode_reexported_static_base_methods(ecx: &EncodeContext,
                                          rbml_w: &mut Encoder,
-                                         exp: &middle::resolve::Export2)
+                                         exp: &def::Export)
                                          -> bool {
     let impl_items = ecx.tcx.impl_items.borrow();
     match ecx.tcx.inherent_impls.borrow().get(&exp.def_id) {
@@ -428,7 +428,7 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
 
 fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
                                           rbml_w: &mut Encoder,
-                                          exp: &middle::resolve::Export2)
+                                          exp: &def::Export)
                                           -> bool {
     match ecx.tcx.trait_items_cache.borrow().get(&exp.def_id) {
         Some(trait_items) => {
@@ -449,10 +449,8 @@ fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
 fn encode_reexported_static_methods(ecx: &EncodeContext,
                                     rbml_w: &mut Encoder,
                                     mod_path: PathElems,
-                                    exp: &middle::resolve::Export2) {
+                                    exp: &def::Export) {
     if let Some(ast_map::NodeItem(item)) = ecx.tcx.map.find(exp.def_id.node) {
-        let original_name = token::get_ident(item.ident);
-
         let path_differs = ecx.tcx.map.with_path(exp.def_id.node, |path| {
             let (mut a, mut b) = (path, mod_path.clone());
             loop {
@@ -474,16 +472,16 @@ fn encode_reexported_static_methods(ecx: &EncodeContext,
         // encoded metadata for static methods relative to Bar,
         // but not yet for Foo.
         //
-        if path_differs || original_name.get() != exp.name {
+        if path_differs || item.ident.name != exp.name {
             if !encode_reexported_static_base_methods(ecx, rbml_w, exp) {
                 if encode_reexported_static_trait_methods(ecx, rbml_w, exp) {
                     debug!("(encode reexported static methods) {} [trait]",
-                           original_name);
+                           item.ident.name);
                 }
             }
             else {
                 debug!("(encode reexported static methods) {} [base]",
-                       original_name);
+                       item.ident.name);
             }
         }
     }
@@ -519,7 +517,7 @@ fn encode_reexports(ecx: &EncodeContext,
                     id: NodeId,
                     path: PathElems) {
     debug!("(encoding info for module) encoding reexports for {}", id);
-    match ecx.reexports2.get(&id) {
+    match ecx.reexports.get(&id) {
         Some(ref exports) => {
             debug!("(encoding info for module) found reexports for {}", id);
             for exp in exports.iter() {
@@ -534,7 +532,7 @@ fn encode_reexports(ecx: &EncodeContext,
                 rbml_w.wr_str(def_to_string(exp.def_id).as_slice());
                 rbml_w.end_tag();
                 rbml_w.start_tag(tag_items_data_item_reexport_name);
-                rbml_w.wr_str(exp.name.as_slice());
+                rbml_w.wr_str(exp.name.as_str());
                 rbml_w.end_tag();
                 rbml_w.end_tag();
                 encode_reexported_static_methods(ecx, rbml_w, path.clone(), exp);
@@ -2071,7 +2069,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
         item_symbols,
         diag,
         tcx,
-        reexports2,
+        reexports,
         cstore,
         encode_inlined_item,
         link_meta,
@@ -2081,7 +2079,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
     let ecx = EncodeContext {
         diag: diag,
         tcx: tcx,
-        reexports2: reexports2,
+        reexports: reexports,
         item_symbols: item_symbols,
         link_meta: link_meta,
         cstore: cstore,
diff --git a/src/librustc/middle/check_static_recursion.rs b/src/librustc/middle/check_static_recursion.rs
index b32eb64025f..90242a3252e 100644
--- a/src/librustc/middle/check_static_recursion.rs
+++ b/src/librustc/middle/check_static_recursion.rs
@@ -12,8 +12,7 @@
 // recursively.
 
 use session::Session;
-use middle::resolve;
-use middle::def::{DefStatic, DefConst};
+use middle::def::{DefStatic, DefConst, DefMap};
 
 use syntax::ast;
 use syntax::{ast_util, ast_map};
@@ -22,7 +21,7 @@ use syntax::visit;
 
 struct CheckCrateVisitor<'a, 'ast: 'a> {
     sess: &'a Session,
-    def_map: &'a resolve::DefMap,
+    def_map: &'a DefMap,
     ast_map: &'a ast_map::Map<'ast>
 }
 
@@ -34,7 +33,7 @@ impl<'v, 'a, 'ast> Visitor<'v> for CheckCrateVisitor<'a, 'ast> {
 
 pub fn check_crate<'ast>(sess: &Session,
                          krate: &ast::Crate,
-                         def_map: &resolve::DefMap,
+                         def_map: &DefMap,
                          ast_map: &ast_map::Map<'ast>) {
     let mut visitor = CheckCrateVisitor {
         sess: sess,
@@ -60,7 +59,7 @@ struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
     root_it: &'a ast::Item,
     sess: &'a Session,
     ast_map: &'a ast_map::Map<'ast>,
-    def_map: &'a resolve::DefMap,
+    def_map: &'a DefMap,
     idstack: Vec<ast::NodeId>
 }
 
@@ -68,7 +67,7 @@ struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
 // FIXME: Should use the dependency graph when it's available (#1356)
 pub fn check_item_recursion<'a>(sess: &'a Session,
                                 ast_map: &'a ast_map::Map,
-                                def_map: &'a resolve::DefMap,
+                                def_map: &'a DefMap,
                                 it: &'a ast::Item) {
 
     let mut visitor = CheckItemRecursionVisitor {
diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs
index 20a0dbdc1ee..a582907612f 100644
--- a/src/librustc/middle/def.rs
+++ b/src/librustc/middle/def.rs
@@ -10,11 +10,16 @@
 
 pub use self::Def::*;
 pub use self::MethodProvenance::*;
+pub use self::TraitItemKind::*;
 
 use middle::subst::ParamSpace;
+use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
+use util::nodemap::NodeMap;
 use syntax::ast;
 use syntax::ast_util::local_def;
 
+use std::cell::RefCell;
+
 #[deriving(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum Def {
     DefFn(ast::DefId, bool /* is_ctor */),
@@ -56,6 +61,18 @@ pub enum Def {
     DefMethod(ast::DefId /* method */, Option<ast::DefId> /* trait */, MethodProvenance),
 }
 
+// Definition mapping
+pub type DefMap = RefCell<NodeMap<Def>>;
+// This is the replacement export map. It maps a module to all of the exports
+// within.
+pub type ExportMap = NodeMap<Vec<Export>>;
+
+#[deriving(Copy)]
+pub struct Export {
+    pub name: ast::Name,    // The name of the target.
+    pub def_id: ast::DefId, // The definition of the target.
+}
+
 #[deriving(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum MethodProvenance {
     FromTrait(ast::DefId),
@@ -88,6 +105,25 @@ impl TyParamProvenance {
     }
 }
 
+#[deriving(Clone, Copy, Eq, PartialEq)]
+pub enum TraitItemKind {
+    NonstaticMethodTraitItemKind,
+    StaticMethodTraitItemKind,
+    TypeTraitItemKind,
+}
+
+impl TraitItemKind {
+    pub fn from_explicit_self_category(explicit_self_category:
+                                       ExplicitSelfCategory)
+                                       -> TraitItemKind {
+        if explicit_self_category == StaticExplicitSelfCategory {
+            StaticMethodTraitItemKind
+        } else {
+            NonstaticMethodTraitItemKind
+        }
+    }
+}
+
 impl Def {
     pub fn def_id(&self) -> ast::DefId {
         match *self {
@@ -122,4 +158,3 @@ impl Def {
         }
     }
 }
-
diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs
index 8ef8e091c94..0a6c29d1cb6 100644
--- a/src/librustc/middle/pat_util.rs
+++ b/src/librustc/middle/pat_util.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use middle::def::*;
-use middle::resolve;
 use middle::ty;
 use util::nodemap::FnvHashMap;
 
@@ -21,7 +20,7 @@ pub type PatIdMap = FnvHashMap<ast::Ident, ast::NodeId>;
 
 // This is used because same-named variables in alternative patterns need to
 // use the NodeId of their namesake in the first pattern.
-pub fn pat_id_map(dm: &resolve::DefMap, pat: &ast::Pat) -> PatIdMap {
+pub fn pat_id_map(dm: &DefMap, pat: &ast::Pat) -> PatIdMap {
     let mut map = FnvHashMap::new();
     pat_bindings(dm, pat, |_bm, p_id, _s, path1| {
         map.insert(path1.node, p_id);
@@ -29,7 +28,7 @@ pub fn pat_id_map(dm: &resolve::DefMap, pat: &ast::Pat) -> PatIdMap {
     map
 }
 
-pub fn pat_is_refutable(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_refutable(dm: &DefMap, pat: &ast::Pat) -> bool {
     match pat.node {
         ast::PatLit(_) | ast::PatRange(_, _) => true,
         ast::PatEnum(_, _) |
@@ -45,7 +44,7 @@ pub fn pat_is_refutable(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
     }
 }
 
-pub fn pat_is_variant_or_struct(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &ast::Pat) -> bool {
     match pat.node {
         ast::PatEnum(_, _) |
         ast::PatIdent(_, _, None) |
@@ -59,7 +58,7 @@ pub fn pat_is_variant_or_struct(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
     }
 }
 
-pub fn pat_is_const(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_const(dm: &DefMap, pat: &ast::Pat) -> bool {
     match pat.node {
         ast::PatIdent(_, _, None) | ast::PatEnum(..) => {
             match dm.borrow().get(&pat.id) {
@@ -71,7 +70,7 @@ pub fn pat_is_const(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
     }
 }
 
-pub fn pat_is_binding(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_binding(dm: &DefMap, pat: &ast::Pat) -> bool {
     match pat.node {
         ast::PatIdent(..) => {
             !pat_is_variant_or_struct(dm, pat) &&
@@ -81,7 +80,7 @@ pub fn pat_is_binding(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
     }
 }
 
-pub fn pat_is_binding_or_wild(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_binding_or_wild(dm: &DefMap, pat: &ast::Pat) -> bool {
     match pat.node {
         ast::PatIdent(..) => pat_is_binding(dm, pat),
         ast::PatWild(_) => true,
@@ -91,7 +90,7 @@ pub fn pat_is_binding_or_wild(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
 
 /// Call `it` on every "binding" in a pattern, e.g., on `a` in
 /// `match foo() { Some(a) => (), None => () }`
-pub fn pat_bindings<I>(dm: &resolve::DefMap, pat: &ast::Pat, mut it: I) where
+pub fn pat_bindings<I>(dm: &DefMap, pat: &ast::Pat, mut it: I) where
     I: FnMut(ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent),
 {
     walk_pat(pat, |p| {
@@ -107,7 +106,7 @@ pub fn pat_bindings<I>(dm: &resolve::DefMap, pat: &ast::Pat, mut it: I) where
 
 /// Checks if the pattern contains any patterns that bind something to
 /// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`.
-pub fn pat_contains_bindings(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_contains_bindings(dm: &DefMap, pat: &ast::Pat) -> bool {
     let mut contains_bindings = false;
     walk_pat(pat, |p| {
         if pat_is_binding(dm, p) {
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index 8cce1321d72..8c566dd288e 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -11,17 +11,20 @@
 //! A pass that checks to make sure private fields and methods aren't used
 //! outside their scopes. This pass will also generate a set of exported items
 //! which are available for use externally when compiled as a library.
+pub use self::PrivateDep::*;
+pub use self::ImportUse::*;
+pub use self::LastPrivate::*;
 use self::PrivacyResult::*;
 use self::FieldName::*;
 
 use std::mem::replace;
 
 use metadata::csearch;
-use middle::{def, resolve};
+use middle::def;
 use middle::ty::{mod, Ty};
 use middle::ty::{MethodCall, MethodMap, MethodOrigin, MethodParam, MethodTypeParam};
 use middle::ty::{MethodStatic, MethodStaticUnboxedClosure, MethodObject, MethodTraitObject};
-use util::nodemap::{NodeMap, NodeSet};
+use util::nodemap::{DefIdSet, NodeMap, NodeSet};
 
 use syntax::{ast, ast_map};
 use syntax::ast_util::{is_local, local_def, PostExpansionMethod};
@@ -29,16 +32,59 @@ use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::visit::{mod, Visitor};
 
-type Context<'a, 'tcx> = (&'a MethodMap<'tcx>, &'a resolve::ExportMap2);
+type Context<'a, 'tcx> = (&'a MethodMap<'tcx>, &'a def::ExportMap);
 
 /// A set of AST nodes exported by the crate.
 pub type ExportedItems = NodeSet;
 
+/// A set containing all exported definitions from external crates.
+/// The set does not contain any entries from local crates.
+pub type ExternalExports = DefIdSet;
+
 /// A set of AST nodes that are fully public in the crate. This map is used for
 /// documentation purposes (reexporting a private struct inlines the doc,
 /// reexporting a public struct doesn't inline the doc).
 pub type PublicItems = NodeSet;
 
+// FIXME: dox
+pub type LastPrivateMap = NodeMap<LastPrivate>;
+
+#[deriving(Copy, Show)]
+pub enum LastPrivate {
+    LastMod(PrivateDep),
+    // `use` directives (imports) can refer to two separate definitions in the
+    // type and value namespaces. We record here the last private node for each
+    // and whether the import is in fact used for each.
+    // If the Option<PrivateDep> fields are None, it means there is no definition
+    // in that namespace.
+    LastImport{value_priv: Option<PrivateDep>,
+               value_used: ImportUse,
+               type_priv: Option<PrivateDep>,
+               type_used: ImportUse},
+}
+
+#[deriving(Copy, Show)]
+pub enum PrivateDep {
+    AllPublic,
+    DependsOn(ast::DefId),
+}
+
+// How an import is used.
+#[deriving(Copy, PartialEq, Show)]
+pub enum ImportUse {
+    Unused,       // The import is not used.
+    Used,         // The import is used.
+}
+
+impl LastPrivate {
+    pub fn or(self, other: LastPrivate) -> LastPrivate {
+        match (self, other) {
+            (me, LastMod(AllPublic)) => me,
+            (_, other) => other,
+        }
+    }
+}
+
 /// Result of a checking operation - None => no errors were found. Some => an
 /// error and contains the span and message for reporting that error and
 /// optionally the same for a note about the error.
@@ -136,7 +182,7 @@ impl<'v> Visitor<'v> for ParentVisitor {
 
 struct EmbargoVisitor<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
-    exp_map2: &'a resolve::ExportMap2,
+    export_map: &'a def::ExportMap,
 
     // This flag is an indicator of whether the previous item in the
     // hierarchical chain was exported or not. This is the indicator of whether
@@ -342,8 +388,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
         // This code is here instead of in visit_item so that the
         // crate module gets processed as well.
         if self.prev_exported {
-            assert!(self.exp_map2.contains_key(&id), "wut {}", id);
-            for export in self.exp_map2[id].iter() {
+            assert!(self.export_map.contains_key(&id), "wut {}", id);
+            for export in self.export_map[id].iter() {
                 if is_local(export.def_id) {
                     self.reexports.insert(export.def_id.node);
                 }
@@ -362,8 +408,8 @@ struct PrivacyVisitor<'a, 'tcx: 'a> {
     curitem: ast::NodeId,
     in_foreign: bool,
     parents: NodeMap<ast::NodeId>,
-    external_exports: resolve::ExternalExports,
-    last_private_map: resolve::LastPrivateMap,
+    external_exports: ExternalExports,
+    last_private_map: LastPrivateMap,
 }
 
 enum PrivacyResult {
@@ -719,25 +765,25 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
             };
 
             match self.last_private_map[path_id] {
-                resolve::LastMod(resolve::AllPublic) => {},
-                resolve::LastMod(resolve::DependsOn(def)) => {
+                LastMod(AllPublic) => {},
+                LastMod(DependsOn(def)) => {
                     self.report_error(ck_public(def));
                 },
-                resolve::LastImport{value_priv,
-                                    value_used: check_value,
-                                    type_priv,
-                                    type_used: check_type} => {
+                LastImport { value_priv,
+                             value_used: check_value,
+                             type_priv,
+                             type_used: check_type } => {
                     // This dance with found_error is because we don't want to report
                     // a privacy error twice for the same directive.
                     let found_error = match (type_priv, check_type) {
-                        (Some(resolve::DependsOn(def)), resolve::Used) => {
+                        (Some(DependsOn(def)), Used) => {
                             !self.report_error(ck_public(def))
                         },
                         _ => false,
                     };
                     if !found_error {
                         match (value_priv, check_value) {
-                            (Some(resolve::DependsOn(def)), resolve::Used) => {
+                            (Some(DependsOn(def)), Used) => {
                                 self.report_error(ck_public(def));
                             },
                             _ => {},
@@ -749,24 +795,24 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
                     // be illegal. We only report one error, even if it is
                     // illegal to import from both namespaces.
                     match (value_priv, check_value, type_priv, check_type) {
-                        (Some(p), resolve::Unused, None, _) |
-                        (None, _, Some(p), resolve::Unused) => {
+                        (Some(p), Unused, None, _) |
+                        (None, _, Some(p), Unused) => {
                             let p = match p {
-                                resolve::AllPublic => None,
-                                resolve::DependsOn(def) => ck_public(def),
+                                AllPublic => None,
+                                DependsOn(def) => ck_public(def),
                             };
                             if p.is_some() {
                                 self.report_error(p);
                             }
                         },
-                        (Some(v), resolve::Unused, Some(t), resolve::Unused) => {
+                        (Some(v), Unused, Some(t), Unused) => {
                             let v = match v {
-                                resolve::AllPublic => None,
-                                resolve::DependsOn(def) => ck_public(def),
+                                AllPublic => None,
+                                DependsOn(def) => ck_public(def),
                             };
                             let t = match t {
-                                resolve::AllPublic => None,
-                                resolve::DependsOn(def) => ck_public(def),
+                                AllPublic => None,
+                                DependsOn(def) => ck_public(def),
                             };
                             if let (Some(_), Some(t)) = (v, t) {
                                 self.report_error(Some(t));
@@ -1520,9 +1566,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
 }
 
 pub fn check_crate(tcx: &ty::ctxt,
-                   exp_map2: &resolve::ExportMap2,
-                   external_exports: resolve::ExternalExports,
-                   last_private_map: resolve::LastPrivateMap)
+                   export_map: &def::ExportMap,
+                   external_exports: ExternalExports,
+                   last_private_map: LastPrivateMap)
                    -> (ExportedItems, PublicItems) {
     let krate = tcx.map.krate();
 
@@ -1561,7 +1607,7 @@ pub fn check_crate(tcx: &ty::ctxt,
         exported_items: NodeSet::new(),
         public_items: NodeSet::new(),
         reexports: NodeSet::new(),
-        exp_map2: exp_map2,
+        export_map: export_map,
         prev_exported: true,
         prev_public: true,
     };
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 2202137d149..c8f53df6727 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -19,9 +19,8 @@ pub use self::DefRegion::*;
 use self::ScopeChain::*;
 
 use session::Session;
-use middle::def;
+use middle::def::{mod, DefMap};
 use middle::region;
-use middle::resolve::DefMap;
 use middle::subst;
 use middle::ty;
 use std::fmt;
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index acf1fced72c..d5c97bd6aa6 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -46,13 +46,12 @@ use lint;
 use metadata::csearch;
 use middle;
 use middle::const_eval;
-use middle::def;
+use middle::def::{mod, DefMap, ExportMap};
 use middle::dependency_format;
 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem};
 use middle::lang_items::{FnOnceTraitLangItem, TyDescStructLangItem};
 use middle::mem_categorization as mc;
 use middle::region;
-use middle::resolve;
 use middle::resolve_lifetime;
 use middle::infer;
 use middle::stability;
@@ -99,7 +98,7 @@ pub const INITIAL_DISCRIMINANT_VALUE: Disr = 0;
 /// The complete set of all analyses described in this module. This is
 /// produced by the driver and fed to trans and later passes.
 pub struct CrateAnalysis<'tcx> {
-    pub exp_map2: middle::resolve::ExportMap2,
+    pub export_map: ExportMap,
     pub exported_items: middle::privacy::ExportedItems,
     pub public_items: middle::privacy::PublicItems,
     pub ty_cx: ty::ctxt<'tcx>,
@@ -615,7 +614,7 @@ pub struct ctxt<'tcx> {
     // queried from a HashSet.
     interner: RefCell<FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>>,
     pub sess: Session,
-    pub def_map: resolve::DefMap,
+    pub def_map: DefMap,
 
     pub named_region_map: resolve_lifetime::NamedRegionMap,
 
@@ -1967,7 +1966,7 @@ impl UnboxedClosureKind {
 
 pub fn mk_ctxt<'tcx>(s: Session,
                      type_arena: &'tcx TypedArena<TyS<'tcx>>,
-                     dm: resolve::DefMap,
+                     dm: DefMap,
                      named_region_map: resolve_lifetime::NamedRegionMap,
                      map: ast_map::Map<'tcx>,
                      freevars: RefCell<FreevarMap>,
@@ -6263,6 +6262,9 @@ pub type FreevarMap = NodeMap<Vec<Freevar>>;
 
 pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
 
+// Trait method resolution
+pub type TraitMap = NodeMap<Vec<DefId>>;
+
 pub fn with_freevars<T, F>(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where
     F: FnOnce(&[Freevar]) -> T,
 {
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 9ed4f46c168..60b890b0370 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -20,6 +20,7 @@ use rustc::plugin::registry::Registry;
 use rustc::plugin;
 use rustc::util::common::time;
 use rustc_borrowck as borrowck;
+use rustc_resolve as resolve;
 use rustc_trans::back::link;
 use rustc_trans::back::write;
 use rustc_trans::save;
@@ -341,17 +342,17 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
     let lang_items = time(time_passes, "language item collection", (), |_|
                           middle::lang_items::collect_language_items(krate, &sess));
 
-    let middle::resolve::CrateMap {
+    let resolve::CrateMap {
         def_map,
         freevars,
         capture_mode_map,
-        exp_map2,
+        export_map,
         trait_map,
         external_exports,
         last_private_map
     } =
-        time(time_passes, "resolution", (), |_|
-             middle::resolve::resolve_crate(&sess, &lang_items, krate));
+        time(time_passes, "resolution", (),
+             |_| resolve::resolve_crate(&sess, &lang_items, krate));
 
     // Discard MTWT tables that aren't required past resolution.
     syntax::ext::mtwt::clear_tables();
@@ -406,7 +407,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
     let maps = (external_exports, last_private_map);
     let (exported_items, public_items) =
             time(time_passes, "privacy checking", maps, |(a, b)|
-                 middle::privacy::check_crate(&ty_cx, &exp_map2, a, b));
+                 middle::privacy::check_crate(&ty_cx, &export_map, a, b));
 
     time(time_passes, "intrinsic checking", (), |_|
          middle::intrinsicck::check_crate(&ty_cx));
@@ -447,7 +448,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
          lint::check_crate(&ty_cx, &exported_items));
 
     ty::CrateAnalysis {
-        exp_map2: exp_map2,
+        export_map: export_map,
         ty_cx: ty_cx,
         exported_items: exported_items,
         public_items: public_items,
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 120654678e9..34d9fd6bcad 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -35,6 +35,7 @@ extern crate libc;
 extern crate rustc;
 extern crate rustc_back;
 extern crate rustc_borrowck;
+extern crate rustc_resolve;
 extern crate rustc_trans;
 extern crate rustc_typeck;
 #[phase(plugin, link)] extern crate log;
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index b2c661cc58a..090d6a7a3ca 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -13,9 +13,9 @@
 use diagnostic;
 use diagnostic::Emitter;
 use driver;
+use rustc_resolve as resolve;
 use rustc_typeck::middle::lang_items;
 use rustc_typeck::middle::region::{mod, CodeExtent};
-use rustc_typeck::middle::resolve;
 use rustc_typeck::middle::resolve_lifetime;
 use rustc_typeck::middle::stability;
 use rustc_typeck::middle::subst;
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
new file mode 100644
index 00000000000..39cdf6fc8f3
--- /dev/null
+++ b/src/librustc_resolve/check_unused.rs
@@ -0,0 +1,161 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+//
+// Unused import checking
+//
+// Although this is mostly a lint pass, it lives in here because it depends on
+// resolve data structures and because it finalises the privacy information for
+// `use` directives.
+//
+
+use Resolver;
+use Namespace::{TypeNS, ValueNS};
+
+use rustc::lint;
+use rustc::middle::privacy::{DependsOn, LastImport, Used, Unused};
+use syntax::ast;
+use syntax::ast::{ViewItem, ViewItemExternCrate, ViewItemUse};
+use syntax::ast::{ViewPathGlob, ViewPathList, ViewPathSimple};
+use syntax::codemap::{Span, DUMMY_SP};
+use syntax::visit::{mod, Visitor};
+
+struct UnusedImportCheckVisitor<'a, 'b:'a> {
+    resolver: &'a mut Resolver<'b>
+}
+
+// Deref and DerefMut impls allow treating UnusedImportCheckVisitor as Resolver.
+impl<'a, 'b> Deref<Resolver<'b>> for UnusedImportCheckVisitor<'a, 'b> {
+    fn deref<'c>(&'c self) -> &'c Resolver<'b> {
+        &*self.resolver
+    }
+}
+
+impl<'a, 'b> DerefMut<Resolver<'b>> for UnusedImportCheckVisitor<'a, 'b> {
+    fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b> {
+        &mut *self.resolver
+    }
+}
+
+impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> {
+    // We have information about whether `use` (import) directives are actually used now.
+    // If an import is not used at all, we signal a lint error. If an import is only used
+    // for a single namespace, we remove the other namespace from the recorded privacy
+    // information. That means in privacy.rs, we will only check imports and namespaces
+    // which are used. In particular, this means that if an import could name either a
+    // public or private item, we will check the correct thing, dependent on how the import
+    // is used.
+    fn finalize_import(&mut self, id: ast::NodeId, span: Span) {
+        debug!("finalizing import uses for {}",
+                self.session.codemap().span_to_snippet(span));
+
+        if !self.used_imports.contains(&(id, TypeNS)) &&
+           !self.used_imports.contains(&(id, ValueNS)) {
+            self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
+                                  id,
+                                  span,
+                                  "unused import".to_string());
+        }
+
+        let (v_priv, t_priv) = match self.last_private.get(&id) {
+            Some(&LastImport {
+                value_priv: v,
+                value_used: _,
+                type_priv: t,
+                type_used: _
+            }) => (v, t),
+            Some(_) => {
+                panic!("we should only have LastImport for `use` directives")
+            }
+            _ => return,
+        };
+
+        let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
+            Used
+        } else {
+            Unused
+        };
+        let t_used = if self.used_imports.contains(&(id, TypeNS)) {
+            Used
+        } else {
+            Unused
+        };
+
+        match (v_priv, t_priv) {
+            // Since some items may be both in the value _and_ type namespaces (e.g., structs)
+            // we might have two LastPrivates pointing at the same thing. There is no point
+            // checking both, so lets not check the value one.
+            (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
+            _ => {},
+        }
+
+        self.last_private.insert(id, LastImport{value_priv: v_priv,
+                                                value_used: v_used,
+                                                type_priv: t_priv,
+                                                type_used: t_used});
+    }
+}
+
+impl<'a, 'b, 'v> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b> {
+    fn visit_view_item(&mut self, vi: &ViewItem) {
+        // Ignore is_public import statements because there's no way to be sure
+        // whether they're used or not. Also ignore imports with a dummy span
+        // because this means that they were generated in some fashion by the
+        // compiler and we don't need to consider them.
+        if vi.vis == ast::Public || vi.span == DUMMY_SP {
+            visit::walk_view_item(self, vi);
+            return;
+        }
+
+        match vi.node {
+            ViewItemExternCrate(_, _, id) => {
+                if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(id) {
+                    if !self.used_crates.contains(&crate_num) {
+                        self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
+                                              id,
+                                              vi.span,
+                                              "unused extern crate".to_string());
+                    }
+                }
+            },
+            ViewItemUse(ref p) => {
+                match p.node {
+                    ViewPathSimple(_, _, id) => {
+                        self.finalize_import(id, p.span)
+                    }
+
+                    ViewPathList(_, ref list, _) => {
+                        for i in list.iter() {
+                            self.finalize_import(i.node.id(), i.span);
+                        }
+                    }
+                    ViewPathGlob(_, id) => {
+                        if !self.used_imports.contains(&(id, TypeNS)) &&
+                           !self.used_imports.contains(&(id, ValueNS)) {
+                            self.session
+                                .add_lint(lint::builtin::UNUSED_IMPORTS,
+                                          id,
+                                          p.span,
+                                          "unused import".to_string());
+                        }
+                    }
+                }
+            }
+        }
+
+        visit::walk_view_item(self, vi);
+    }
+}
+
+pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
+    let mut visitor = UnusedImportCheckVisitor { resolver: resolver };
+    visit::walk_crate(&mut visitor, krate);
+}
diff --git a/src/librustc/middle/resolve.rs b/src/librustc_resolve/lib.rs
index e1e376c537c..e1708be30d9 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc_resolve/lib.rs
@@ -8,12 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(non_camel_case_types)]
+#![crate_name = "rustc_resolve"]
+#![experimental]
+#![crate_type = "dylib"]
+#![crate_type = "rlib"]
+#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+      html_favicon_url = "http://www.rust-lang.org/favicon.ico",
+      html_root_url = "http://doc.rust-lang.org/nightly/")]
+
+#![feature(globs, phase, slicing_syntax)]
+#![feature(rustc_diagnostic_macros)]
+
+#[phase(plugin, link)] extern crate log;
+#[phase(plugin, link)] extern crate syntax;
+
+extern crate rustc;
 
-pub use self::PrivateDep::*;
-pub use self::ImportUse::*;
-pub use self::TraitItemKind::*;
-pub use self::LastPrivate::*;
 use self::PatternBindingMode::*;
 use self::Namespace::*;
 use self::NamespaceError::*;
@@ -36,26 +46,26 @@ use self::ModuleKind::*;
 use self::TraitReferenceType::*;
 use self::FallbackChecks::*;
 
-use session::Session;
-use lint;
-use metadata::csearch;
-use metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
-use middle::def::*;
-use middle::lang_items::LanguageItems;
-use middle::pat_util::pat_bindings;
-use middle::subst::{ParamSpace, FnSpace, TypeSpace};
-use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
-use middle::ty::{CaptureModeMap, Freevar, FreevarMap};
-use util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
+use rustc::session::Session;
+use rustc::lint;
+use rustc::metadata::csearch;
+use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
+use rustc::middle::def::*;
+use rustc::middle::lang_items::LanguageItems;
+use rustc::middle::pat_util::pat_bindings;
+use rustc::middle::privacy::*;
+use rustc::middle::subst::{ParamSpace, FnSpace, TypeSpace};
+use rustc::middle::ty::{CaptureModeMap, Freevar, FreevarMap, TraitMap};
+use rustc::util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
 
 use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
 use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
 use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
 use syntax::ast::{ExprPath, ExprStruct, FnDecl};
 use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
-use syntax::ast::{Ident, ImplItem, Item, ItemEnum, ItemFn, ItemForeignMod};
-use syntax::ast::{ItemImpl, ItemMac, ItemMod, ItemStatic, ItemStruct};
-use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local, ItemConst};
+use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemFn};
+use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
+use syntax::ast::{ItemStruct, ItemTrait, ItemTy, Local};
 use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
 use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
 use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
@@ -86,72 +96,17 @@ use std::mem::replace;
 use std::rc::{Rc, Weak};
 use std::uint;
 
-// Definition mapping
-pub type DefMap = RefCell<NodeMap<Def>>;
+mod check_unused;
+mod record_exports;
 
 #[deriving(Copy)]
-struct binding_info {
+struct BindingInfo {
     span: Span,
     binding_mode: BindingMode,
 }
 
 // Map from the name in a pattern to its binding mode.
-type BindingMap = HashMap<Name,binding_info>;
-
-// Trait method resolution
-pub type TraitMap = NodeMap<Vec<DefId> >;
-
-// This is the replacement export map. It maps a module to all of the exports
-// within.
-pub type ExportMap2 = NodeMap<Vec<Export2>>;
-
-pub struct Export2 {
-    pub name: String,        // The name of the target.
-    pub def_id: DefId,       // The definition of the target.
-}
-
-// This set contains all exported definitions from external crates. The set does
-// not contain any entries from local crates.
-pub type ExternalExports = DefIdSet;
-
-// FIXME: dox
-pub type LastPrivateMap = NodeMap<LastPrivate>;
-
-#[deriving(Copy, Show)]
-pub enum LastPrivate {
-    LastMod(PrivateDep),
-    // `use` directives (imports) can refer to two separate definitions in the
-    // type and value namespaces. We record here the last private node for each
-    // and whether the import is in fact used for each.
-    // If the Option<PrivateDep> fields are None, it means there is no definition
-    // in that namespace.
-    LastImport{value_priv: Option<PrivateDep>,
-               value_used: ImportUse,
-               type_priv: Option<PrivateDep>,
-               type_used: ImportUse},
-}
-
-#[deriving(Copy, Show)]
-pub enum PrivateDep {
-    AllPublic,
-    DependsOn(DefId),
-}
-
-// How an import is used.
-#[deriving(Copy, PartialEq, Show)]
-pub enum ImportUse {
-    Unused,       // The import is not used.
-    Used,         // The import is used.
-}
-
-impl LastPrivate {
-    fn or(self, other: LastPrivate) -> LastPrivate {
-        match (self, other) {
-            (me, LastMod(AllPublic)) => me,
-            (_, other) => other,
-        }
-    }
-}
+type BindingMap = HashMap<Name, BindingInfo>;
 
 #[deriving(Copy, PartialEq)]
 enum PatternBindingMode {
@@ -340,25 +295,6 @@ enum ModulePrefixResult {
     PrefixFound(Rc<Module>, uint)
 }
 
-#[deriving(Clone, Copy, Eq, PartialEq)]
-pub enum TraitItemKind {
-    NonstaticMethodTraitItemKind,
-    StaticMethodTraitItemKind,
-    TypeTraitItemKind,
-}
-
-impl TraitItemKind {
-    pub fn from_explicit_self_category(explicit_self_category:
-                                       ExplicitSelfCategory)
-                                       -> TraitItemKind {
-        if explicit_self_category == StaticExplicitSelfCategory {
-            StaticMethodTraitItemKind
-        } else {
-            NonstaticMethodTraitItemKind
-        }
-    }
-}
-
 #[deriving(Copy, PartialEq)]
 enum NameSearchType {
     /// We're doing a name search in order to resolve a `use` directive.
@@ -948,7 +884,7 @@ struct Resolver<'a> {
     freevars: RefCell<FreevarMap>,
     freevars_seen: RefCell<NodeMap<NodeSet>>,
     capture_mode_map: CaptureModeMap,
-    export_map2: ExportMap2,
+    export_map: ExportMap,
     trait_map: TraitMap,
     external_exports: ExternalExports,
     last_private: LastPrivateMap,
@@ -1002,17 +938,6 @@ impl<'a, 'b, 'v> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b> {
 
 }
 
-struct UnusedImportCheckVisitor<'a, 'b:'a> {
-    resolver: &'a mut Resolver<'b>
-}
-
-impl<'a, 'b, 'v> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b> {
-    fn visit_view_item(&mut self, vi: &ViewItem) {
-        self.resolver.check_for_item_unused_imports(vi);
-        visit::walk_view_item(self, vi);
-    }
-}
-
 #[deriving(PartialEq)]
 enum FallbackChecks {
     Everything,
@@ -1063,7 +988,7 @@ impl<'a> Resolver<'a> {
             freevars: RefCell::new(NodeMap::new()),
             freevars_seen: RefCell::new(NodeMap::new()),
             capture_mode_map: NodeMap::new(),
-            export_map2: NodeMap::new(),
+            export_map: NodeMap::new(),
             trait_map: NodeMap::new(),
             used_imports: HashSet::new(),
             used_crates: HashSet::new(),
@@ -1073,22 +998,6 @@ impl<'a> Resolver<'a> {
             emit_errors: true,
         }
     }
-    /// The main name resolution procedure.
-    fn resolve(&mut self, krate: &ast::Crate) {
-        self.build_reduced_graph(krate);
-        self.session.abort_if_errors();
-
-        self.resolve_imports();
-        self.session.abort_if_errors();
-
-        self.record_exports();
-        self.session.abort_if_errors();
-
-        self.resolve_crate(krate);
-        self.session.abort_if_errors();
-
-        self.check_for_unused_imports(krate);
-    }
 
     //
     // Reduced graph building
@@ -3800,125 +3709,6 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    // Export recording
-    //
-    // This pass simply determines what all "export" keywords refer to and
-    // writes the results into the export map.
-    //
-    // FIXME #4953 This pass will be removed once exports change to per-item.
-    // Then this operation can simply be performed as part of item (or import)
-    // processing.
-
-    fn record_exports(&mut self) {
-        let root_module = self.graph_root.get_module();
-        self.record_exports_for_module_subtree(root_module);
-    }
-
-    fn record_exports_for_module_subtree(&mut self,
-                                             module_: Rc<Module>) {
-        // If this isn't a local krate, then bail out. We don't need to record
-        // exports for nonlocal crates.
-
-        match module_.def_id.get() {
-            Some(def_id) if def_id.krate == LOCAL_CRATE => {
-                // OK. Continue.
-                debug!("(recording exports for module subtree) recording \
-                        exports for local module `{}`",
-                       self.module_to_string(&*module_));
-            }
-            None => {
-                // Record exports for the root module.
-                debug!("(recording exports for module subtree) recording \
-                        exports for root module `{}`",
-                       self.module_to_string(&*module_));
-            }
-            Some(_) => {
-                // Bail out.
-                debug!("(recording exports for module subtree) not recording \
-                        exports for `{}`",
-                       self.module_to_string(&*module_));
-                return;
-            }
-        }
-
-        self.record_exports_for_module(&*module_);
-        self.populate_module_if_necessary(&module_);
-
-        for (_, child_name_bindings) in module_.children.borrow().iter() {
-            match child_name_bindings.get_module_if_available() {
-                None => {
-                    // Nothing to do.
-                }
-                Some(child_module) => {
-                    self.record_exports_for_module_subtree(child_module);
-                }
-            }
-        }
-
-        for (_, child_module) in module_.anonymous_children.borrow().iter() {
-            self.record_exports_for_module_subtree(child_module.clone());
-        }
-    }
-
-    fn record_exports_for_module(&mut self, module_: &Module) {
-        let mut exports2 = Vec::new();
-
-        self.add_exports_for_module(&mut exports2, module_);
-        match module_.def_id.get() {
-            Some(def_id) => {
-                self.export_map2.insert(def_id.node, exports2);
-                debug!("(computing exports) writing exports for {} (some)",
-                       def_id.node);
-            }
-            None => {}
-        }
-    }
-
-    fn add_exports_of_namebindings(&mut self,
-                                   exports2: &mut Vec<Export2> ,
-                                   name: Name,
-                                   namebindings: &NameBindings,
-                                   ns: Namespace) {
-        match namebindings.def_for_namespace(ns) {
-            Some(d) => {
-                let name = token::get_name(name);
-                debug!("(computing exports) YES: export '{}' => {}",
-                       name, d.def_id());
-                exports2.push(Export2 {
-                    name: name.get().to_string(),
-                    def_id: d.def_id()
-                });
-            }
-            d_opt => {
-                debug!("(computing exports) NO: {}", d_opt);
-            }
-        }
-    }
-
-    fn add_exports_for_module(&mut self,
-                              exports2: &mut Vec<Export2> ,
-                              module_: &Module) {
-        for (name, importresolution) in module_.import_resolutions.borrow().iter() {
-            if !importresolution.is_public {
-                continue
-            }
-            let xs = [TypeNS, ValueNS];
-            for &ns in xs.iter() {
-                match importresolution.target_for_namespace(ns) {
-                    Some(target) => {
-                        debug!("(computing exports) maybe export '{}'",
-                               token::get_name(*name));
-                        self.add_exports_of_namebindings(exports2,
-                                                         *name,
-                                                         &*target.bindings,
-                                                         ns)
-                    }
-                    _ => ()
-                }
-            }
-        }
-    }
-
     // AST resolution
     //
     // We maintain a list of value ribs and type ribs.
@@ -4809,9 +4599,10 @@ impl<'a> Resolver<'a> {
         let mut result = HashMap::new();
         pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
             let name = mtwt::resolve(path1.node);
-            result.insert(name,
-                          binding_info {span: sp,
-                                        binding_mode: binding_mode});
+            result.insert(name, BindingInfo {
+                span: sp,
+                binding_mode: binding_mode
+            });
         });
         return result;
     }
@@ -6136,119 +5927,6 @@ impl<'a> Resolver<'a> {
     }
 
     //
-    // Unused import checking
-    //
-    // Although this is mostly a lint pass, it lives in here because it depends on
-    // resolve data structures and because it finalises the privacy information for
-    // `use` directives.
-    //
-
-    fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
-        let mut visitor = UnusedImportCheckVisitor{ resolver: self };
-        visit::walk_crate(&mut visitor, krate);
-    }
-
-    fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
-        // Ignore is_public import statements because there's no way to be sure
-        // whether they're used or not. Also ignore imports with a dummy span
-        // because this means that they were generated in some fashion by the
-        // compiler and we don't need to consider them.
-        if vi.vis == Public { return }
-        if vi.span == DUMMY_SP { return }
-
-        match vi.node {
-            ViewItemExternCrate(_, _, id) => {
-                if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(id) {
-                    if !self.used_crates.contains(&crate_num) {
-                        self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
-                                              id,
-                                              vi.span,
-                                              "unused extern crate".to_string());
-                    }
-                }
-            },
-            ViewItemUse(ref p) => {
-                match p.node {
-                    ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
-
-                    ViewPathList(_, ref list, _) => {
-                        for i in list.iter() {
-                            self.finalize_import(i.node.id(), i.span);
-                        }
-                    },
-                    ViewPathGlob(_, id) => {
-                        if !self.used_imports.contains(&(id, TypeNS)) &&
-                           !self.used_imports.contains(&(id, ValueNS)) {
-                            self.session
-                                .add_lint(lint::builtin::UNUSED_IMPORTS,
-                                          id,
-                                          p.span,
-                                          "unused import".to_string());
-                        }
-                    },
-                }
-            }
-        }
-    }
-
-    // We have information about whether `use` (import) directives are actually used now.
-    // If an import is not used at all, we signal a lint error. If an import is only used
-    // for a single namespace, we remove the other namespace from the recorded privacy
-    // information. That means in privacy.rs, we will only check imports and namespaces
-    // which are used. In particular, this means that if an import could name either a
-    // public or private item, we will check the correct thing, dependent on how the import
-    // is used.
-    fn finalize_import(&mut self, id: NodeId, span: Span) {
-        debug!("finalizing import uses for {}",
-               self.session.codemap().span_to_snippet(span));
-
-        if !self.used_imports.contains(&(id, TypeNS)) &&
-           !self.used_imports.contains(&(id, ValueNS)) {
-            self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
-                                  id,
-                                  span,
-                                  "unused import".to_string());
-        }
-
-        let (v_priv, t_priv) = match self.last_private.get(&id) {
-            Some(&LastImport {
-                value_priv: v,
-                value_used: _,
-                type_priv: t,
-                type_used: _
-            }) => (v, t),
-            Some(_) => {
-                panic!("we should only have LastImport for `use` directives")
-            }
-            _ => return,
-        };
-
-        let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
-            Used
-        } else {
-            Unused
-        };
-        let t_used = if self.used_imports.contains(&(id, TypeNS)) {
-            Used
-        } else {
-            Unused
-        };
-
-        match (v_priv, t_priv) {
-            // Since some items may be both in the value _and_ type namespaces (e.g., structs)
-            // we might have two LastPrivates pointing at the same thing. There is no point
-            // checking both, so lets not check the value one.
-            (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
-            _ => {},
-        }
-
-        self.last_private.insert(id, LastImport{value_priv: v_priv,
-                                                value_used: v_used,
-                                                type_priv: t_priv,
-                                                type_used: t_used});
-    }
-
-    //
     // Diagnostics
     //
     // Diagnostics are not particularly efficient, because they're rarely
@@ -6323,7 +6001,7 @@ pub struct CrateMap {
     pub def_map: DefMap,
     pub freevars: RefCell<FreevarMap>,
     pub capture_mode_map: RefCell<CaptureModeMap>,
-    pub exp_map2: ExportMap2,
+    pub export_map: ExportMap,
     pub trait_map: TraitMap,
     pub external_exports: ExternalExports,
     pub last_private_map: LastPrivateMap,
@@ -6335,12 +6013,26 @@ pub fn resolve_crate(session: &Session,
                      krate: &Crate)
                   -> CrateMap {
     let mut resolver = Resolver::new(session, krate.span);
-    resolver.resolve(krate);
+
+    resolver.build_reduced_graph(krate);
+    session.abort_if_errors();
+
+    resolver.resolve_imports();
+    session.abort_if_errors();
+
+    record_exports::record(&mut resolver);
+    session.abort_if_errors();
+
+    resolver.resolve_crate(krate);
+    session.abort_if_errors();
+
+    check_unused::check_crate(&mut resolver, krate);
+
     CrateMap {
         def_map: resolver.def_map,
         freevars: resolver.freevars,
         capture_mode_map: RefCell::new(resolver.capture_mode_map),
-        exp_map2: resolver.export_map2,
+        export_map: resolver.export_map,
         trait_map: resolver.trait_map,
         external_exports: resolver.external_exports,
         last_private_map: resolver.last_private,
diff --git a/src/librustc_resolve/record_exports.rs b/src/librustc_resolve/record_exports.rs
new file mode 100644
index 00000000000..41882a94b34
--- /dev/null
+++ b/src/librustc_resolve/record_exports.rs
@@ -0,0 +1,157 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+// Export recording
+//
+// This pass simply determines what all "export" keywords refer to and
+// writes the results into the export map.
+//
+// FIXME #4953 This pass will be removed once exports change to per-item.
+// Then this operation can simply be performed as part of item (or import)
+// processing.
+
+use {Module, NameBindings, Resolver};
+use Namespace::{mod, TypeNS, ValueNS};
+
+use rustc::middle::def::Export;
+use syntax::ast;
+use syntax::parse::token;
+
+use std::rc::Rc;
+
+struct ExportRecorder<'a, 'b:'a> {
+    resolver: &'a mut Resolver<'b>
+}
+
+// Deref and DerefMut impls allow treating ExportRecorder as Resolver.
+impl<'a, 'b> Deref<Resolver<'b>> for ExportRecorder<'a, 'b> {
+    fn deref<'c>(&'c self) -> &'c Resolver<'b> {
+        &*self.resolver
+    }
+}
+
+impl<'a, 'b> DerefMut<Resolver<'b>> for ExportRecorder<'a, 'b> {
+    fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b> {
+        &mut *self.resolver
+    }
+}
+
+impl<'a, 'b> ExportRecorder<'a, 'b> {
+    fn record_exports_for_module_subtree(&mut self,
+                                         module_: Rc<Module>) {
+        // If this isn't a local krate, then bail out. We don't need to record
+        // exports for nonlocal crates.
+
+        match module_.def_id.get() {
+            Some(def_id) if def_id.krate == ast::LOCAL_CRATE => {
+                // OK. Continue.
+                debug!("(recording exports for module subtree) recording \
+                        exports for local module `{}`",
+                       self.module_to_string(&*module_));
+            }
+            None => {
+                // Record exports for the root module.
+                debug!("(recording exports for module subtree) recording \
+                        exports for root module `{}`",
+                       self.module_to_string(&*module_));
+            }
+            Some(_) => {
+                // Bail out.
+                debug!("(recording exports for module subtree) not recording \
+                        exports for `{}`",
+                       self.module_to_string(&*module_));
+                return;
+            }
+        }
+
+        self.record_exports_for_module(&*module_);
+        self.populate_module_if_necessary(&module_);
+
+        for (_, child_name_bindings) in module_.children.borrow().iter() {
+            match child_name_bindings.get_module_if_available() {
+                None => {
+                    // Nothing to do.
+                }
+                Some(child_module) => {
+                    self.record_exports_for_module_subtree(child_module);
+                }
+            }
+        }
+
+        for (_, child_module) in module_.anonymous_children.borrow().iter() {
+            self.record_exports_for_module_subtree(child_module.clone());
+        }
+    }
+
+    fn record_exports_for_module(&mut self, module_: &Module) {
+        let mut exports = Vec::new();
+
+        self.add_exports_for_module(&mut exports, module_);
+        match module_.def_id.get() {
+            Some(def_id) => {
+                self.export_map.insert(def_id.node, exports);
+                debug!("(computing exports) writing exports for {} (some)",
+                       def_id.node);
+            }
+            None => {}
+        }
+    }
+
+    fn add_exports_of_namebindings(&mut self,
+                                   exports: &mut Vec<Export>,
+                                   name: ast::Name,
+                                   namebindings: &NameBindings,
+                                   ns: Namespace) {
+        match namebindings.def_for_namespace(ns) {
+            Some(d) => {
+                debug!("(computing exports) YES: export '{}' => {}",
+                       name, d.def_id());
+                exports.push(Export {
+                    name: name,
+                    def_id: d.def_id()
+                });
+            }
+            d_opt => {
+                debug!("(computing exports) NO: {}", d_opt);
+            }
+        }
+    }
+
+    fn add_exports_for_module(&mut self,
+                              exports: &mut Vec<Export>,
+                              module_: &Module) {
+        for (name, importresolution) in module_.import_resolutions.borrow().iter() {
+            if !importresolution.is_public {
+                continue
+            }
+            let xs = [TypeNS, ValueNS];
+            for &ns in xs.iter() {
+                match importresolution.target_for_namespace(ns) {
+                    Some(target) => {
+                        debug!("(computing exports) maybe export '{}'",
+                               token::get_name(*name));
+                        self.add_exports_of_namebindings(exports,
+                                                         *name,
+                                                         &*target.bindings,
+                                                         ns)
+                    }
+                    _ => ()
+                }
+            }
+        }
+    }
+}
+
+pub fn record(resolver: &mut Resolver) {
+    let mut recorder = ExportRecorder { resolver: resolver };
+    let root_module = recorder.graph_root.get_module();
+    recorder.record_exports_for_module_subtree(root_module);
+}
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs
index 1401f1ad1f5..2bcd723fc83 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -193,12 +193,11 @@ use llvm::{ValueRef, BasicBlockRef};
 use middle::check_match::StaticInliner;
 use middle::check_match;
 use middle::const_eval;
-use middle::def;
+use middle::def::{mod, DefMap};
 use middle::expr_use_visitor as euv;
 use middle::lang_items::StrEqFnLangItem;
 use middle::mem_categorization as mc;
 use middle::pat_util::*;
-use middle::resolve::DefMap;
 use trans::adt;
 use trans::base::*;
 use trans::build::{AddCase, And, BitCast, Br, CondBr, GEPi, InBoundsGEP, Load};
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 25fbaa66776..b0ef2257a0a 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -2938,7 +2938,7 @@ pub fn crate_ctxt_to_encode_parms<'a, 'tcx>(cx: &'a SharedCrateContext<'tcx>,
     encoder::EncodeParams {
         diag: cx.sess().diagnostic(),
         tcx: cx.tcx(),
-        reexports2: cx.exp_map2(),
+        reexports: cx.export_map(),
         item_symbols: cx.item_symbols(),
         link_meta: cx.link_meta(),
         cstore: &cx.sess().cstore,
@@ -3071,7 +3071,7 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
 
 pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
                          -> (ty::ctxt<'tcx>, CrateTranslation) {
-    let ty::CrateAnalysis { ty_cx: tcx, exp_map2, reachable, name, .. } = analysis;
+    let ty::CrateAnalysis { ty_cx: tcx, export_map, reachable, name, .. } = analysis;
     let krate = tcx.map.krate();
 
     // Before we touch LLVM, make sure that multithreading is enabled.
@@ -3098,7 +3098,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
     let shared_ccx = SharedCrateContext::new(link_meta.crate_name.as_slice(),
                                              codegen_units,
                                              tcx,
-                                             exp_map2,
+                                             export_map,
                                              Sha256::new(),
                                              link_meta.clone(),
                                              reachable);
diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs
index af003b01157..7b962a93990 100644
--- a/src/librustc_trans/trans/context.rs
+++ b/src/librustc_trans/trans/context.rs
@@ -13,7 +13,7 @@ use llvm::{ContextRef, ModuleRef, ValueRef, BuilderRef};
 use llvm::{TargetData};
 use llvm::mk_target_data;
 use metadata::common::LinkMeta;
-use middle::resolve;
+use middle::def::ExportMap;
 use middle::traits;
 use trans::adt;
 use trans::base;
@@ -61,7 +61,7 @@ pub struct SharedCrateContext<'tcx> {
     metadata_llmod: ModuleRef,
     metadata_llcx: ContextRef,
 
-    exp_map2: resolve::ExportMap2,
+    export_map: ExportMap,
     reachable: NodeSet,
     item_symbols: RefCell<NodeMap<String>>,
     link_meta: LinkMeta,
@@ -238,7 +238,7 @@ impl<'tcx> SharedCrateContext<'tcx> {
     pub fn new(crate_name: &str,
                local_count: uint,
                tcx: ty::ctxt<'tcx>,
-               emap2: resolve::ExportMap2,
+               export_map: ExportMap,
                symbol_hasher: Sha256,
                link_meta: LinkMeta,
                reachable: NodeSet)
@@ -251,7 +251,7 @@ impl<'tcx> SharedCrateContext<'tcx> {
             local_ccxs: Vec::with_capacity(local_count),
             metadata_llmod: metadata_llmod,
             metadata_llcx: metadata_llcx,
-            exp_map2: emap2,
+            export_map: export_map,
             reachable: reachable,
             item_symbols: RefCell::new(NodeMap::new()),
             link_meta: link_meta,
@@ -329,8 +329,8 @@ impl<'tcx> SharedCrateContext<'tcx> {
         self.metadata_llcx
     }
 
-    pub fn exp_map2<'a>(&'a self) -> &'a resolve::ExportMap2 {
-        &self.exp_map2
+    pub fn export_map<'a>(&'a self) -> &'a ExportMap {
+        &self.export_map
     }
 
     pub fn reachable<'a>(&'a self) -> &'a NodeSet {
@@ -553,8 +553,8 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         &self.local.item_vals
     }
 
-    pub fn exp_map2<'a>(&'a self) -> &'a resolve::ExportMap2 {
-        &self.shared.exp_map2
+    pub fn export_map<'a>(&'a self) -> &'a ExportMap {
+        &self.shared.export_map
     }
 
     pub fn reachable<'a>(&'a self) -> &'a NodeSet {
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 5fc2466674e..ec0313d4d8f 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -90,7 +90,6 @@ pub use rustc::session;
 pub use rustc::util;
 
 use middle::def;
-use middle::resolve;
 use middle::infer;
 use middle::subst;
 use middle::subst::VecPerParamSpace;
@@ -121,7 +120,7 @@ struct TypeAndSubsts<'tcx> {
 
 struct CrateCtxt<'a, 'tcx: 'a> {
     // A mapping from method call sites to traits that have that method.
-    trait_map: resolve::TraitMap,
+    trait_map: ty::TraitMap,
     tcx: &'a ty::ctxt<'tcx>
 }
 
@@ -316,7 +315,7 @@ fn check_for_entry_fn(ccx: &CrateCtxt) {
     }
 }
 
-pub fn check_crate(tcx: &ty::ctxt, trait_map: resolve::TraitMap) {
+pub fn check_crate(tcx: &ty::ctxt, trait_map: ty::TraitMap) {
     let time_passes = tcx.sess.time_passes();
     let ccx = CrateCtxt {
         trait_map: trait_map,
diff --git a/src/test/run-pass/issue-14254.rs b/src/test/run-pass/issue-14254.rs
index 160828d42fc..ad4ed03e6e2 100644
--- a/src/test/run-pass/issue-14254.rs
+++ b/src/test/run-pass/issue-14254.rs
@@ -24,7 +24,7 @@ impl BarTy {
     fn b(&self) {}
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl Foo for *const BarTy {
     fn bar(&self) {
         self.baz();
@@ -33,7 +33,7 @@ impl Foo for *const BarTy {
     }
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl<'a> Foo for &'a BarTy {
     fn bar(&self) {
         self.baz();
@@ -45,7 +45,7 @@ impl<'a> Foo for &'a BarTy {
     }
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl<'a> Foo for &'a mut BarTy {
     fn bar(&self) {
         self.baz();
@@ -57,7 +57,7 @@ impl<'a> Foo for &'a mut BarTy {
     }
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl Foo for Box<BarTy> {
     fn bar(&self) {
         self.baz();
@@ -65,7 +65,7 @@ impl Foo for Box<BarTy> {
     }
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl Foo for *const int {
     fn bar(&self) {
         self.baz();
@@ -73,7 +73,7 @@ impl Foo for *const int {
     }
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl<'a> Foo for &'a int {
     fn bar(&self) {
         self.baz();
@@ -81,7 +81,7 @@ impl<'a> Foo for &'a int {
     }
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl<'a> Foo for &'a mut int {
     fn bar(&self) {
         self.baz();
@@ -89,7 +89,7 @@ impl<'a> Foo for &'a mut int {
     }
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl Foo for Box<int> {
     fn bar(&self) {
         self.baz();