about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-11-26 18:20:58 +0000
committerbors <bors@rust-lang.org>2015-11-26 18:20:58 +0000
commit6ef02eff89e3d2a29eab3346bff393821df6e033 (patch)
tree076a4a0e092ef845b9b836b0853d97203a144271
parent6f3becb18ad01707584035a590746e35bd64d8e8 (diff)
parent43a6deb95f06709a1a1b333ff040373037f6c7e5 (diff)
downloadrust-6ef02eff89e3d2a29eab3346bff393821df6e033.tar.gz
rust-6ef02eff89e3d2a29eab3346bff393821df6e033.zip
Auto merge of #30043 - arielb1:split-metadata, r=nikomatsakis
This improves bootstrap times because of better parallelism - though I need to measure how much - and allows metadata to be modified without triggering a full recompile. This also ensures that metadata handling and the rest of rustc remain decoupled, which is a first step for switching to a new metadata format.

This is a [breaking-change] to all plugin authors because of the following renames:
 * `rustc::plugin` is now `rustc_plugin`
 * `rustc::metadata` is now `rustc_metadata`
 * Most data types from `rustc::metadata`, along with `LOCAL_CRATE`, are now in `rustc::middle::cstore`.
 * The CStore methods were split between the `rustc::middle::CrateStore` trait (and trait object) and the `rustc_metadata::cstore::CStore`, with an `Rc<CrateStore>` stored in the `Session`. The inner `CStore` can be accessed via the inner `Any` bound, but this is deprecated.

r? @nikomatsakis
-rw-r--r--mk/crates.mk11
-rw-r--r--src/doc/book/compiler-plugins.md12
-rw-r--r--src/doc/complement-lang-faq.md2
-rw-r--r--src/grammar/verify.rs5
-rw-r--r--src/librustc/diagnostics.rs61
-rw-r--r--src/librustc/front/map/definitions.rs2
-rw-r--r--src/librustc/front/map/mod.rs4
-rw-r--r--src/librustc/lib.rs10
-rw-r--r--src/librustc/metadata/csearch.rs409
-rw-r--r--src/librustc/metadata/inline.rs60
-rw-r--r--src/librustc/middle/const_eval.rs23
-rw-r--r--src/librustc/middle/cstore.rs407
-rw-r--r--src/librustc/middle/def_id.rs2
-rw-r--r--src/librustc/middle/dependency_format.rs82
-rw-r--r--src/librustc/middle/infer/error_reporting.rs4
-rw-r--r--src/librustc/middle/lang_items.rs15
-rw-r--r--src/librustc/middle/region.rs2
-rw-r--r--src/librustc/middle/stability.rs9
-rw-r--r--src/librustc/middle/traits/coherence.rs2
-rw-r--r--src/librustc/middle/ty/context.rs6
-rw-r--r--src/librustc/middle/ty/mod.rs67
-rw-r--r--src/librustc/middle/ty/util.rs2
-rw-r--r--src/librustc/middle/weak_lang_items.rs10
-rw-r--r--src/librustc/session/config.rs19
-rw-r--r--src/librustc/session/filesearch.rs (renamed from src/librustc/metadata/filesearch.rs)0
-rw-r--r--src/librustc/session/mod.rs18
-rw-r--r--src/librustc_driver/driver.rs20
-rw-r--r--src/librustc_driver/lib.rs41
-rw-r--r--src/librustc_driver/pretty.rs9
-rw-r--r--src/librustc_driver/test.rs8
-rw-r--r--src/librustc_lint/builtin.rs8
-rw-r--r--src/librustc_lint/lib.rs3
-rw-r--r--src/librustc_lint/unused.rs15
-rw-r--r--src/librustc_metadata/astencode.rs (renamed from src/librustc/middle/astencode.rs)28
-rw-r--r--src/librustc_metadata/common.rs (renamed from src/librustc/metadata/common.rs)8
-rw-r--r--src/librustc_metadata/creader.rs (renamed from src/librustc/metadata/creader.rs)101
-rw-r--r--src/librustc_metadata/csearch.rs487
-rw-r--r--src/librustc_metadata/cstore.rs (renamed from src/librustc/metadata/cstore.rs)73
-rw-r--r--src/librustc_metadata/decoder.rs (renamed from src/librustc/metadata/decoder.rs)85
-rw-r--r--src/librustc_metadata/diagnostics.rs77
-rw-r--r--src/librustc_metadata/encoder.rs (renamed from src/librustc/metadata/encoder.rs)28
-rw-r--r--src/librustc_metadata/index.rs (renamed from src/librustc/metadata/index.rs)0
-rw-r--r--src/librustc_metadata/lib.rs61
-rw-r--r--src/librustc_metadata/loader.rs (renamed from src/librustc/metadata/loader.rs)24
-rw-r--r--src/librustc_metadata/macro_import.rs (renamed from src/librustc/metadata/macro_import.rs)16
-rw-r--r--src/librustc_metadata/macros.rs46
-rw-r--r--src/librustc_metadata/tydecode.rs (renamed from src/librustc/metadata/tydecode.rs)0
-rw-r--r--src/librustc_metadata/tyencode.rs (renamed from src/librustc/metadata/tyencode.rs)2
-rw-r--r--src/librustc_plugin/build.rs (renamed from src/librustc/plugin/build.rs)0
-rw-r--r--src/librustc_plugin/diagnostics.rs (renamed from src/librustc/metadata/mod.rs)24
-rw-r--r--src/librustc_plugin/lib.rs (renamed from src/librustc/plugin/mod.rs)24
-rw-r--r--src/librustc_plugin/load.rs (renamed from src/librustc/plugin/load.rs)15
-rw-r--r--src/librustc_plugin/registry.rs (renamed from src/librustc/plugin/registry.rs)4
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs71
-rw-r--r--src/librustc_resolve/check_unused.rs2
-rw-r--r--src/librustc_resolve/lib.rs7
-rw-r--r--src/librustc_trans/back/archive.rs7
-rw-r--r--src/librustc_trans/back/link.rs66
-rw-r--r--src/librustc_trans/back/linker.rs6
-rw-r--r--src/librustc_trans/lib.rs2
-rw-r--r--src/librustc_trans/save/dump_csv.rs3
-rw-r--r--src/librustc_trans/save/mod.rs6
-rw-r--r--src/librustc_trans/save/recorder.rs2
-rw-r--r--src/librustc_trans/trans/base.rs62
-rw-r--r--src/librustc_trans/trans/callee.rs2
-rw-r--r--src/librustc_trans/trans/consts.rs2
-rw-r--r--src/librustc_trans/trans/context.rs2
-rw-r--r--src/librustc_trans/trans/debuginfo/metadata.rs2
-rw-r--r--src/librustc_trans/trans/inline.rs27
-rw-r--r--src/librustc_trans/trans/mod.rs2
-rw-r--r--src/librustc_typeck/check/callee.rs2
-rw-r--r--src/librustc_typeck/check/method/suggest.rs32
-rw-r--r--src/librustc_typeck/check/mod.rs2
-rw-r--r--src/librustc_typeck/coherence/orphan.rs2
-rw-r--r--src/librustc_typeck/coherence/overlap.rs7
-rw-r--r--src/librustc_typeck/lib.rs1
-rw-r--r--src/librustdoc/clean/inline.rs60
-rw-r--r--src/librustdoc/clean/mod.rs48
-rw-r--r--src/librustdoc/core.rs10
-rw-r--r--src/librustdoc/html/format.rs2
-rw-r--r--src/librustdoc/html/render.rs2
-rw-r--r--src/librustdoc/lib.rs1
-rw-r--r--src/librustdoc/test.rs19
-rw-r--r--src/test/auxiliary/attr_plugin_test.rs3
-rw-r--r--src/test/auxiliary/custom_derive_plugin.rs3
-rw-r--r--src/test/auxiliary/custom_derive_plugin_attr.rs3
-rw-r--r--src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs3
-rw-r--r--src/test/auxiliary/lint_for_crate.rs3
-rw-r--r--src/test/auxiliary/lint_group_plugin_test.rs3
-rw-r--r--src/test/auxiliary/lint_plugin_test.rs3
-rw-r--r--src/test/auxiliary/llvm_pass_plugin.rs3
-rw-r--r--src/test/auxiliary/lto-syntax-extension-plugin.rs3
-rw-r--r--src/test/auxiliary/macro_crate_MacroRulesTT.rs3
-rw-r--r--src/test/auxiliary/macro_crate_test.rs3
-rw-r--r--src/test/auxiliary/plugin_args.rs3
-rw-r--r--src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs3
-rw-r--r--src/test/auxiliary/plugin_with_plugin_lib.rs3
-rw-r--r--src/test/auxiliary/procedural_mbe_matching.rs3
-rw-r--r--src/test/auxiliary/rlib_crate_test.rs3
-rw-r--r--src/test/auxiliary/roman_numerals.rs3
-rw-r--r--src/test/auxiliary/syntax_extension_with_dll_deps_2.rs3
-rw-r--r--src/test/compile-fail/use-from-trait-xc.rs4
-rw-r--r--src/test/run-make/execution-engine/test.rs18
-rw-r--r--src/test/run-make/issue-19371/foo.rs16
-rw-r--r--src/test/run-make/libs-through-symlinks/Makefile2
105 files changed, 1760 insertions, 1244 deletions
diff --git a/mk/crates.mk b/mk/crates.mk
index 89a836eb7cb..8ce0a41d978 100644
--- a/mk/crates.mk
+++ b/mk/crates.mk
@@ -56,7 +56,8 @@ TARGET_CRATES := libc std flate arena term \
 		 alloc_system
 RUSTC_CRATES := rustc rustc_typeck rustc_mir rustc_borrowck rustc_resolve rustc_driver \
                 rustc_trans rustc_back rustc_llvm rustc_privacy rustc_lint \
-                rustc_data_structures rustc_front rustc_platform_intrinsics
+                rustc_data_structures rustc_front rustc_platform_intrinsics \
+                rustc_plugin rustc_metadata
 HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc fmt_macros
 TOOLS := compiletest rustdoc rustc rustbook error-index-generator
 
@@ -87,21 +88,23 @@ DEPS_test := std getopts serialize rbml term native:rust_test_helpers
 
 DEPS_syntax := std term serialize log fmt_macros arena libc rustc_bitflags
 
-DEPS_rustc := syntax flate arena serialize getopts rbml rustc_front\
+DEPS_rustc := syntax flate arena serialize getopts rustc_front\
               log graphviz rustc_llvm rustc_back rustc_data_structures
 DEPS_rustc_back := std syntax rustc_llvm rustc_front flate log libc
 DEPS_rustc_borrowck := rustc rustc_front log graphviz syntax
 DEPS_rustc_data_structures := std log serialize
 DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_borrowck \
                      rustc_typeck rustc_mir rustc_resolve log syntax serialize rustc_llvm \
-		             rustc_trans rustc_privacy rustc_lint rustc_front
-
+	             rustc_trans rustc_privacy rustc_lint rustc_front rustc_plugin \
+                     rustc_metadata
 DEPS_rustc_front := std syntax log serialize
 DEPS_rustc_lint := rustc log syntax
 DEPS_rustc_llvm := native:rustllvm libc std rustc_bitflags
+DEPS_rustc_metadata := rustc rustc_front syntax rbml
 DEPS_rustc_mir := rustc rustc_front syntax
 DEPS_rustc_resolve := rustc rustc_front log syntax
 DEPS_rustc_platform_intrinsics := rustc rustc_llvm
+DEPS_rustc_plugin := rustc rustc_metadata syntax
 DEPS_rustc_privacy := rustc rustc_front log syntax
 DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back rustc_mir \
                     log syntax serialize rustc_llvm rustc_front rustc_platform_intrinsics
diff --git a/src/doc/book/compiler-plugins.md b/src/doc/book/compiler-plugins.md
index 2cb62cdfca5..800be13a243 100644
--- a/src/doc/book/compiler-plugins.md
+++ b/src/doc/book/compiler-plugins.md
@@ -8,12 +8,12 @@ extend the compiler's behavior with new syntax extensions, lint checks, etc.
 A plugin is a dynamic library crate with a designated *registrar* function that
 registers extensions with `rustc`. Other crates can load these extensions using
 the crate attribute `#![plugin(...)]`.  See the
-[`rustc::plugin`](../rustc/plugin/index.html) documentation for more about the
+[`rustc_plugin`](../rustc_plugin/index.html) documentation for more about the
 mechanics of defining and loading a plugin.
 
 If present, arguments passed as `#![plugin(foo(... args ...))]` are not
 interpreted by rustc itself.  They are provided to the plugin through the
-`Registry`'s [`args` method](../rustc/plugin/registry/struct.Registry.html#method.args).
+`Registry`'s [`args` method](../rustc_plugin/registry/struct.Registry.html#method.args).
 
 In the vast majority of cases, a plugin should *only* be used through
 `#![plugin]` and not through an `extern crate` item.  Linking a plugin would
@@ -43,13 +43,14 @@ that implements Roman numeral integer literals.
 
 extern crate syntax;
 extern crate rustc;
+extern crate rustc_plugin;
 
 use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::ast::TokenTree;
 use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
 use syntax::ext::build::AstBuilder;  // trait for expr_usize
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         -> Box<MacResult + 'static> {
@@ -120,7 +121,7 @@ The advantages over a simple `fn(&str) -> u32` are:
 In addition to procedural macros, you can define new
 [`derive`](../reference.html#derive)-like attributes and other kinds of
 extensions.  See
-[`Registry::register_syntax_extension`](../rustc/plugin/registry/struct.Registry.html#method.register_syntax_extension)
+[`Registry::register_syntax_extension`](../rustc_plugin/registry/struct.Registry.html#method.register_syntax_extension)
 and the [`SyntaxExtension`
 enum](https://doc.rust-lang.org/syntax/ext/base/enum.SyntaxExtension.html).  For
 a more involved macro example, see
@@ -189,10 +190,11 @@ extern crate syntax;
 // Load rustc as a plugin to get macros
 #[macro_use]
 extern crate rustc;
+extern crate rustc_plugin;
 
 use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass,
                   EarlyLintPassObject, LintArray};
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 use syntax::ast;
 
 declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
diff --git a/src/doc/complement-lang-faq.md b/src/doc/complement-lang-faq.md
index 05c17606ce0..55abebf496d 100644
--- a/src/doc/complement-lang-faq.md
+++ b/src/doc/complement-lang-faq.md
@@ -158,7 +158,7 @@ can be combined to control the exact logging you want to see. For example, when
 debugging linking in the compiler, you might set the following:
 
 ```sh
-RUST_LOG=rustc::metadata::creader,rustc::util::filesearch,rustc::back::rpath
+RUST_LOG=rustc_metadata::creader,rustc::util::filesearch,rustc::back::rpath
 ```
 
 For a full description, see [the logging crate][1].
diff --git a/src/grammar/verify.rs b/src/grammar/verify.rs
index fe9c5aaee4c..f04830ee969 100644
--- a/src/grammar/verify.rs
+++ b/src/grammar/verify.rs
@@ -25,7 +25,9 @@ use std::path::Path;
 use syntax::parse;
 use syntax::parse::lexer;
 use rustc::session::{self, config};
+use rustc::middle::cstore::DummyCrateStore;
 
+use std::rc::Rc;
 use syntax::ast;
 use syntax::ast::Name;
 use syntax::codemap;
@@ -286,7 +288,8 @@ fn main() {
 
     let options = config::basic_options();
     let session = session::build_session(options, None,
-                                         syntax::diagnostics::registry::Registry::new(&[]));
+                                         syntax::diagnostics::registry::Registry::new(&[]),
+                                         Rc::new(DummyCrateStore));
     let filemap = session.parse_sess.codemap().new_filemap(String::from("<n/a>"), code);
     let mut lexer = lexer::StringReader::new(session.diagnostic(), filemap);
     let cm = session.codemap();
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index f4d7a318691..b4e188c498d 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -1899,51 +1899,6 @@ contain references (with a maximum lifetime of `'a`).
 [1]: https://github.com/rust-lang/rfcs/pull/1156
 "##,
 
-E0454: r##"
-A link name was given with an empty name. Erroneous code example:
-
-```
-#[link(name = "")] extern {} // error: #[link(name = "")] given with empty name
-```
-
-The rust compiler cannot link to an external library if you don't give it its
-name. Example:
-
-```
-#[link(name = "some_lib")] extern {} // ok!
-```
-"##,
-
-E0458: r##"
-An unknown "kind" was specified for a link attribute. Erroneous code example:
-
-```
-#[link(kind = "wonderful_unicorn")] extern {}
-// error: unknown kind: `wonderful_unicorn`
-```
-
-Please specify a valid "kind" value, from one of the following:
- * static
- * dylib
- * framework
-"##,
-
-E0459: r##"
-A link was used without a name parameter. Erroneous code example:
-
-```
-#[link(kind = "dylib")] extern {}
-// error: #[link(...)] specified without `name = "foo"`
-```
-
-Please add the name parameter to allow the rust compiler to find the library
-you want. Example:
-
-```
-#[link(kind = "dylib", name = "some_lib")] extern {} // ok!
-```
-"##,
-
 E0493: r##"
 A type with a destructor was assigned to an invalid type of variable. Erroneous
 code example:
@@ -2144,20 +2099,6 @@ register_diagnostics! {
     E0400, // overloaded derefs are not allowed in constants
     E0452, // malformed lint attribute
     E0453, // overruled by outer forbid
-    E0455, // native frameworks are only available on OSX targets
-    E0456, // plugin `..` is not available for triple `..`
-    E0457, // plugin `..` only found in rlib format, but must be available...
-    E0460, // found possibly newer version of crate `..`
-    E0461, // couldn't find crate `..` with expected target triple ..
-    E0462, // found staticlib `..` instead of rlib or dylib
-    E0463, // can't find crate for `..`
-    E0464, // multiple matching crates for `..`
-    E0465, // multiple .. candidates for `..` found
-    E0466, // bad macro import
-    E0467, // bad macro reexport
-    E0468, // an `extern crate` loading macros must be at the crate root
-    E0469, // imported macro not found
-    E0470, // reexported macro not found
     E0471, // constant evaluation error: ..
     E0472, // asm! is unsupported on this target
     E0473, // dereference of reference outside its lifetime
@@ -2181,6 +2122,4 @@ register_diagnostics! {
     E0491, // in type `..`, reference has a longer lifetime than the data it...
     E0492, // cannot borrow a constant which contains interior mutability
     E0495, // cannot infer an appropriate lifetime due to conflicting requirements
-    E0498, // malformed plugin attribute
-    E0514, // metadata version mismatch
 }
diff --git a/src/librustc/front/map/definitions.rs b/src/librustc/front/map/definitions.rs
index c1eb5f1f118..0f0d59e70b0 100644
--- a/src/librustc/front/map/definitions.rs
+++ b/src/librustc/front/map/definitions.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use metadata::cstore::LOCAL_CRATE;
+use middle::cstore::LOCAL_CRATE;
 use middle::def_id::{DefId, DefIndex};
 use rustc_data_structures::fnv::FnvHashMap;
 use rustc_front::hir;
diff --git a/src/librustc/front/map/mod.rs b/src/librustc/front/map/mod.rs
index 6ee6b070597..8c3da2cddd5 100644
--- a/src/librustc/front/map/mod.rs
+++ b/src/librustc/front/map/mod.rs
@@ -14,8 +14,8 @@ use self::MapEntry::*;
 use self::collector::NodeCollector;
 pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData, DisambiguatedDefPathData};
 
-use metadata::inline::InlinedItem;
-use metadata::inline::InlinedItem as II;
+use middle::cstore::InlinedItem;
+use middle::cstore::InlinedItem as II;
 use middle::def_id::DefId;
 
 use syntax::abi;
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index a81ecd38638..6da4f174e3e 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -33,7 +33,6 @@
 #![feature(const_fn)]
 #![feature(core)]
 #![feature(duration_span)]
-#![feature(dynamic_lib)]
 #![feature(enumset)]
 #![feature(hashmap_hasher)]
 #![feature(into_cow)]
@@ -68,7 +67,6 @@ extern crate rustc_back;
 extern crate rustc_front;
 extern crate rustc_data_structures;
 extern crate serialize;
-extern crate rbml;
 extern crate collections;
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
@@ -100,9 +98,8 @@ pub mod front {
 }
 
 pub mod middle {
-    pub mod expr_use_visitor; // STAGE0: increase glitch immunity
     pub mod astconv_util;
-    pub mod astencode;
+    pub mod expr_use_visitor; // STAGE0: increase glitch immunity
     pub mod cfg;
     pub mod check_const;
     pub mod check_static_recursion;
@@ -111,6 +108,7 @@ pub mod middle {
     pub mod check_no_asm;
     pub mod check_rvalues;
     pub mod const_eval;
+    pub mod cstore;
     pub mod dataflow;
     pub mod dead;
     pub mod def;
@@ -138,12 +136,8 @@ pub mod middle {
     pub mod weak_lang_items;
 }
 
-pub mod metadata;
-
 pub mod session;
 
-pub mod plugin;
-
 pub mod lint;
 
 pub mod util {
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
deleted file mode 100644
index 09dec375a69..00000000000
--- a/src/librustc/metadata/csearch.rs
+++ /dev/null
@@ -1,409 +0,0 @@
-// 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.
-
-// Searching for information from the cstore
-
-use front::map as ast_map;
-use metadata::cstore;
-use metadata::decoder;
-use metadata::inline::InlinedItem;
-use middle::def_id::{DefId, DefIndex};
-use middle::lang_items;
-use middle::ty;
-use util::nodemap::FnvHashMap;
-
-use std::rc::Rc;
-use syntax::ast;
-use syntax::attr;
-use rustc_front::hir;
-
-#[derive(Copy, Clone)]
-pub struct MethodInfo {
-    pub name: ast::Name,
-    pub def_id: DefId,
-    pub vis: hir::Visibility,
-}
-
-pub fn get_symbol(cstore: &cstore::CStore, def: DefId) -> String {
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_symbol(&cdata, def.index)
-}
-
-/// Iterates over all the language items in the given crate.
-pub fn each_lang_item<F>(cstore: &cstore::CStore,
-                         cnum: ast::CrateNum,
-                         f: F)
-                         -> bool where
-    F: FnMut(DefIndex, usize) -> bool,
-{
-    let crate_data = cstore.get_crate_data(cnum);
-    decoder::each_lang_item(&*crate_data, f)
-}
-
-/// Iterates over each child of the given item.
-pub fn each_child_of_item<F>(cstore: &cstore::CStore,
-                             def_id: DefId,
-                             callback: F) where
-    F: FnMut(decoder::DefLike, ast::Name, hir::Visibility),
-{
-    let crate_data = cstore.get_crate_data(def_id.krate);
-    let get_crate_data = |cnum| {
-        cstore.get_crate_data(cnum)
-    };
-    decoder::each_child_of_item(cstore.intr.clone(),
-                                &*crate_data,
-                                def_id.index,
-                                get_crate_data,
-                                callback)
-}
-
-/// Iterates over each top-level crate item.
-pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore,
-                                       cnum: ast::CrateNum,
-                                       callback: F) where
-    F: FnMut(decoder::DefLike, ast::Name, hir::Visibility),
-{
-    let crate_data = cstore.get_crate_data(cnum);
-    let get_crate_data = |cnum| {
-        cstore.get_crate_data(cnum)
-    };
-    decoder::each_top_level_item_of_crate(cstore.intr.clone(),
-                                          &*crate_data,
-                                          get_crate_data,
-                                          callback)
-}
-
-pub fn get_item_path(tcx: &ty::ctxt, def: DefId) -> Vec<ast_map::PathElem> {
-    let cstore = &tcx.sess.cstore;
-    let cdata = cstore.get_crate_data(def.krate);
-    let path = decoder::get_item_path(&*cdata, def.index);
-
-    cdata.with_local_path(|cpath| {
-        let mut r = Vec::with_capacity(cpath.len() + path.len());
-        r.push_all(cpath);
-        r.push_all(&path);
-        r
-    })
-}
-
-pub fn get_item_name(tcx: &ty::ctxt, def: DefId) -> ast::Name {
-    let cstore = &tcx.sess.cstore;
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_item_name(&cstore.intr, &cdata, def.index)
-}
-
-pub enum FoundAst<'ast> {
-    Found(&'ast InlinedItem),
-    FoundParent(DefId, &'ast InlinedItem),
-    NotFound,
-}
-
-// Finds the AST for this item in the crate metadata, if any.  If the item was
-// not marked for inlining, then the AST will not be present and hence none
-// will be returned.
-pub fn maybe_get_item_ast<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId,
-                                decode_inlined_item: decoder::DecodeInlinedItem)
-                                -> FoundAst<'tcx> {
-    let cstore = &tcx.sess.cstore;
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::maybe_get_item_ast(&*cdata, tcx, def.index, decode_inlined_item)
-}
-
-/// Returns information about the given implementation.
-pub fn get_impl_items(cstore: &cstore::CStore, impl_def_id: DefId)
-                      -> Vec<ty::ImplOrTraitItemId> {
-    let cdata = cstore.get_crate_data(impl_def_id.krate);
-    decoder::get_impl_items(&*cdata, impl_def_id.index)
-}
-
-pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
-                                    -> ty::ImplOrTraitItem<'tcx> {
-    let cdata = tcx.sess.cstore.get_crate_data(def.krate);
-    decoder::get_impl_or_trait_item(tcx.sess.cstore.intr.clone(),
-                                    &*cdata,
-                                    def.index,
-                                    tcx)
-}
-
-pub fn get_trait_name(cstore: &cstore::CStore, def: DefId) -> ast::Name {
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_trait_name(cstore.intr.clone(),
-                            &*cdata,
-                            def.index)
-}
-
-pub fn is_static_method(cstore: &cstore::CStore, def: DefId) -> bool {
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::is_static_method(&*cdata, def.index)
-}
-
-pub fn get_trait_item_def_ids(cstore: &cstore::CStore, def: DefId)
-                              -> Vec<ty::ImplOrTraitItemId> {
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_trait_item_def_ids(&*cdata, def.index)
-}
-
-pub fn get_item_variances(cstore: &cstore::CStore,
-                          def: DefId) -> ty::ItemVariances {
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_item_variances(&*cdata, def.index)
-}
-
-pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                        def: DefId)
-                                        -> Vec<Rc<ty::Method<'tcx>>> {
-    let cstore = &tcx.sess.cstore;
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.index, tcx)
-}
-
-pub fn get_associated_consts<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
-                                   -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
-    let cstore = &tcx.sess.cstore;
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_associated_consts(cstore.intr.clone(), &*cdata, def.index, tcx)
-}
-
-pub fn get_methods_if_impl(cstore: &cstore::CStore,
-                                  def: DefId)
-                               -> Option<Vec<MethodInfo> > {
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_methods_if_impl(cstore.intr.clone(), &*cdata, def.index)
-}
-
-pub fn get_item_attrs(cstore: &cstore::CStore,
-                      def_id: DefId)
-                      -> Vec<ast::Attribute> {
-    let cdata = cstore.get_crate_data(def_id.krate);
-    decoder::get_item_attrs(&*cdata, def_id.index)
-}
-
-pub fn get_struct_field_names(cstore: &cstore::CStore, def: DefId) -> Vec<ast::Name> {
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_struct_field_names(&cstore.intr, &*cdata, def.index)
-}
-
-pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: DefId)
-                              -> FnvHashMap<DefId, Vec<ast::Attribute>> {
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_struct_field_attrs(&*cdata)
-}
-
-pub fn get_type<'tcx>(tcx: &ty::ctxt<'tcx>,
-                      def: DefId)
-                      -> ty::TypeScheme<'tcx> {
-    let cstore = &tcx.sess.cstore;
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_type(&*cdata, def.index, tcx)
-}
-
-pub fn get_trait_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::TraitDef<'tcx> {
-    let cstore = &tcx.sess.cstore;
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_trait_def(&*cdata, def.index, tcx)
-}
-
-pub fn get_adt_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx> {
-    let cstore = &tcx.sess.cstore;
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_adt_def(&cstore.intr, &*cdata, def.index, tcx)
-}
-
-pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
-                            -> ty::GenericPredicates<'tcx>
-{
-    let cstore = &tcx.sess.cstore;
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_predicates(&*cdata, def.index, tcx)
-}
-
-pub fn get_super_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
-                                  -> ty::GenericPredicates<'tcx>
-{
-    let cstore = &tcx.sess.cstore;
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_super_predicates(&*cdata, def.index, tcx)
-}
-
-pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>,
-                               def: DefId)
-                               -> Option<hir::ImplPolarity>
-{
-    let cstore = &tcx.sess.cstore;
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_impl_polarity(&*cdata, def.index)
-}
-
-pub fn get_custom_coerce_unsized_kind<'tcx>(
-    tcx: &ty::ctxt<'tcx>,
-    def: DefId)
-    -> Option<ty::adjustment::CustomCoerceUnsized>
-{
-    let cstore = &tcx.sess.cstore;
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_custom_coerce_unsized_kind(&*cdata, def.index)
-}
-
-// Given a def_id for an impl, return the trait it implements,
-// if there is one.
-pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
-                            def: DefId)
-                            -> Option<ty::TraitRef<'tcx>> {
-    let cstore = &tcx.sess.cstore;
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_impl_trait(&*cdata, def.index, tcx)
-}
-
-pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum)
-                            -> Vec<(cstore::NativeLibraryKind, String)> {
-    let cdata = cstore.get_crate_data(crate_num);
-    decoder::get_native_libraries(&*cdata)
-}
-
-pub fn each_inherent_implementation_for_type<F>(cstore: &cstore::CStore,
-                                                def_id: DefId,
-                                                callback: F) where
-    F: FnMut(DefId),
-{
-    let cdata = cstore.get_crate_data(def_id.krate);
-    decoder::each_inherent_implementation_for_type(&*cdata, def_id.index, callback)
-}
-
-pub fn each_implementation_for_trait<F>(cstore: &cstore::CStore,
-                                        def_id: DefId,
-                                        mut callback: F) where
-    F: FnMut(DefId),
-{
-    cstore.iter_crate_data(|_, cdata| {
-        decoder::each_implementation_for_trait(cdata, def_id, &mut callback)
-    })
-}
-
-/// If the given def ID describes an item belonging to a trait (either a
-/// default method or an implementation of a trait method), returns the ID of
-/// the trait that the method belongs to. Otherwise, returns `None`.
-pub fn get_trait_of_item(cstore: &cstore::CStore,
-                         def_id: DefId,
-                         tcx: &ty::ctxt)
-                         -> Option<DefId> {
-    let cdata = cstore.get_crate_data(def_id.krate);
-    decoder::get_trait_of_item(&*cdata, def_id.index, tcx)
-}
-
-pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore,
-                                           def_id: DefId)
-    -> Option<DefId>
-{
-    let cdata = cstore.get_crate_data(def_id.krate);
-    decoder::get_tuple_struct_definition_if_ctor(&*cdata, def_id.index)
-}
-
-pub fn get_dylib_dependency_formats(cstore: &cstore::CStore,
-                                    cnum: ast::CrateNum)
-    -> Vec<(ast::CrateNum, cstore::LinkagePreference)>
-{
-    let cdata = cstore.get_crate_data(cnum);
-    decoder::get_dylib_dependency_formats(&*cdata)
-}
-
-pub fn get_missing_lang_items(cstore: &cstore::CStore, cnum: ast::CrateNum)
-    -> Vec<lang_items::LangItem>
-{
-    let cdata = cstore.get_crate_data(cnum);
-    decoder::get_missing_lang_items(&*cdata)
-}
-
-pub fn get_method_arg_names(cstore: &cstore::CStore, did: DefId)
-    -> Vec<String>
-{
-    let cdata = cstore.get_crate_data(did.krate);
-    decoder::get_method_arg_names(&*cdata, did.index)
-}
-
-pub fn get_reachable_ids(cstore: &cstore::CStore, cnum: ast::CrateNum)
-    -> Vec<DefId>
-{
-    let cdata = cstore.get_crate_data(cnum);
-    decoder::get_reachable_ids(&*cdata)
-}
-
-pub fn is_typedef(cstore: &cstore::CStore, did: DefId) -> bool {
-    let cdata = cstore.get_crate_data(did.krate);
-    decoder::is_typedef(&*cdata, did.index)
-}
-
-pub fn is_const_fn(cstore: &cstore::CStore, did: DefId) -> bool {
-    let cdata = cstore.get_crate_data(did.krate);
-    decoder::is_const_fn(&*cdata, did.index)
-}
-
-pub fn is_static(cstore: &cstore::CStore, did: DefId) -> bool {
-    let cdata = cstore.get_crate_data(did.krate);
-    decoder::is_static(&*cdata, did.index)
-}
-
-pub fn is_impl(cstore: &cstore::CStore, did: DefId) -> bool {
-    let cdata = cstore.get_crate_data(did.krate);
-    decoder::is_impl(&*cdata, did.index)
-}
-
-pub fn get_stability(cstore: &cstore::CStore,
-                     def: DefId)
-                     -> Option<attr::Stability> {
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_stability(&*cdata, def.index)
-}
-
-pub fn is_staged_api(cstore: &cstore::CStore, krate: ast::CrateNum) -> bool {
-    cstore.get_crate_data(krate).staged_api
-}
-
-pub fn get_repr_attrs(cstore: &cstore::CStore, def: DefId)
-                      -> Vec<attr::ReprAttr> {
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_repr_attrs(&*cdata, def.index)
-}
-
-pub fn is_defaulted_trait(cstore: &cstore::CStore, trait_def_id: DefId) -> bool {
-    let cdata = cstore.get_crate_data(trait_def_id.krate);
-    decoder::is_defaulted_trait(&*cdata, trait_def_id.index)
-}
-
-pub fn is_default_impl(cstore: &cstore::CStore, impl_did: DefId) -> bool {
-    let cdata = cstore.get_crate_data(impl_did.krate);
-    decoder::is_default_impl(&*cdata, impl_did.index)
-}
-
-pub fn is_extern_fn(cstore: &cstore::CStore, did: DefId,
-                    tcx: &ty::ctxt) -> bool {
-    let cdata = cstore.get_crate_data(did.krate);
-    decoder::is_extern_fn(&*cdata, did.index, tcx)
-}
-
-pub fn closure_kind<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId) -> ty::ClosureKind {
-    assert!(!def_id.is_local());
-    let cdata = tcx.sess.cstore.get_crate_data(def_id.krate);
-    decoder::closure_kind(&*cdata, def_id.index)
-}
-
-pub fn closure_ty<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId) -> ty::ClosureTy<'tcx> {
-    assert!(!def_id.is_local());
-    let cdata = tcx.sess.cstore.get_crate_data(def_id.krate);
-    decoder::closure_ty(&*cdata, def_id.index, tcx)
-}
-
-pub fn def_path(tcx: &ty::ctxt, def: DefId) -> ast_map::DefPath {
-    let cstore = &tcx.sess.cstore;
-    let cdata = cstore.get_crate_data(def.krate);
-    let path = decoder::def_path(&*cdata, def.index);
-    let local_path = cdata.local_def_path();
-    local_path.into_iter().chain(path).collect()
-}
-
diff --git a/src/librustc/metadata/inline.rs b/src/librustc/metadata/inline.rs
deleted file mode 100644
index e621a4166d7..00000000000
--- a/src/librustc/metadata/inline.rs
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2012-2015 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.
-
-use middle::def_id::DefId;
-use rustc_front::hir;
-use rustc_front::util::IdVisitor;
-use syntax::ast_util::{IdRange, IdRangeComputingVisitor, IdVisitingOperation};
-use syntax::ptr::P;
-use rustc_front::intravisit::Visitor;
-use self::InlinedItem::*;
-
-/// The data we save and restore about an inlined item or method.  This is not
-/// part of the AST that we parse from a file, but it becomes part of the tree
-/// that we trans.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum InlinedItem {
-    Item(P<hir::Item>),
-    TraitItem(DefId /* impl id */, P<hir::TraitItem>),
-    ImplItem(DefId /* impl id */, P<hir::ImplItem>),
-    Foreign(P<hir::ForeignItem>),
-}
-
-/// A borrowed version of `hir::InlinedItem`.
-pub enum InlinedItemRef<'a> {
-    Item(&'a hir::Item),
-    TraitItem(DefId, &'a hir::TraitItem),
-    ImplItem(DefId, &'a hir::ImplItem),
-    Foreign(&'a hir::ForeignItem)
-}
-
-impl InlinedItem {
-    pub fn visit<'ast,V>(&'ast self, visitor: &mut V)
-        where V: Visitor<'ast>
-    {
-        match *self {
-            Item(ref i) => visitor.visit_item(&**i),
-            Foreign(ref i) => visitor.visit_foreign_item(&**i),
-            TraitItem(_, ref ti) => visitor.visit_trait_item(ti),
-            ImplItem(_, ref ii) => visitor.visit_impl_item(ii),
-        }
-    }
-
-    pub fn visit_ids<O: IdVisitingOperation>(&self, operation: &mut O) {
-        let mut id_visitor = IdVisitor::new(operation);
-        self.visit(&mut id_visitor);
-    }
-
-    pub fn compute_id_range(&self) -> IdRange {
-        let mut visitor = IdRangeComputingVisitor::new();
-        self.visit_ids(&mut visitor);
-        visitor.result()
-    }
-}
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index e43d1628743..21ece8f381e 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -16,9 +16,8 @@ use self::EvalHint::*;
 
 use front::map as ast_map;
 use front::map::blocks::FnLikeNode;
-use metadata::csearch;
-use metadata::inline::InlinedItem;
-use middle::{astencode, def, infer, subst, traits};
+use middle::cstore::{self, CrateStore, InlinedItem};
+use middle::{def, infer, subst, traits};
 use middle::def_id::DefId;
 use middle::pat_util::def_to_path;
 use middle::ty::{self, Ty};
@@ -145,13 +144,12 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
             None => {}
         }
         let mut used_ref_id = false;
-        let expr_id = match csearch::maybe_get_item_ast(tcx, def_id,
-            Box::new(astencode::decode_inlined_item)) {
-            csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
+        let expr_id = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) {
+            cstore::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
                 hir::ItemConst(_, ref const_expr) => Some(const_expr.id),
                 _ => None
             },
-            csearch::FoundAst::Found(&InlinedItem::TraitItem(trait_id, ref ti)) => match ti.node {
+            cstore::FoundAst::Found(&InlinedItem::TraitItem(trait_id, ref ti)) => match ti.node {
                 hir::ConstTraitItem(_, _) => {
                     used_ref_id = true;
                     match maybe_ref_id {
@@ -170,7 +168,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
                 }
                 _ => None
             },
-            csearch::FoundAst::Found(&InlinedItem::ImplItem(_, ref ii)) => match ii.node {
+            cstore::FoundAst::Found(&InlinedItem::ImplItem(_, ref ii)) => match ii.node {
                 hir::ImplItemKind::Const(_, ref expr) => Some(expr.id),
                 _ => None
             },
@@ -196,15 +194,14 @@ fn inline_const_fn_from_external_crate(tcx: &ty::ctxt, def_id: DefId)
         None => {}
     }
 
-    if !csearch::is_const_fn(&tcx.sess.cstore, def_id) {
+    if !tcx.sess.cstore.is_const_fn(def_id) {
         tcx.extern_const_fns.borrow_mut().insert(def_id, ast::DUMMY_NODE_ID);
         return None;
     }
 
-    let fn_id = match csearch::maybe_get_item_ast(tcx, def_id,
-        box astencode::decode_inlined_item) {
-        csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => Some(item.id),
-        csearch::FoundAst::Found(&InlinedItem::ImplItem(_, ref item)) => Some(item.id),
+    let fn_id = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) {
+        cstore::FoundAst::Found(&InlinedItem::Item(ref item)) => Some(item.id),
+        cstore::FoundAst::Found(&InlinedItem::ImplItem(_, ref item)) => Some(item.id),
         _ => None
     };
     tcx.extern_const_fns.borrow_mut().insert(def_id,
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
new file mode 100644
index 00000000000..81375bd3a5a
--- /dev/null
+++ b/src/librustc/middle/cstore.rs
@@ -0,0 +1,407 @@
+// Copyright 2015 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.
+
+// Copyright 2015 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.
+
+// the rustc crate store interface. This also includes types that
+// are *mostly* used as a part of that interface, but these should
+// probably get a better home if someone can find one.
+
+use back::svh::Svh;
+use front::map as hir_map;
+use middle::def;
+use middle::lang_items;
+use middle::ty::{self, Ty};
+use middle::def_id::{DefId, DefIndex};
+use session::Session;
+use session::search_paths::PathKind;
+use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
+use std::any::Any;
+use std::cell::RefCell;
+use std::rc::Rc;
+use std::path::PathBuf;
+use syntax::ast;
+use syntax::ast_util::{IdVisitingOperation};
+use syntax::attr;
+use syntax::codemap::Span;
+use syntax::ptr::P;
+use rustc_back::target::Target;
+use rustc_front::hir;
+use rustc_front::intravisit::Visitor;
+use rustc_front::util::IdVisitor;
+
+pub use self::DefLike::{DlDef, DlField, DlImpl};
+pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown};
+
+// lonely orphan structs and enums looking for a better home
+
+#[derive(Clone, Debug)]
+pub struct LinkMeta {
+    pub crate_name: String,
+    pub crate_hash: Svh,
+}
+
+// Where a crate came from on the local filesystem. One of these two options
+// must be non-None.
+#[derive(PartialEq, Clone, Debug)]
+pub struct CrateSource {
+    pub dylib: Option<(PathBuf, PathKind)>,
+    pub rlib: Option<(PathBuf, PathKind)>,
+    pub cnum: ast::CrateNum,
+}
+
+#[derive(Copy, Debug, PartialEq, Clone)]
+pub enum LinkagePreference {
+    RequireDynamic,
+    RequireStatic,
+}
+
+enum_from_u32! {
+    #[derive(Copy, Clone, PartialEq)]
+    pub enum NativeLibraryKind {
+        NativeStatic,    // native static library (.a archive)
+        NativeFramework, // OSX-specific
+        NativeUnknown,   // default way to specify a dynamic library
+    }
+}
+
+// Something that a name can resolve to.
+#[derive(Copy, Clone, Debug)]
+pub enum DefLike {
+    DlDef(def::Def),
+    DlImpl(DefId),
+    DlField
+}
+
+/// The data we save and restore about an inlined item or method.  This is not
+/// part of the AST that we parse from a file, but it becomes part of the tree
+/// that we trans.
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum InlinedItem {
+    Item(P<hir::Item>),
+    TraitItem(DefId /* impl id */, P<hir::TraitItem>),
+    ImplItem(DefId /* impl id */, P<hir::ImplItem>),
+    Foreign(P<hir::ForeignItem>),
+}
+
+/// A borrowed version of `hir::InlinedItem`.
+pub enum InlinedItemRef<'a> {
+    Item(&'a hir::Item),
+    TraitItem(DefId, &'a hir::TraitItem),
+    ImplItem(DefId, &'a hir::ImplItem),
+    Foreign(&'a hir::ForeignItem)
+}
+
+/// Item definitions in the currently-compiled crate would have the CrateNum
+/// LOCAL_CRATE in their DefId.
+pub const LOCAL_CRATE: ast::CrateNum = 0;
+
+pub struct ChildItem {
+    pub def: DefLike,
+    pub name: ast::Name,
+    pub vis: hir::Visibility
+}
+
+pub enum FoundAst<'ast> {
+    Found(&'ast InlinedItem),
+    FoundParent(DefId, &'ast InlinedItem),
+    NotFound,
+}
+
+/// A store of Rust crates, through with their metadata
+/// can be accessed.
+///
+/// The `: Any` bound is a temporary measure that allows access
+/// to the backing `rustc_metadata::cstore::CStore` object. It
+/// will be removed in the near future - if you need to access
+/// internal APIs, please tell us.
+pub trait CrateStore<'tcx> : Any {
+    // item info
+    fn stability(&self, def: DefId) -> Option<attr::Stability>;
+    fn closure_kind(&self, tcx: &ty::ctxt<'tcx>, def_id: DefId)
+                    -> ty::ClosureKind;
+    fn closure_ty(&self, tcx: &ty::ctxt<'tcx>, def_id: DefId)
+                  -> ty::ClosureTy<'tcx>;
+    fn item_variances(&self, def: DefId) -> ty::ItemVariances;
+    fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr>;
+    fn item_type(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                 -> ty::TypeScheme<'tcx>;
+    fn item_path(&self, def: DefId) -> Vec<hir_map::PathElem>;
+    fn item_name(&self, def: DefId) -> ast::Name;
+    fn item_predicates(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                       -> ty::GenericPredicates<'tcx>;
+    fn item_super_predicates(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                             -> ty::GenericPredicates<'tcx>;
+    fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
+    fn item_symbol(&self, def: DefId) -> String;
+    fn trait_def(&self, tcx: &ty::ctxt<'tcx>, def: DefId)-> ty::TraitDef<'tcx>;
+    fn adt_def(&self, tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>;
+    fn method_arg_names(&self, did: DefId) -> Vec<String>;
+    fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>;
+
+    // trait info
+    fn implementations_of_trait(&self, def_id: DefId) -> Vec<DefId>;
+    fn provided_trait_methods(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                              -> Vec<Rc<ty::Method<'tcx>>>;
+    fn trait_item_def_ids(&self, def: DefId)
+                          -> Vec<ty::ImplOrTraitItemId>;
+
+    // impl info
+    fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>;
+    fn impl_trait_ref(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                      -> Option<ty::TraitRef<'tcx>>;
+    fn impl_polarity(&self, def: DefId) -> Option<hir::ImplPolarity>;
+    fn custom_coerce_unsized_kind(&self, def: DefId)
+                                  -> Option<ty::adjustment::CustomCoerceUnsized>;
+    fn associated_consts(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                         -> Vec<Rc<ty::AssociatedConst<'tcx>>>;
+
+    // trait/impl-item info
+    fn trait_of_item(&self, tcx: &ty::ctxt<'tcx>, def_id: DefId)
+                     -> Option<DefId>;
+    fn impl_or_trait_item(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                          -> ty::ImplOrTraitItem<'tcx>;
+
+    // flags
+    fn is_const_fn(&self, did: DefId) -> bool;
+    fn is_defaulted_trait(&self, did: DefId) -> bool;
+    fn is_impl(&self, did: DefId) -> bool;
+    fn is_default_impl(&self, impl_did: DefId) -> bool;
+    fn is_extern_fn(&self, tcx: &ty::ctxt<'tcx>, did: DefId) -> bool;
+    fn is_static(&self, did: DefId) -> bool;
+    fn is_static_method(&self, did: DefId) -> bool;
+    fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
+    fn is_typedef(&self, did: DefId) -> bool;
+
+    // crate metadata
+    fn dylib_dependency_formats(&self, cnum: ast::CrateNum)
+                                    -> Vec<(ast::CrateNum, LinkagePreference)>;
+    fn lang_items(&self, cnum: ast::CrateNum) -> Vec<(DefIndex, usize)>;
+    fn missing_lang_items(&self, cnum: ast::CrateNum) -> Vec<lang_items::LangItem>;
+    fn is_staged_api(&self, cnum: ast::CrateNum) -> bool;
+    fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool;
+    fn is_allocator(&self, cnum: ast::CrateNum) -> bool;
+    fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>;
+    fn crate_name(&self, cnum: ast::CrateNum) -> String;
+    fn crate_hash(&self, cnum: ast::CrateNum) -> Svh;
+    fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
+                                -> FnvHashMap<DefId, Vec<ast::Attribute>>;
+    fn plugin_registrar_fn(&self, cnum: ast::CrateNum) -> Option<DefId>;
+    fn native_libraries(&self, cnum: ast::CrateNum) -> Vec<(NativeLibraryKind, String)>;
+    fn reachable_ids(&self, cnum: ast::CrateNum) -> Vec<DefId>;
+
+    // resolve
+    fn def_path(&self, def: DefId) -> hir_map::DefPath;
+    fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option<DefId>;
+    fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
+    fn item_children(&self, did: DefId) -> Vec<ChildItem>;
+    fn crate_top_level_items(&self, cnum: ast::CrateNum) -> Vec<ChildItem>;
+
+    // misc. metadata
+    fn maybe_get_item_ast(&'tcx self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                          -> FoundAst<'tcx>;
+    // This is basically a 1-based range of ints, which is a little
+    // silly - I may fix that.
+    fn crates(&self) -> Vec<ast::CrateNum>;
+    fn used_libraries(&self) -> Vec<(String, NativeLibraryKind)>;
+    fn used_link_args(&self) -> Vec<String>;
+
+    // utility functions
+    fn metadata_filename(&self) -> &str;
+    fn metadata_section_name(&self, target: &Target) -> &str;
+    fn encode_type(&self, tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Vec<u8>;
+    fn used_crates(&self, prefer: LinkagePreference) -> Vec<(ast::CrateNum, Option<PathBuf>)>;
+    fn used_crate_source(&self, cnum: ast::CrateNum) -> CrateSource;
+    fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum>;
+    fn encode_metadata(&self,
+                       tcx: &ty::ctxt<'tcx>,
+                       reexports: &def::ExportMap,
+                       item_symbols: &RefCell<NodeMap<String>>,
+                       link_meta: &LinkMeta,
+                       reachable: &NodeSet,
+                       krate: &hir::Crate) -> Vec<u8>;
+    fn metadata_encoding_version(&self) -> &[u8];
+}
+
+impl InlinedItem {
+    pub fn visit<'ast,V>(&'ast self, visitor: &mut V)
+        where V: Visitor<'ast>
+    {
+        match *self {
+            InlinedItem::Item(ref i) => visitor.visit_item(&**i),
+            InlinedItem::Foreign(ref i) => visitor.visit_foreign_item(&**i),
+            InlinedItem::TraitItem(_, ref ti) => visitor.visit_trait_item(ti),
+            InlinedItem::ImplItem(_, ref ii) => visitor.visit_impl_item(ii),
+        }
+    }
+
+    pub fn visit_ids<O: IdVisitingOperation>(&self, operation: &mut O) {
+        let mut id_visitor = IdVisitor::new(operation);
+        self.visit(&mut id_visitor);
+    }
+}
+
+// FIXME: find a better place for this?
+pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
+    let say = |s: &str| {
+        match (sp, sess) {
+            (_, None) => panic!("{}", s),
+            (Some(sp), Some(sess)) => sess.span_err(sp, s),
+            (None, Some(sess)) => sess.err(s),
+        }
+    };
+    if s.is_empty() {
+        say("crate name must not be empty");
+    }
+    for c in s.chars() {
+        if c.is_alphanumeric() { continue }
+        if c == '_'  { continue }
+        say(&format!("invalid character `{}` in crate name: `{}`", c, s));
+    }
+    match sess {
+        Some(sess) => sess.abort_if_errors(),
+        None => {}
+    }
+}
+
+/// A dummy crate store that does not support any non-local crates,
+/// for test purposes.
+pub struct DummyCrateStore;
+#[allow(unused_variables)]
+impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
+    // item info
+    fn stability(&self, def: DefId) -> Option<attr::Stability> { unimplemented!() }
+    fn closure_kind(&self, tcx: &ty::ctxt<'tcx>, def_id: DefId)
+                    -> ty::ClosureKind  { unimplemented!() }
+    fn closure_ty(&self, tcx: &ty::ctxt<'tcx>, def_id: DefId)
+                  -> ty::ClosureTy<'tcx>  { unimplemented!() }
+    fn item_variances(&self, def: DefId) -> ty::ItemVariances { unimplemented!() }
+    fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr> { unimplemented!() }
+    fn item_type(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                 -> ty::TypeScheme<'tcx> { unimplemented!() }
+    fn item_path(&self, def: DefId) -> Vec<hir_map::PathElem> { unimplemented!() }
+    fn item_name(&self, def: DefId) -> ast::Name { unimplemented!() }
+    fn item_predicates(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                       -> ty::GenericPredicates<'tcx> { unimplemented!() }
+    fn item_super_predicates(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                             -> ty::GenericPredicates<'tcx> { unimplemented!() }
+    fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { unimplemented!() }
+    fn item_symbol(&self, def: DefId) -> String { unimplemented!() }
+    fn trait_def(&self, tcx: &ty::ctxt<'tcx>, def: DefId)-> ty::TraitDef<'tcx>
+        { unimplemented!() }
+    fn adt_def(&self, tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
+        { unimplemented!() }
+    fn method_arg_names(&self, did: DefId) -> Vec<String> { unimplemented!() }
+    fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId> { vec![] }
+
+    // trait info
+    fn implementations_of_trait(&self, def_id: DefId) -> Vec<DefId> { vec![] }
+    fn provided_trait_methods(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                              -> Vec<Rc<ty::Method<'tcx>>> { unimplemented!() }
+    fn trait_item_def_ids(&self, def: DefId)
+                          -> Vec<ty::ImplOrTraitItemId> { unimplemented!() }
+
+    // impl info
+    fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>
+        { unimplemented!() }
+    fn impl_trait_ref(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                      -> Option<ty::TraitRef<'tcx>> { unimplemented!() }
+    fn impl_polarity(&self, def: DefId) -> Option<hir::ImplPolarity> { unimplemented!() }
+    fn custom_coerce_unsized_kind(&self, def: DefId)
+                                  -> Option<ty::adjustment::CustomCoerceUnsized>
+        { unimplemented!() }
+    fn associated_consts(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                         -> Vec<Rc<ty::AssociatedConst<'tcx>>> { unimplemented!() }
+
+    // trait/impl-item info
+    fn trait_of_item(&self, tcx: &ty::ctxt<'tcx>, def_id: DefId)
+                     -> Option<DefId> { unimplemented!() }
+    fn impl_or_trait_item(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                          -> ty::ImplOrTraitItem<'tcx> { unimplemented!() }
+
+    // flags
+    fn is_const_fn(&self, did: DefId) -> bool { unimplemented!() }
+    fn is_defaulted_trait(&self, did: DefId) -> bool { unimplemented!() }
+    fn is_impl(&self, did: DefId) -> bool { unimplemented!() }
+    fn is_default_impl(&self, impl_did: DefId) -> bool { unimplemented!() }
+    fn is_extern_fn(&self, tcx: &ty::ctxt<'tcx>, did: DefId) -> bool { unimplemented!() }
+    fn is_static(&self, did: DefId) -> bool { unimplemented!() }
+    fn is_static_method(&self, did: DefId) -> bool { unimplemented!() }
+    fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
+    fn is_typedef(&self, did: DefId) -> bool { unimplemented!() }
+
+    // crate metadata
+    fn dylib_dependency_formats(&self, cnum: ast::CrateNum)
+                                    -> Vec<(ast::CrateNum, LinkagePreference)>
+        { unimplemented!() }
+    fn lang_items(&self, cnum: ast::CrateNum) -> Vec<(DefIndex, usize)>
+        { unimplemented!() }
+    fn missing_lang_items(&self, cnum: ast::CrateNum) -> Vec<lang_items::LangItem>
+        { unimplemented!() }
+    fn is_staged_api(&self, cnum: ast::CrateNum) -> bool { unimplemented!() }
+    fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool { unimplemented!() }
+    fn is_allocator(&self, cnum: ast::CrateNum) -> bool { unimplemented!() }
+    fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>
+        { unimplemented!() }
+    fn crate_name(&self, cnum: ast::CrateNum) -> String { unimplemented!() }
+    fn crate_hash(&self, cnum: ast::CrateNum) -> Svh { unimplemented!() }
+    fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
+                                -> FnvHashMap<DefId, Vec<ast::Attribute>>
+        { unimplemented!() }
+    fn plugin_registrar_fn(&self, cnum: ast::CrateNum) -> Option<DefId>
+        { unimplemented!() }
+    fn native_libraries(&self, cnum: ast::CrateNum) -> Vec<(NativeLibraryKind, String)>
+        { unimplemented!() }
+    fn reachable_ids(&self, cnum: ast::CrateNum) -> Vec<DefId> { unimplemented!() }
+
+    // resolve
+    fn def_path(&self, def: DefId) -> hir_map::DefPath { unimplemented!() }
+    fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option<DefId>
+        { unimplemented!() }
+    fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { unimplemented!() }
+    fn item_children(&self, did: DefId) -> Vec<ChildItem> { unimplemented!() }
+    fn crate_top_level_items(&self, cnum: ast::CrateNum) -> Vec<ChildItem>
+        { unimplemented!() }
+
+    // misc. metadata
+    fn maybe_get_item_ast(&'tcx self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                          -> FoundAst<'tcx> { unimplemented!() }
+    // This is basically a 1-based range of ints, which is a little
+    // silly - I may fix that.
+    fn crates(&self) -> Vec<ast::CrateNum> { vec![] }
+    fn used_libraries(&self) -> Vec<(String, NativeLibraryKind)> { vec![] }
+    fn used_link_args(&self) -> Vec<String> { vec![] }
+
+    // utility functions
+    fn metadata_filename(&self) -> &str { unimplemented!() }
+    fn metadata_section_name(&self, target: &Target) -> &str { unimplemented!() }
+    fn encode_type(&self, tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Vec<u8>
+        { unimplemented!() }
+    fn used_crates(&self, prefer: LinkagePreference) -> Vec<(ast::CrateNum, Option<PathBuf>)>
+        { vec![] }
+    fn used_crate_source(&self, cnum: ast::CrateNum) -> CrateSource { unimplemented!() }
+    fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum> { None }
+    fn encode_metadata(&self,
+                       tcx: &ty::ctxt<'tcx>,
+                       reexports: &def::ExportMap,
+                       item_symbols: &RefCell<NodeMap<String>>,
+                       link_meta: &LinkMeta,
+                       reachable: &NodeSet,
+                       krate: &hir::Crate) -> Vec<u8> { vec![] }
+    fn metadata_encoding_version(&self) -> &[u8] { unimplemented!() }
+}
diff --git a/src/librustc/middle/def_id.rs b/src/librustc/middle/def_id.rs
index 288eb01ebb4..4d0005f47c4 100644
--- a/src/librustc/middle/def_id.rs
+++ b/src/librustc/middle/def_id.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use metadata::cstore::LOCAL_CRATE;
+use middle::cstore::LOCAL_CRATE;
 use middle::ty;
 use syntax::ast::CrateNum;
 use std::fmt;
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs
index 125e9285b52..ab5153e1a61 100644
--- a/src/librustc/middle/dependency_format.rs
+++ b/src/librustc/middle/dependency_format.rs
@@ -65,8 +65,8 @@ use syntax::ast;
 
 use session;
 use session::config;
-use metadata::cstore;
-use metadata::csearch;
+use middle::cstore::CrateStore;
+use middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic};
 use util::nodemap::FnvHashMap;
 
 /// A list of dependencies for a certain crate type.
@@ -123,12 +123,12 @@ fn calculate_type(sess: &session::Session,
                 Some(v) => return v,
                 None => {}
             }
-            sess.cstore.iter_crate_data(|cnum, data| {
-                let src = sess.cstore.get_used_crate_source(cnum).unwrap();
-                if src.rlib.is_some() { return }
+            for cnum in sess.cstore.crates() {
+                let src = sess.cstore.used_crate_source(cnum);
+                if src.rlib.is_some() { continue }
                 sess.err(&format!("dependency `{}` not found in rlib format",
-                                 data.name));
-            });
+                                  sess.cstore.crate_name(cnum)));
+            }
             return Vec::new();
         }
 
@@ -151,25 +151,27 @@ fn calculate_type(sess: &session::Session,
     // Sweep all crates for found dylibs. Add all dylibs, as well as their
     // dependencies, ensuring there are no conflicts. The only valid case for a
     // dependency to be relied upon twice is for both cases to rely on a dylib.
-    sess.cstore.iter_crate_data(|cnum, data| {
-        let src = sess.cstore.get_used_crate_source(cnum).unwrap();
+    for cnum in sess.cstore.crates() {
+        let name = sess.cstore.crate_name(cnum);
+        let src = sess.cstore.used_crate_source(cnum);
         if src.dylib.is_some() {
-            info!("adding dylib: {}", data.name);
-            add_library(sess, cnum, cstore::RequireDynamic, &mut formats);
-            let deps = csearch::get_dylib_dependency_formats(&sess.cstore, cnum);
+            info!("adding dylib: {}", name);
+            add_library(sess, cnum, RequireDynamic, &mut formats);
+            let deps = sess.cstore.dylib_dependency_formats(cnum);
             for &(depnum, style) in &deps {
                 info!("adding {:?}: {}", style,
-                      sess.cstore.get_crate_data(depnum).name.clone());
+                      sess.cstore.crate_name(depnum));
                 add_library(sess, depnum, style, &mut formats);
             }
         }
-    });
+    }
 
     // Collect what we've got so far in the return vector.
-    let mut ret = (1..sess.cstore.next_crate_num()).map(|i| {
-        match formats.get(&i) {
-            Some(&cstore::RequireDynamic) => Linkage::Dynamic,
-            Some(&cstore::RequireStatic) => Linkage::IncludedFromDylib,
+    let last_crate = sess.cstore.crates().len() as ast::CrateNum;
+    let mut ret = (1..last_crate+1).map(|cnum| {
+        match formats.get(&cnum) {
+            Some(&RequireDynamic) => Linkage::Dynamic,
+            Some(&RequireStatic) => Linkage::IncludedFromDylib,
             None => Linkage::NotLinked,
         }
     }).collect::<Vec<_>>();
@@ -179,17 +181,17 @@ fn calculate_type(sess: &session::Session,
     //
     // If the crate hasn't been included yet and it's not actually required
     // (e.g. it's an allocator) then we skip it here as well.
-    sess.cstore.iter_crate_data(|cnum, data| {
-        let src = sess.cstore.get_used_crate_source(cnum).unwrap();
+    for cnum in sess.cstore.crates() {
+        let src = sess.cstore.used_crate_source(cnum);
         if src.dylib.is_none() &&
            !formats.contains_key(&cnum) &&
-           data.explicitly_linked.get() {
+           sess.cstore.is_explicitly_linked(cnum) {
             assert!(src.rlib.is_some());
-            info!("adding staticlib: {}", data.name);
-            add_library(sess, cnum, cstore::RequireStatic, &mut formats);
+            info!("adding staticlib: {}", sess.cstore.crate_name(cnum));
+            add_library(sess, cnum, RequireStatic, &mut formats);
             ret[cnum as usize - 1] = Linkage::Static;
         }
-    });
+    }
 
     // We've gotten this far because we're emitting some form of a final
     // artifact which means that we're going to need an allocator of some form.
@@ -205,7 +207,7 @@ fn calculate_type(sess: &session::Session,
     // making sure that everything is available in the requested format.
     for (cnum, kind) in ret.iter().enumerate() {
         let cnum = (cnum + 1) as ast::CrateNum;
-        let src = sess.cstore.get_used_crate_source(cnum).unwrap();
+        let src = sess.cstore.used_crate_source(cnum);
         match *kind {
             Linkage::NotLinked |
             Linkage::IncludedFromDylib => {}
@@ -216,10 +218,10 @@ fn calculate_type(sess: &session::Session,
                     Linkage::Static => "rlib",
                     _ => "dylib",
                 };
-                let data = sess.cstore.get_crate_data(cnum);
+                let name = sess.cstore.crate_name(cnum);
                 sess.err(&format!("crate `{}` required to be available in {}, \
                                   but it was not available in this form",
-                                 data.name, kind));
+                                  name, kind));
             }
         }
     }
@@ -229,8 +231,8 @@ fn calculate_type(sess: &session::Session,
 
 fn add_library(sess: &session::Session,
                cnum: ast::CrateNum,
-               link: cstore::LinkagePreference,
-               m: &mut FnvHashMap<ast::CrateNum, cstore::LinkagePreference>) {
+               link: LinkagePreference,
+               m: &mut FnvHashMap<ast::CrateNum, LinkagePreference>) {
     match m.get(&cnum) {
         Some(&link2) => {
             // If the linkages differ, then we'd have two copies of the library
@@ -240,10 +242,9 @@ fn add_library(sess: &session::Session,
             //
             // This error is probably a little obscure, but I imagine that it
             // can be refined over time.
-            if link2 != link || link == cstore::RequireStatic {
-                let data = sess.cstore.get_crate_data(cnum);
+            if link2 != link || link == RequireStatic {
                 sess.err(&format!("cannot satisfy dependencies so `{}` only \
-                                   shows up once", data.name));
+                                   shows up once", sess.cstore.crate_name(cnum)));
                 sess.help("having upstream crates all available in one format \
                            will likely make this go away");
             }
@@ -253,15 +254,16 @@ fn add_library(sess: &session::Session,
 }
 
 fn attempt_static(sess: &session::Session) -> Option<DependencyList> {
-    let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
+    let crates = sess.cstore.used_crates(RequireStatic);
     if !crates.iter().by_ref().all(|&(_, ref p)| p.is_some()) {
         return None
     }
 
     // All crates are available in an rlib format, so we're just going to link
     // everything in explicitly so long as it's actually required.
-    let mut ret = (1..sess.cstore.next_crate_num()).map(|cnum| {
-        if sess.cstore.get_crate_data(cnum).explicitly_linked.get() {
+    let last_crate = sess.cstore.crates().len() as ast::CrateNum;
+    let mut ret = (1..last_crate+1).map(|cnum| {
+        if sess.cstore.is_explicitly_linked(cnum) {
             Linkage::Static
         } else {
             Linkage::NotLinked
@@ -288,7 +290,7 @@ fn activate_allocator(sess: &session::Session, list: &mut DependencyList) {
     let mut allocator_found = false;
     for (i, slot) in list.iter().enumerate() {
         let cnum = (i + 1) as ast::CrateNum;
-        if !sess.cstore.get_crate_data(cnum).is_allocator() {
+        if !sess.cstore.is_allocator(cnum) {
             continue
         }
         if let Linkage::NotLinked = *slot {
@@ -314,18 +316,18 @@ fn verify_ok(sess: &session::Session, list: &[Linkage]) {
     let mut allocator = None;
     for (i, linkage) in list.iter().enumerate() {
         let cnum = (i + 1) as ast::CrateNum;
-        let data = sess.cstore.get_crate_data(cnum);
-        if !data.is_allocator() {
+        if !sess.cstore.is_allocator(cnum) {
             continue
         }
         if let Linkage::NotLinked = *linkage {
             continue
         }
         if let Some(prev_alloc) = allocator {
-            let prev = sess.cstore.get_crate_data(prev_alloc);
+            let prev_name = sess.cstore.crate_name(prev_alloc);
+            let cur_name = sess.cstore.crate_name(cnum);
             sess.err(&format!("cannot link together two \
                                allocators: {} and {}",
-                              prev.name(), data.name()));
+                              prev_name, cur_name));
         }
         allocator = Some(cnum);
     }
diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs
index 1b118520339..5563cd80438 100644
--- a/src/librustc/middle/infer/error_reporting.rs
+++ b/src/librustc/middle/infer/error_reporting.rs
@@ -76,6 +76,7 @@ use front::map as ast_map;
 use rustc_front::hir;
 use rustc_front::print::pprust;
 
+use middle::cstore::CrateStore;
 use middle::def;
 use middle::def_id::DefId;
 use middle::infer::{self, TypeOrigin};
@@ -498,8 +499,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                 // We compare strings because PathMod and PathName can be different
                 // for imported and non-imported crates
                 if exp_path == found_path {
-                    let crate_name = self.tcx.sess.cstore
-                                         .get_crate_data(did1.krate).name();
+                    let crate_name = self.tcx.sess.cstore.crate_name(did1.krate);
                     self.tcx.sess.span_note(sp, &format!("Perhaps two different versions \
                                                           of crate `{}` are being used?",
                                                           crate_name));
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index a37f62e52b8..ec55daca9ec 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -23,7 +23,7 @@ pub use self::LangItem::*;
 
 use front::map as hir_map;
 use session::Session;
-use metadata::csearch::each_lang_item;
+use middle::cstore::CrateStore;
 use middle::def_id::DefId;
 use middle::ty;
 use middle::weak_lang_items;
@@ -203,14 +203,13 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
     }
 
     pub fn collect_external_language_items(&mut self) {
-        let crate_store = &self.session.cstore;
-        crate_store.iter_crate_data(|crate_number, _crate_metadata| {
-            each_lang_item(crate_store, crate_number, |index, item_index| {
-                let def_id = DefId { krate: crate_number, index: index };
+        let cstore = &self.session.cstore;
+        for cnum in cstore.crates() {
+            for (index, item_index) in cstore.lang_items(cnum) {
+                let def_id = DefId { krate: cnum, index: index };
                 self.collect_item(item_index, def_id, DUMMY_SP);
-                true
-            });
-        })
+            }
+        }
     }
 
     pub fn collect(&mut self, krate: &hir::Crate) {
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 45b8ac4a16d..e3504b6a744 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -16,10 +16,10 @@
 //! Most of the documentation on regions can be found in
 //! `middle/typeck/infer/region_inference.rs`
 
-use metadata::inline::InlinedItem;
 use front::map as ast_map;
 use session::Session;
 use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
+use middle::cstore::InlinedItem;
 use middle::ty::{self, Ty};
 
 use std::cell::RefCell;
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 9ba49633f2b..0d92c3da83c 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -15,12 +15,11 @@ pub use self::StabilityLevel::*;
 
 use session::Session;
 use lint;
-use metadata::cstore::LOCAL_CRATE;
+use middle::cstore::{CrateStore, LOCAL_CRATE};
 use middle::def;
 use middle::def_id::{CRATE_DEF_INDEX, DefId};
 use middle::ty;
 use middle::privacy::AccessLevels;
-use metadata::csearch;
 use syntax::parse::token::InternedString;
 use syntax::codemap::{Span, DUMMY_SP};
 use syntax::ast;
@@ -448,7 +447,7 @@ pub fn check_item(tcx: &ty::ctxt, item: &hir::Item, warn_about_defns: bool,
             // compiler-generated `extern crate` items have a dummy span.
             if item.span == DUMMY_SP { return }
 
-            let cnum = match tcx.sess.cstore.find_extern_mod_stmt_cnum(item.id) {
+            let cnum = match tcx.sess.cstore.extern_mod_stmt_cnum(item.id) {
                 Some(cnum) => cnum,
                 None => return,
             };
@@ -621,7 +620,7 @@ fn is_staged_api(tcx: &ty::ctxt, id: DefId) -> bool {
             }
         _ => {
             *tcx.stability.borrow_mut().staged_api.entry(id.krate).or_insert_with(
-                || csearch::is_staged_api(&tcx.sess.cstore, id.krate))
+                || tcx.sess.cstore.is_staged_api(id.krate))
         }
     }
 }
@@ -653,7 +652,7 @@ fn lookup_uncached<'tcx>(tcx: &ty::ctxt<'tcx>, id: DefId) -> Option<&'tcx Stabil
     let item_stab = if id.is_local() {
         None // The stability cache is filled partially lazily
     } else {
-        csearch::get_stability(&tcx.sess.cstore, id).map(|st| tcx.intern_stability(st))
+        tcx.sess.cstore.stability(id).map(|st| tcx.intern_stability(st))
     };
 
     item_stab.or_else(|| {
diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs
index 705cb97a898..56dc259b1c2 100644
--- a/src/librustc/middle/traits/coherence.rs
+++ b/src/librustc/middle/traits/coherence.rs
@@ -17,7 +17,7 @@ use super::PredicateObligation;
 use super::project;
 use super::util;
 
-use metadata::cstore::LOCAL_CRATE;
+use middle::cstore::LOCAL_CRATE;
 use middle::def_id::DefId;
 use middle::subst::{Subst, Substs, TypeSpace};
 use middle::ty::{self, Ty};
diff --git a/src/librustc/middle/ty/context.rs b/src/librustc/middle/ty/context.rs
index e02a120a5c6..4b614539921 100644
--- a/src/librustc/middle/ty/context.rs
+++ b/src/librustc/middle/ty/context.rs
@@ -16,8 +16,8 @@
 use front::map as ast_map;
 use session::Session;
 use lint;
-use metadata::csearch;
 use middle;
+use middle::cstore::CrateStore;
 use middle::def::DefMap;
 use middle::def_id::DefId;
 use middle::free_region::FreeRegionMap;
@@ -155,7 +155,7 @@ impl<'tcx> Tables<'tcx> {
             return kind;
         }
 
-        let kind = csearch::closure_kind(tcx, def_id);
+        let kind = tcx.sess.cstore.closure_kind(tcx, def_id);
         this.borrow_mut().closure_kinds.insert(def_id, kind);
         kind
     }
@@ -173,7 +173,7 @@ impl<'tcx> Tables<'tcx> {
             return ty.subst(tcx, &substs.func_substs);
         }
 
-        let ty = csearch::closure_ty(tcx, def_id);
+        let ty = tcx.sess.cstore.closure_ty(tcx, def_id);
         this.borrow_mut().closure_tys.insert(def_id, ty.clone());
         ty.subst(tcx, &substs.func_substs)
     }
diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs
index 501781627fb..71ae8e40b45 100644
--- a/src/librustc/middle/ty/mod.rs
+++ b/src/librustc/middle/ty/mod.rs
@@ -21,9 +21,8 @@ pub use self::LvaluePreference::*;
 
 use front::map as ast_map;
 use front::map::LinkedPath;
-use metadata::csearch;
-use metadata::cstore::LOCAL_CRATE;
 use middle;
+use middle::cstore::{CrateStore, LOCAL_CRATE};
 use middle::def::{self, ExportMap};
 use middle::def_id::DefId;
 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
@@ -2131,7 +2130,7 @@ impl<'tcx> ctxt<'tcx> {
                 self.sess.bug(&format!("provided_trait_methods: `{:?}` is not a trait", id))
             }
         } else {
-            csearch::get_provided_trait_methods(self, id)
+            self.sess.cstore.provided_trait_methods(self, id)
         }
     }
 
@@ -2176,7 +2175,7 @@ impl<'tcx> ctxt<'tcx> {
                 }
             }
         } else {
-            csearch::get_associated_consts(self, id)
+            self.sess.cstore.associated_consts(self, id)
         }
     }
 
@@ -2208,14 +2207,14 @@ impl<'tcx> ctxt<'tcx> {
                 _ => None
             }
         } else {
-            csearch::get_impl_polarity(self, id)
+            self.sess.cstore.impl_polarity(id)
         }
     }
 
     pub fn custom_coerce_unsized_kind(&self, did: DefId) -> adjustment::CustomCoerceUnsized {
         memoized(&self.custom_coerce_unsized_kinds, did, |did: DefId| {
             let (kind, src) = if did.krate != LOCAL_CRATE {
-                (csearch::get_custom_coerce_unsized_kind(self, did), "external")
+                (self.sess.cstore.custom_coerce_unsized_kind(did), "external")
             } else {
                 (None, "local")
             };
@@ -2234,13 +2233,13 @@ impl<'tcx> ctxt<'tcx> {
     pub fn impl_or_trait_item(&self, id: DefId) -> ImplOrTraitItem<'tcx> {
         lookup_locally_or_in_crate_store(
             "impl_or_trait_items", id, &self.impl_or_trait_items,
-            || csearch::get_impl_or_trait_item(self, id))
+            || self.sess.cstore.impl_or_trait_item(self, id))
     }
 
     pub fn trait_item_def_ids(&self, id: DefId) -> Rc<Vec<ImplOrTraitItemId>> {
         lookup_locally_or_in_crate_store(
             "trait_item_def_ids", id, &self.trait_item_def_ids,
-            || Rc::new(csearch::get_trait_item_def_ids(&self.sess.cstore, id)))
+            || Rc::new(self.sess.cstore.trait_item_def_ids(id)))
     }
 
     /// Returns the trait-ref corresponding to a given impl, or None if it is
@@ -2248,7 +2247,7 @@ impl<'tcx> ctxt<'tcx> {
     pub fn impl_trait_ref(&self, id: DefId) -> Option<TraitRef<'tcx>> {
         lookup_locally_or_in_crate_store(
             "impl_trait_refs", id, &self.impl_trait_refs,
-            || csearch::get_impl_trait(self, id))
+            || self.sess.cstore.impl_trait_ref(self, id))
     }
 
     /// Returns whether this DefId refers to an impl
@@ -2261,7 +2260,7 @@ impl<'tcx> ctxt<'tcx> {
                 false
             }
         } else {
-            csearch::is_impl(&self.sess.cstore, id)
+            self.sess.cstore.is_impl(id)
         }
     }
 
@@ -2277,7 +2276,7 @@ impl<'tcx> ctxt<'tcx> {
         if id.is_local() {
             self.map.def_path(id)
         } else {
-            csearch::def_path(self, id)
+            self.sess.cstore.def_path(id)
         }
     }
 
@@ -2287,7 +2286,7 @@ impl<'tcx> ctxt<'tcx> {
         if let Some(id) = self.map.as_local_node_id(id) {
             self.map.with_path(id, f)
         } else {
-            f(csearch::get_item_path(self, id).iter().cloned().chain(LinkedPath::empty()))
+            f(self.sess.cstore.item_path(id).iter().cloned().chain(LinkedPath::empty()))
         }
     }
 
@@ -2295,7 +2294,7 @@ impl<'tcx> ctxt<'tcx> {
         if let Some(id) = self.map.as_local_node_id(id) {
             self.map.get_path_elem(id).name()
         } else {
-            csearch::get_item_name(self, id)
+            self.sess.cstore.item_name(id)
         }
     }
 
@@ -2309,14 +2308,14 @@ impl<'tcx> ctxt<'tcx> {
     pub fn lookup_item_type(&self, did: DefId) -> TypeScheme<'tcx> {
         lookup_locally_or_in_crate_store(
             "tcache", did, &self.tcache,
-            || csearch::get_type(self, did))
+            || self.sess.cstore.item_type(self, did))
     }
 
     /// Given the did of a trait, returns its canonical trait ref.
     pub fn lookup_trait_def(&self, did: DefId) -> &'tcx TraitDef<'tcx> {
         lookup_locally_or_in_crate_store(
             "trait_defs", did, &self.trait_defs,
-            || self.alloc_trait_def(csearch::get_trait_def(self, did))
+            || self.alloc_trait_def(self.sess.cstore.trait_def(self, did))
         )
     }
 
@@ -2326,7 +2325,7 @@ impl<'tcx> ctxt<'tcx> {
     pub fn lookup_adt_def_master(&self, did: DefId) -> AdtDefMaster<'tcx> {
         lookup_locally_or_in_crate_store(
             "adt_defs", did, &self.adt_defs,
-            || csearch::get_adt_def(self, did)
+            || self.sess.cstore.adt_def(self, did)
         )
     }
 
@@ -2341,14 +2340,14 @@ impl<'tcx> ctxt<'tcx> {
     pub fn lookup_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
         lookup_locally_or_in_crate_store(
             "predicates", did, &self.predicates,
-            || csearch::get_predicates(self, did))
+            || self.sess.cstore.item_predicates(self, did))
     }
 
     /// Given the did of a trait, returns its superpredicates.
     pub fn lookup_super_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
         lookup_locally_or_in_crate_store(
             "super_predicates", did, &self.super_predicates,
-            || csearch::get_super_predicates(self, did))
+            || self.sess.cstore.item_super_predicates(self, did))
     }
 
     /// Get the attributes of a definition.
@@ -2356,7 +2355,7 @@ impl<'tcx> ctxt<'tcx> {
         if let Some(id) = self.map.as_local_node_id(did) {
             Cow::Borrowed(self.map.attrs(id))
         } else {
-            Cow::Owned(csearch::get_item_attrs(&self.sess.cstore, did))
+            Cow::Owned(self.sess.cstore.item_attrs(did))
         }
     }
 
@@ -2384,7 +2383,7 @@ impl<'tcx> ctxt<'tcx> {
                     attr::find_repr_attrs(self.sess.diagnostic(), meta).into_iter()
                 }).collect()
             } else {
-                csearch::get_repr_attrs(&self.sess.cstore, did)
+                self.sess.cstore.repr_attrs(did)
             })
         })
     }
@@ -2392,7 +2391,7 @@ impl<'tcx> ctxt<'tcx> {
     pub fn item_variances(&self, item_id: DefId) -> Rc<ItemVariances> {
         lookup_locally_or_in_crate_store(
             "item_variance_map", item_id, &self.item_variance_map,
-            || Rc::new(csearch::get_item_variances(&self.sess.cstore, item_id)))
+            || Rc::new(self.sess.cstore.item_variances(item_id)))
     }
 
     pub fn trait_has_default_impl(&self, trait_def_id: DefId) -> bool {
@@ -2422,7 +2421,7 @@ impl<'tcx> ctxt<'tcx> {
         debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}",
                primitive_def_id);
 
-        let impl_items = csearch::get_impl_items(&self.sess.cstore, primitive_def_id);
+        let impl_items = self.sess.cstore.impl_items(primitive_def_id);
 
         // Store the implementation info.
         self.impl_items.borrow_mut().insert(primitive_def_id, impl_items);
@@ -2444,15 +2443,12 @@ impl<'tcx> ctxt<'tcx> {
         debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}",
                type_id);
 
-        let mut inherent_impls = Vec::new();
-        csearch::each_inherent_implementation_for_type(&self.sess.cstore, type_id, |impl_def_id| {
-            // Record the implementation.
-            inherent_impls.push(impl_def_id);
-
+        let inherent_impls = self.sess.cstore.inherent_implementations_for_type(type_id);
+        for &impl_def_id in &inherent_impls {
             // Store the implementation info.
-            let impl_items = csearch::get_impl_items(&self.sess.cstore, impl_def_id);
+            let impl_items = self.sess.cstore.impl_items(impl_def_id);
             self.impl_items.borrow_mut().insert(impl_def_id, impl_items);
-        });
+        }
 
         self.inherent_impls.borrow_mut().insert(type_id, Rc::new(inherent_impls));
         self.populated_external_types.borrow_mut().insert(type_id);
@@ -2472,12 +2468,12 @@ impl<'tcx> ctxt<'tcx> {
 
         debug!("populate_implementations_for_trait_if_necessary: searching for {:?}", def);
 
-        if csearch::is_defaulted_trait(&self.sess.cstore, trait_id) {
+        if self.sess.cstore.is_defaulted_trait(trait_id) {
             self.record_trait_has_default_impl(trait_id);
         }
 
-        csearch::each_implementation_for_trait(&self.sess.cstore, trait_id, |impl_def_id| {
-            let impl_items = csearch::get_impl_items(&self.sess.cstore, impl_def_id);
+        for impl_def_id in self.sess.cstore.implementations_of_trait(trait_id) {
+            let impl_items = self.sess.cstore.impl_items(impl_def_id);
             let trait_ref = self.impl_trait_ref(impl_def_id).unwrap();
             // Record the trait->implementation mapping.
             def.record_impl(self, impl_def_id, trait_ref);
@@ -2493,7 +2489,7 @@ impl<'tcx> ctxt<'tcx> {
 
             // Store the implementation info.
             self.impl_items.borrow_mut().insert(impl_def_id, impl_items);
-        });
+        }
 
         def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
     }
@@ -2520,8 +2516,7 @@ impl<'tcx> ctxt<'tcx> {
     /// ID of the impl that the method belongs to. Otherwise, return `None`.
     pub fn impl_of_method(&self, def_id: DefId) -> Option<DefId> {
         if def_id.krate != LOCAL_CRATE {
-            return match csearch::get_impl_or_trait_item(self,
-                                                         def_id).container() {
+            return match self.sess.cstore.impl_or_trait_item(self, def_id).container() {
                 TraitContainer(_) => None,
                 ImplContainer(def_id) => Some(def_id),
             };
@@ -2542,7 +2537,7 @@ impl<'tcx> ctxt<'tcx> {
     /// the trait that the method belongs to. Otherwise, return `None`.
     pub fn trait_of_item(&self, def_id: DefId) -> Option<DefId> {
         if def_id.krate != LOCAL_CRATE {
-            return csearch::get_trait_of_item(&self.sess.cstore, def_id, self);
+            return self.sess.cstore.trait_of_item(self, def_id);
         }
         match self.impl_or_trait_items.borrow().get(&def_id).cloned() {
             Some(impl_or_trait_item) => {
diff --git a/src/librustc/middle/ty/util.rs b/src/librustc/middle/ty/util.rs
index 2142755d4a5..0517769356f 100644
--- a/src/librustc/middle/ty/util.rs
+++ b/src/librustc/middle/ty/util.rs
@@ -458,7 +458,7 @@ impl<'tcx> ty::ctxt<'tcx> {
                 let h = if did.is_local() {
                     svh.clone()
                 } else {
-                    tcx.sess.cstore.get_crate_hash(did.krate)
+                    tcx.sess.cstore.crate_hash(did.krate)
                 };
                 h.as_str().hash(state);
                 did.index.hash(state);
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index ee999c91097..78cdc99f047 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -12,7 +12,7 @@
 
 use session::config;
 use session::Session;
-use metadata::csearch;
+use middle::cstore::CrateStore;
 use middle::lang_items;
 
 use syntax::ast;
@@ -79,11 +79,11 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) {
     if !needs_check { return }
 
     let mut missing = HashSet::new();
-    sess.cstore.iter_crate_data(|cnum, _| {
-        for item in &csearch::get_missing_lang_items(&sess.cstore, cnum) {
-            missing.insert(*item);
+    for cnum in sess.cstore.crates() {
+        for item in sess.cstore.missing_lang_items(cnum) {
+            missing.insert(item);
         }
-    });
+    }
 
     $(
         if missing.contains(&lang_items::$item) && items.$name().is_none() {
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 4781992b987..dbeb4c3ed73 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -22,7 +22,7 @@ use session::search_paths::SearchPaths;
 
 use rustc_back::target::Target;
 use lint;
-use metadata::cstore;
+use middle::cstore;
 
 use syntax::ast::{self, IntTy, UintTy};
 use syntax::attr;
@@ -1122,10 +1122,11 @@ impl fmt::Display for CrateType {
 
 #[cfg(test)]
 mod tests {
-
+    use middle::cstore::DummyCrateStore;
     use session::config::{build_configuration, optgroups, build_session_options};
     use session::build_session;
 
+    use std::rc::Rc;
     use getopts::getopts;
     use syntax::attr;
     use syntax::attr::AttrMetaMethods;
@@ -1141,7 +1142,7 @@ mod tests {
             };
         let registry = diagnostics::registry::Registry::new(&[]);
         let sessopts = build_session_options(matches);
-        let sess = build_session(sessopts, None, registry);
+        let sess = build_session(sessopts, None, registry, Rc::new(DummyCrateStore));
         let cfg = build_configuration(&sess);
         assert!((attr::contains_name(&cfg[..], "test")));
     }
@@ -1160,7 +1161,8 @@ mod tests {
             };
         let registry = diagnostics::registry::Registry::new(&[]);
         let sessopts = build_session_options(matches);
-        let sess = build_session(sessopts, None, registry);
+        let sess = build_session(sessopts, None, registry,
+                                 Rc::new(DummyCrateStore));
         let cfg = build_configuration(&sess);
         let mut test_items = cfg.iter().filter(|m| m.name() == "test");
         assert!(test_items.next().is_some());
@@ -1175,7 +1177,8 @@ mod tests {
             ], &optgroups()).unwrap();
             let registry = diagnostics::registry::Registry::new(&[]);
             let sessopts = build_session_options(&matches);
-            let sess = build_session(sessopts, None, registry);
+            let sess = build_session(sessopts, None, registry,
+                                     Rc::new(DummyCrateStore));
             assert!(!sess.can_print_warnings);
         }
 
@@ -1186,7 +1189,8 @@ mod tests {
             ], &optgroups()).unwrap();
             let registry = diagnostics::registry::Registry::new(&[]);
             let sessopts = build_session_options(&matches);
-            let sess = build_session(sessopts, None, registry);
+            let sess = build_session(sessopts, None, registry,
+                                     Rc::new(DummyCrateStore));
             assert!(sess.can_print_warnings);
         }
 
@@ -1196,7 +1200,8 @@ mod tests {
             ], &optgroups()).unwrap();
             let registry = diagnostics::registry::Registry::new(&[]);
             let sessopts = build_session_options(&matches);
-            let sess = build_session(sessopts, None, registry);
+            let sess = build_session(sessopts, None, registry,
+                                     Rc::new(DummyCrateStore));
             assert!(sess.can_print_warnings);
         }
     }
diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/session/filesearch.rs
index 09c6b54d99c..09c6b54d99c 100644
--- a/src/librustc/metadata/filesearch.rs
+++ b/src/librustc/session/filesearch.rs
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index cab61b96b07..7bf96b41dce 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -9,8 +9,7 @@
 // except according to those terms.
 
 use lint;
-use metadata::cstore::CStore;
-use metadata::filesearch;
+use middle::cstore::CrateStore;
 use middle::dependency_format;
 use session::search_paths::PathKind;
 use util::nodemap::{NodeMap, FnvHashMap};
@@ -21,7 +20,6 @@ use syntax::diagnostic::{self, Emitter};
 use syntax::diagnostics;
 use syntax::feature_gate;
 use syntax::parse;
-use syntax::parse::token;
 use syntax::parse::ParseSess;
 use syntax::{ast, codemap};
 use syntax::feature_gate::AttributeType;
@@ -32,8 +30,10 @@ use std::path::{Path, PathBuf};
 use std::cell::{Cell, RefCell};
 use std::collections::HashSet;
 use std::env;
+use std::rc::Rc;
 
 pub mod config;
+pub mod filesearch;
 pub mod search_paths;
 
 // Represents the data associated with a compilation
@@ -42,7 +42,7 @@ pub struct Session {
     pub target: config::Config,
     pub host: Target,
     pub opts: config::Options,
-    pub cstore: CStore,
+    pub cstore: Rc<for<'a> CrateStore<'a>>,
     pub parse_sess: ParseSess,
     // For a library crate, this is always none
     pub entry_fn: RefCell<Option<(NodeId, codemap::Span)>>,
@@ -392,7 +392,8 @@ fn split_msg_into_multilines(msg: &str) -> Option<String> {
 
 pub fn build_session(sopts: config::Options,
                      local_crate_source_file: Option<PathBuf>,
-                     registry: diagnostics::registry::Registry)
+                     registry: diagnostics::registry::Registry,
+                     cstore: Rc<for<'a> CrateStore<'a>>)
                      -> Session {
     // FIXME: This is not general enough to make the warning lint completely override
     // normal diagnostic warnings, since the warning lint can also be denied and changed
@@ -410,12 +411,13 @@ pub fn build_session(sopts: config::Options,
     let span_diagnostic_handler =
         diagnostic::SpanHandler::new(diagnostic_handler, codemap);
 
-    build_session_(sopts, local_crate_source_file, span_diagnostic_handler)
+    build_session_(sopts, local_crate_source_file, span_diagnostic_handler, cstore)
 }
 
 pub fn build_session_(sopts: config::Options,
                       local_crate_source_file: Option<PathBuf>,
-                      span_diagnostic: diagnostic::SpanHandler)
+                      span_diagnostic: diagnostic::SpanHandler,
+                      cstore: Rc<for<'a> CrateStore<'a>>)
                       -> Session {
     let host = match Target::search(config::host_triple()) {
         Ok(t) => t,
@@ -451,7 +453,7 @@ pub fn build_session_(sopts: config::Options,
         target: target_cfg,
         host: host,
         opts: sopts,
-        cstore: CStore::new(token::get_ident_interner()),
+        cstore: cstore,
         parse_sess: p_s,
         // For a library crate, this is always none
         entry_fn: RefCell::new(None),
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index a1bec7e78a3..1429a6a54a6 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -16,22 +16,23 @@ use rustc::session::Session;
 use rustc::session::config::{self, Input, OutputFilenames, OutputType};
 use rustc::session::search_paths::PathKind;
 use rustc::lint;
-use rustc::metadata;
-use rustc::metadata::creader::LocalCrateReader;
 use rustc::middle::{stability, ty, reachable};
 use rustc::middle::dependency_format;
 use rustc::middle;
-use rustc::plugin::registry::Registry;
-use rustc::plugin;
 use rustc::util::nodemap::NodeMap;
 use rustc::util::common::time;
 use rustc_borrowck as borrowck;
 use rustc_resolve as resolve;
+use rustc_metadata::macro_import;
+use rustc_metadata::creader::LocalCrateReader;
+use rustc_metadata::cstore::CStore;
 use rustc_trans::back::link;
 use rustc_trans::back::write;
 use rustc_trans::trans;
 use rustc_typeck as typeck;
 use rustc_privacy;
+use rustc_plugin::registry::Registry;
+use rustc_plugin as plugin;
 use rustc_front::hir;
 use rustc_front::lowering::{lower_crate, LoweringContext};
 use super::Compilation;
@@ -57,6 +58,7 @@ use syntax::visit;
 use syntax;
 
 pub fn compile_input(sess: Session,
+                     cstore: &CStore,
                      cfg: ast::CrateConfig,
                      input: &Input,
                      outdir: &Option<PathBuf>,
@@ -87,6 +89,7 @@ pub fn compile_input(sess: Session,
             let outputs = build_output_filenames(input, outdir, output, &krate.attrs, &sess);
             let id = link::find_crate_name(Some(&sess), &krate.attrs, input);
             let expanded_crate = match phase_2_configure_and_expand(&sess,
+                                                                    &cstore,
                                                                     krate,
                                                                     &id[..],
                                                                     addl_plugins) {
@@ -136,6 +139,7 @@ pub fn compile_input(sess: Session,
              || lint::check_ast_crate(&sess, &expanded_crate));
 
         phase_3_run_analysis_passes(&sess,
+                                    &cstore,
                                     ast_map,
                                     &arenas,
                                     &id,
@@ -434,6 +438,7 @@ fn count_nodes(krate: &ast::Crate) -> usize {
 ///
 /// Returns `None` if we're aborting after handling -W help.
 pub fn phase_2_configure_and_expand(sess: &Session,
+                                    cstore: &CStore,
                                     mut krate: ast::Crate,
                                     crate_name: &str,
                                     addl_plugins: Option<Vec<String>>)
@@ -477,11 +482,11 @@ pub fn phase_2_configure_and_expand(sess: &Session,
 
     let macros = time(time_passes,
                       "macro loading",
-                      || metadata::macro_import::read_macro_defs(sess, &krate));
+                      || macro_import::read_macro_defs(sess, &cstore, &krate));
 
     let mut addl_plugins = Some(addl_plugins);
     let registrars = time(time_passes, "plugin loading", || {
-        plugin::load::load_plugins(sess, &krate, addl_plugins.take().unwrap())
+        plugin::load::load_plugins(sess, &cstore, &krate, addl_plugins.take().unwrap())
     });
 
     let mut registry = Registry::new(sess, &krate);
@@ -670,6 +675,7 @@ pub fn make_map<'ast>(sess: &Session,
 /// miscellaneous analysis passes on the crate. Return various
 /// structures carrying the results of the analysis.
 pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
+                                               cstore: &CStore,
                                                ast_map: front::map::Map<'tcx>,
                                                arenas: &'tcx ty::CtxtArenas<'tcx>,
                                                name: &str,
@@ -683,7 +689,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
 
     time(time_passes,
          "external crate/lib resolution",
-         || LocalCrateReader::new(sess, &ast_map).read_crates(krate));
+         || LocalCrateReader::new(sess, cstore, &ast_map).read_crates(krate));
 
     let lang_items = time(time_passes,
                           "language item collection",
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 649834d4e95..3a91b573fd4 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -33,6 +33,7 @@
 #![feature(set_stdio)]
 #![feature(staged_api)]
 #![feature(vec_push_all)]
+#![feature(raw)] // remove after snapshot
 
 extern crate arena;
 extern crate flate;
@@ -44,7 +45,9 @@ extern crate rustc_back;
 extern crate rustc_borrowck;
 extern crate rustc_front;
 extern crate rustc_lint;
+extern crate rustc_plugin;
 extern crate rustc_privacy;
+extern crate rustc_metadata;
 extern crate rustc_mir;
 extern crate rustc_resolve;
 extern crate rustc_trans;
@@ -66,9 +69,11 @@ use rustc_trans::back::link;
 use rustc_trans::save;
 use rustc::session::{config, Session, build_session};
 use rustc::session::config::{Input, PrintRequest, OutputType};
+use rustc::middle::cstore::CrateStore;
 use rustc::lint::Lint;
 use rustc::lint;
-use rustc::metadata;
+use rustc_metadata::loader;
+use rustc_metadata::cstore::CStore;
 use rustc::util::common::time;
 
 use std::cmp::Ordering::Equal;
@@ -77,6 +82,7 @@ use std::io::{self, Read, Write};
 use std::iter::repeat;
 use std::path::PathBuf;
 use std::process;
+use std::rc::Rc;
 use std::str;
 use std::sync::{Arc, Mutex};
 use std::thread;
@@ -87,6 +93,7 @@ use syntax::ast;
 use syntax::parse;
 use syntax::diagnostic::Emitter;
 use syntax::diagnostics;
+use syntax::parse::token;
 
 #[cfg(test)]
 pub mod test;
@@ -99,6 +106,23 @@ pub mod target_features;
 const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\
                                       md#bug-reports";
 
+// SNAP 1af31d4
+// This is a terrible hack. Our stage0 is older than 1.4 and does not
+// support DST coercions, so this function performs the corecion
+// manually. This should go away.
+pub fn cstore_to_cratestore(a: Rc<CStore>) -> Rc<for<'s> CrateStore<'s>>
+{
+    use std::mem;
+    use std::raw::TraitObject;
+    unsafe {
+        let TraitObject { vtable, .. } =
+            mem::transmute::<&for<'s> CrateStore<'s>, TraitObject>(&*a);
+        mem::transmute(TraitObject {
+            data: mem::transmute(a),
+            vtable: vtable
+        })
+    }
+}
 
 pub fn run(args: Vec<String>) -> isize {
     monitor(move || run_compiler(&args, &mut RustcDefaultCalls));
@@ -135,7 +159,9 @@ pub fn run_compiler<'a>(args: &[String], callbacks: &mut CompilerCalls<'a>) {
         },
     };
 
-    let mut sess = build_session(sopts, input_file_path, descriptions);
+    let cstore = Rc::new(CStore::new(token::get_ident_interner()));
+    let cstore_ = cstore_to_cratestore(cstore.clone());
+    let mut sess = build_session(sopts, input_file_path, descriptions, cstore_);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
     if sess.unstable_options() {
         sess.opts.show_span = matches.opt_str("show-span");
@@ -150,7 +176,7 @@ pub fn run_compiler<'a>(args: &[String], callbacks: &mut CompilerCalls<'a>) {
     let pretty = callbacks.parse_pretty(&sess, &matches);
     match pretty {
         Some((ppm, opt_uii)) => {
-            pretty::pretty_print_input(sess, cfg, &input, ppm, opt_uii, ofile);
+            pretty::pretty_print_input(sess, &cstore, cfg, &input, ppm, opt_uii, ofile);
             return;
         }
         None => {
@@ -160,7 +186,8 @@ pub fn run_compiler<'a>(args: &[String], callbacks: &mut CompilerCalls<'a>) {
 
     let plugins = sess.opts.debugging_opts.extra_plugins.clone();
     let control = callbacks.build_controller(&sess);
-    driver::compile_input(sess, cfg, &input, &odir, &ofile, Some(plugins), control);
+    driver::compile_input(sess, &cstore, cfg, &input, &odir, &ofile,
+                          Some(plugins), control);
 }
 
 // Extract output directory and file from matches.
@@ -329,7 +356,9 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
                     describe_lints(&ls, false);
                     return None;
                 }
-                let sess = build_session(sopts.clone(), None, descriptions.clone());
+                let cstore = Rc::new(CStore::new(token::get_ident_interner()));
+                let cstore_ = cstore_to_cratestore(cstore.clone());
+                let sess = build_session(sopts.clone(), None, descriptions.clone(), cstore_);
                 rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
                 let should_stop = RustcDefaultCalls::print_crate_info(&sess, None, odir, ofile);
                 if should_stop == Compilation::Stop {
@@ -423,7 +452,7 @@ impl RustcDefaultCalls {
                 &Input::File(ref ifile) => {
                     let path = &(*ifile);
                     let mut v = Vec::new();
-                    metadata::loader::list_file_metadata(&sess.target.target, path, &mut v)
+                    loader::list_file_metadata(&sess.target.target, path, &mut v)
                         .unwrap();
                     println!("{}", String::from_utf8(v).unwrap());
                 }
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 8815d574725..630c42db68c 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -27,6 +27,7 @@ use rustc::session::config::Input;
 use rustc_borrowck as borrowck;
 use rustc_borrowck::graphviz as borrowck_dot;
 use rustc_resolve as resolve;
+use rustc_metadata::cstore::CStore;
 
 use syntax::ast;
 use syntax::codemap;
@@ -167,6 +168,7 @@ impl PpSourceMode {
     }
     fn call_with_pp_support_hir<'tcx, A, B, F>(&self,
                                                sess: &'tcx Session,
+                                               cstore: &CStore,
                                                ast_map: &hir_map::Map<'tcx>,
                                                arenas: &'tcx ty::CtxtArenas<'tcx>,
                                                id: &str,
@@ -193,6 +195,7 @@ impl PpSourceMode {
             }
             PpmTyped => {
                 driver::phase_3_run_analysis_passes(sess,
+                                                    cstore,
                                                     ast_map.clone(),
                                                     arenas,
                                                     id,
@@ -668,6 +671,7 @@ impl fold::Folder for ReplaceBodyWithLoop {
 }
 
 pub fn pretty_print_input(sess: Session,
+                          cstore: &CStore,
                           cfg: ast::CrateConfig,
                           input: &Input,
                           ppm: PpMode,
@@ -687,7 +691,7 @@ pub fn pretty_print_input(sess: Session,
     let is_expanded = needs_expansion(&ppm);
     let compute_ast_map = needs_ast_map(&ppm, &opt_uii);
     let krate = if compute_ast_map {
-        match driver::phase_2_configure_and_expand(&sess, krate, &id[..], None) {
+        match driver::phase_2_configure_and_expand(&sess, &cstore, krate, &id[..], None) {
             None => return,
             Some(k) => driver::assign_node_ids(&sess, k),
         }
@@ -741,6 +745,7 @@ pub fn pretty_print_input(sess: Session,
         (PpmHir(s), None) => {
             let out: &mut Write = &mut out;
             s.call_with_pp_support_hir(&sess,
+                                       cstore,
                                        &ast_map.unwrap(),
                                        &arenas,
                                        &id,
@@ -762,6 +767,7 @@ pub fn pretty_print_input(sess: Session,
         (PpmHir(s), Some(uii)) => {
             let out: &mut Write = &mut out;
             s.call_with_pp_support_hir(&sess,
+                                       cstore,
                                        &ast_map.unwrap(),
                                        &arenas,
                                        &id,
@@ -811,6 +817,7 @@ pub fn pretty_print_input(sess: Session,
                 Some(code) => {
                     let variants = gather_flowgraph_variants(&sess);
                     driver::phase_3_run_analysis_passes(&sess,
+                                                        &cstore,
                                                         ast_map,
                                                         &arenas,
                                                         &id,
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index aa439e102eb..2fb23c943c7 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -29,8 +29,10 @@ use rustc_typeck::middle::infer::{self, TypeOrigin};
 use rustc_typeck::middle::infer::lub::Lub;
 use rustc_typeck::middle::infer::glb::Glb;
 use rustc_typeck::middle::infer::sub::Sub;
+use rustc_metadata::cstore::CStore;
 use rustc::front::map as hir_map;
 use rustc::session::{self, config};
+use std::rc::Rc;
 use syntax::{abi, ast};
 use syntax::codemap;
 use syntax::codemap::{Span, CodeMap, DUMMY_SP};
@@ -107,12 +109,14 @@ fn test_env<F>(source_string: &str,
     let diagnostic_handler = diagnostic::Handler::with_emitter(true, emitter);
     let span_diagnostic_handler = diagnostic::SpanHandler::new(diagnostic_handler, codemap);
 
-    let sess = session::build_session_(options, None, span_diagnostic_handler);
+    let cstore = Rc::new(CStore::new(token::get_ident_interner()));
+    let sess = session::build_session_(options, None, span_diagnostic_handler,
+                                       cstore.clone());
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
     let krate_config = Vec::new();
     let input = config::Input::Str(source_string.to_string());
     let krate = driver::phase_1_parse_input(&sess, krate_config, &input);
-    let krate = driver::phase_2_configure_and_expand(&sess, krate, "test", None)
+    let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, "test", None)
                     .expect("phase 2 aborted");
 
     let krate = driver::assign_node_ids(&sess, krate);
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index c4459ef5273..739c5f12ecb 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -28,8 +28,8 @@
 //! Use the former for unit-like structs and the latter for structs with
 //! a `pub fn new()`.
 
-use metadata::decoder;
 use middle::{cfg, def, infer, stability, traits};
+use middle::cstore::CrateStore;
 use middle::def_id::DefId;
 use middle::subst::Substs;
 use middle::ty::{self, Ty};
@@ -936,8 +936,8 @@ impl LateLintPass for PluginAsLibrary {
             _ => return,
         };
 
-        let md = match cx.sess().cstore.find_extern_mod_stmt_cnum(it.id) {
-            Some(cnum) => cx.sess().cstore.get_crate_data(cnum),
+        let prfn = match cx.sess().cstore.extern_mod_stmt_cnum(it.id) {
+            Some(cnum) => cx.sess().cstore.plugin_registrar_fn(cnum),
             None => {
                 // Probably means we aren't linking the crate for some reason.
                 //
@@ -946,7 +946,7 @@ impl LateLintPass for PluginAsLibrary {
             }
         };
 
-        if decoder::get_plugin_registrar_fn(md.data()).is_some() {
+        if prfn.is_some() {
             cx.span_lint(PLUGIN_AS_LIBRARY, it.span,
                          "compiler plugin used as an ordinary library");
         }
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 06e54141d7a..1d7431404f5 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -13,7 +13,7 @@
 //! This currently only contains the definitions and implementations
 //! of most of the lints that `rustc` supports directly, it does not
 //! contain the infrastructure for defining/registering lints. That is
-//! available in `rustc::lint` and `rustc::plugin` respectively.
+//! available in `rustc::lint` and `rustc_plugin` respectively.
 //!
 //! # Note
 //!
@@ -50,7 +50,6 @@ extern crate rustc_front;
 extern crate rustc_back;
 
 pub use rustc::lint as lint;
-pub use rustc::metadata as metadata;
 pub use rustc::middle as middle;
 pub use rustc::session as session;
 pub use rustc::util as util;
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index c6494dc81f9..b8750cccb4b 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -8,11 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use metadata::csearch;
 use middle::pat_util;
 use middle::ty;
 use middle::ty::adjustment;
-use rustc::front::map as hir_map;
 use util::nodemap::FnvHashMap;
 use lint::{LateContext, EarlyContext, LintContext, LintArray};
 use lint::{LintPass, EarlyLintPass, LateLintPass};
@@ -138,16 +136,8 @@ impl LateLintPass for UnusedResults {
             ty::TyBool => return,
             ty::TyStruct(def, _) |
             ty::TyEnum(def, _) => {
-                if let Some(def_node_id) = cx.tcx.map.as_local_node_id(def.did) {
-                    if let hir_map::NodeItem(it) = cx.tcx.map.get(def_node_id) {
-                        check_must_use(cx, &it.attrs, s.span)
-                    } else {
-                        false
-                    }
-                } else {
-                    let attrs = csearch::get_item_attrs(&cx.sess().cstore, def.did);
-                    check_must_use(cx, &attrs[..], s.span)
-                }
+                let attrs = cx.tcx.get_attrs(def.did);
+                check_must_use(cx, &attrs[..], s.span)
             }
             _ => false,
         };
@@ -459,4 +449,3 @@ impl LateLintPass for UnusedAllocation {
         }
     }
 }
-
diff --git a/src/librustc/middle/astencode.rs b/src/librustc_metadata/astencode.rs
index 752fdc23474..2ecf715424b 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc_metadata/astencode.rs
@@ -12,19 +12,21 @@
 // FIXME: remove this after snapshot, and Results are handled
 #![allow(unused_must_use)]
 
-use front::map as ast_map;
+use rustc::front::map as ast_map;
+use rustc::session::Session;
+
 use rustc_front::hir;
 use rustc_front::fold;
 use rustc_front::fold::Folder;
 
-use metadata::common as c;
-use metadata::cstore as cstore;
-use session::Session;
-use metadata::decoder;
-use metadata::encoder as e;
-use metadata::inline::{InlinedItem, InlinedItemRef};
-use metadata::tydecode;
-use metadata::tyencode;
+use common as c;
+use cstore;
+use decoder;
+use encoder as e;
+use tydecode;
+use tyencode;
+
+use middle::cstore::{InlinedItem, InlinedItemRef};
 use middle::ty::adjustment;
 use middle::ty::cast;
 use middle::check_const::ConstQualif;
@@ -89,7 +91,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
 
     // Folding could be avoided with a smarter encoder.
     let ii = simplify_ast(ii);
-    let id_range = ii.compute_id_range();
+    let id_range = inlined_item_id_range(&ii);
 
     rbml_w.start_tag(c::tag_ast as usize);
     id_range.encode(rbml_w);
@@ -1326,6 +1328,12 @@ fn copy_item_types(dcx: &DecodeContext, ii: &InlinedItem, orig_did: DefId) {
     }
 }
 
+fn inlined_item_id_range(v: &InlinedItem) -> ast_util::IdRange {
+    let mut visitor = ast_util::IdRangeComputingVisitor::new();
+    v.visit_ids(&mut visitor);
+    visitor.result()
+}
+
 // ______________________________________________________________________
 // Testing of astencode_gen
 
diff --git a/src/librustc/metadata/common.rs b/src/librustc_metadata/common.rs
index a4fee5b7aa8..b6454a4c81a 100644
--- a/src/librustc/metadata/common.rs
+++ b/src/librustc_metadata/common.rs
@@ -12,8 +12,6 @@
 
 pub use self::astencode_tag::*;
 
-use back::svh::Svh;
-
 // RBML enum definitions and utils shared by the encoder and decoder
 //
 // 0x00..0x1f: reserved for RBML generic type tags
@@ -191,12 +189,6 @@ pub const tag_items_data_item_stability: usize = 0x88;
 
 pub const tag_items_data_item_repr: usize = 0x89;
 
-#[derive(Clone, Debug)]
-pub struct LinkMeta {
-    pub crate_name: String,
-    pub crate_hash: Svh,
-}
-
 pub const tag_struct_fields: usize = 0x10d; // top-level only
 pub const tag_struct_field: usize = 0x8a;
 
diff --git a/src/librustc/metadata/creader.rs b/src/librustc_metadata/creader.rs
index 4a28872b1b8..4420da5f9b8 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -12,17 +12,17 @@
 
 //! Validates all used crates and extern libraries and loads their metadata
 
-use back::svh::Svh;
-use session::{config, Session};
-use session::search_paths::PathKind;
-use metadata::common::rustc_version;
-use metadata::cstore;
-use metadata::cstore::{CStore, CrateSource, MetadataBlob};
-use metadata::decoder;
-use metadata::loader;
-use metadata::loader::CratePaths;
-use util::nodemap::FnvHashMap;
-use front::map as hir_map;
+use common::rustc_version;
+use cstore::{self, CStore, CrateSource, MetadataBlob};
+use decoder;
+use loader::{self, CratePaths};
+
+use rustc::back::svh::Svh;
+use rustc::session::{config, Session};
+use rustc::session::search_paths::PathKind;
+use rustc::middle::cstore::{CrateStore, validate_crate_name};
+use rustc::util::nodemap::FnvHashMap;
+use rustc::front::map as hir_map;
 
 use std::cell::{RefCell, Cell};
 use std::path::PathBuf;
@@ -43,12 +43,14 @@ use log;
 
 pub struct LocalCrateReader<'a, 'b:'a> {
     sess: &'a Session,
+    cstore: &'a CStore,
     creader: CrateReader<'a>,
     ast_map: &'a hir_map::Map<'b>,
 }
 
 pub struct CrateReader<'a> {
     sess: &'a Session,
+    cstore: &'a CStore,
     next_crate_num: ast::CrateNum,
     foreign_item_map: FnvHashMap<String, Vec<ast::NodeId>>,
 }
@@ -89,30 +91,8 @@ struct CrateInfo {
     should_link: bool,
 }
 
-pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
-    let say = |s: &str| {
-        match (sp, sess) {
-            (_, None) => panic!("{}", s),
-            (Some(sp), Some(sess)) => sess.span_err(sp, s),
-            (None, Some(sess)) => sess.err(s),
-        }
-    };
-    if s.is_empty() {
-        say("crate name must not be empty");
-    }
-    for c in s.chars() {
-        if c.is_alphanumeric() { continue }
-        if c == '_'  { continue }
-        say(&format!("invalid character `{}` in crate name: `{}`", c, s));
-    }
-    match sess {
-        Some(sess) => sess.abort_if_errors(),
-        None => {}
-    }
-}
-
-
 fn register_native_lib(sess: &Session,
+                       cstore: &CStore,
                        span: Option<Span>,
                        name: String,
                        kind: cstore::NativeLibraryKind) {
@@ -139,7 +119,7 @@ fn register_native_lib(sess: &Session,
             None => sess.err(msg),
         }
     }
-    sess.cstore.add_used_library(name, kind);
+    cstore.add_used_library(name, kind);
 }
 
 // Extra info about a crate loaded for plugins or exported macros.
@@ -164,10 +144,11 @@ impl PMDSource {
 }
 
 impl<'a> CrateReader<'a> {
-    pub fn new(sess: &'a Session) -> CrateReader<'a> {
+    pub fn new(sess: &'a Session, cstore: &'a CStore) -> CrateReader<'a> {
         CrateReader {
             sess: sess,
-            next_crate_num: sess.cstore.next_crate_num(),
+            cstore: cstore,
+            next_crate_num: cstore.next_crate_num(),
             foreign_item_map: FnvHashMap(),
         }
     }
@@ -224,7 +205,7 @@ impl<'a> CrateReader<'a> {
     fn existing_match(&self, name: &str, hash: Option<&Svh>, kind: PathKind)
                       -> Option<ast::CrateNum> {
         let mut ret = None;
-        self.sess.cstore.iter_crate_data(|cnum, data| {
+        self.cstore.iter_crate_data(|cnum, data| {
             if data.name != name { return }
 
             match hash {
@@ -242,7 +223,7 @@ impl<'a> CrateReader<'a> {
             // We're also sure to compare *paths*, not actual byte slices. The
             // `source` stores paths which are normalized which may be different
             // from the strings on the command line.
-            let source = self.sess.cstore.get_used_crate_source(cnum).unwrap();
+            let source = self.cstore.used_crate_source(cnum);
             if let Some(locs) = self.sess.opts.externs.get(name) {
                 let found = locs.iter().any(|l| {
                     let l = fs::canonicalize(l).ok();
@@ -342,8 +323,8 @@ impl<'a> CrateReader<'a> {
             cnum: cnum,
         };
 
-        self.sess.cstore.set_crate_data(cnum, cmeta.clone());
-        self.sess.cstore.add_used_crate_source(source.clone());
+        self.cstore.set_crate_data(cnum, cmeta.clone());
+        self.cstore.add_used_crate_source(source.clone());
         (cnum, cmeta, source)
     }
 
@@ -398,7 +379,7 @@ impl<'a> CrateReader<'a> {
                 let meta_hash = decoder::get_crate_hash(library.metadata
                                                                .as_slice());
                 let mut result = LookupResult::Loaded(library);
-                self.sess.cstore.iter_crate_data(|cnum, data| {
+                self.cstore.iter_crate_data(|cnum, data| {
                     if data.name() == name && meta_hash == data.hash() {
                         assert!(hash.is_none());
                         result = LookupResult::Previous(cnum);
@@ -410,11 +391,11 @@ impl<'a> CrateReader<'a> {
 
         match result {
             LookupResult::Previous(cnum) => {
-                let data = self.sess.cstore.get_crate_data(cnum);
+                let data = self.cstore.get_crate_data(cnum);
                 if explicitly_linked && !data.explicitly_linked.get() {
                     data.explicitly_linked.set(explicitly_linked);
                 }
-                (cnum, data, self.sess.cstore.get_used_crate_source(cnum).unwrap())
+                (cnum, data, self.cstore.used_crate_source(cnum))
             }
             LookupResult::Loaded(library) => {
                 self.register_crate(root, ident, name, span, library,
@@ -512,7 +493,7 @@ impl<'a> CrateReader<'a> {
         let source_name = format!("<{} macros>", item.ident);
         let mut macros = vec![];
         decoder::each_exported_macro(ekrate.metadata.as_slice(),
-                                     &*self.sess.cstore.intr,
+                                     &*self.cstore.intr,
             |name, attrs, body| {
                 // NB: Don't use parse::parse_tts_from_source_str because it parses with
                 // quote_depth > 0.
@@ -593,14 +574,14 @@ impl<'a> CrateReader<'a> {
     }
 
     fn register_statically_included_foreign_items(&mut self) {
-        let libs = self.sess.cstore.get_used_libraries();
+        let libs = self.cstore.get_used_libraries();
         for (lib, list) in self.foreign_item_map.iter() {
             let is_static = libs.borrow().iter().any(|&(ref name, kind)| {
                 lib == name && kind == cstore::NativeStatic
             });
             if is_static {
                 for id in list {
-                    self.sess.cstore.add_statically_included_foreign_item(*id);
+                    self.cstore.add_statically_included_foreign_item(*id);
                 }
             }
         }
@@ -614,7 +595,7 @@ impl<'a> CrateReader<'a> {
         // also bail out as we don't need to implicitly inject one.
         let mut needs_allocator = false;
         let mut found_required_allocator = false;
-        self.sess.cstore.iter_crate_data(|cnum, data| {
+        self.cstore.iter_crate_data(|cnum, data| {
             needs_allocator = needs_allocator || data.needs_allocator();
             if data.is_allocator() {
                 debug!("{} required by rlib and is an allocator", data.name());
@@ -693,7 +674,7 @@ impl<'a> CrateReader<'a> {
         //
         // Here we inject a dependency from all crates with #![needs_allocator]
         // to the crate tagged with #![allocator] for this compilation unit.
-        self.sess.cstore.iter_crate_data(|cnum, data| {
+        self.cstore.iter_crate_data(|cnum, data| {
             if !data.needs_allocator() {
                 return
             }
@@ -707,10 +688,10 @@ impl<'a> CrateReader<'a> {
 
         fn validate(me: &CrateReader, krate: ast::CrateNum,
                     allocator: ast::CrateNum) {
-            let data = me.sess.cstore.get_crate_data(krate);
+            let data = me.cstore.get_crate_data(krate);
             if data.needs_allocator() {
                 let krate_name = data.name();
-                let data = me.sess.cstore.get_crate_data(allocator);
+                let data = me.cstore.get_crate_data(allocator);
                 let alloc_name = data.name();
                 me.sess.err(&format!("the allocator crate `{}` cannot depend \
                                       on a crate that needs an allocator, but \
@@ -726,10 +707,12 @@ impl<'a> CrateReader<'a> {
 }
 
 impl<'a, 'b> LocalCrateReader<'a, 'b> {
-    pub fn new(sess: &'a Session, map: &'a hir_map::Map<'b>) -> LocalCrateReader<'a, 'b> {
+    pub fn new(sess: &'a Session, cstore: &'a CStore,
+               map: &'a hir_map::Map<'b>) -> LocalCrateReader<'a, 'b> {
         LocalCrateReader {
             sess: sess,
-            creader: CrateReader::new(sess),
+            cstore: cstore,
+            creader: CrateReader::new(sess, cstore),
             ast_map: map,
         }
     }
@@ -743,11 +726,11 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
         self.creader.inject_allocator_crate();
 
         if log_enabled!(log::INFO) {
-            dump_crates(&self.sess.cstore);
+            dump_crates(&self.cstore);
         }
 
         for &(ref name, kind) in &self.sess.opts.libs {
-            register_native_lib(self.sess, None, name.clone(), kind);
+            register_native_lib(self.sess, self.cstore, None, name.clone(), kind);
         }
         self.creader.register_statically_included_foreign_items();
     }
@@ -755,7 +738,7 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
     fn process_crate(&self, c: &hir::Crate) {
         for a in c.attrs.iter().filter(|m| m.name() == "link_args") {
             match a.value_str() {
-                Some(ref linkarg) => self.sess.cstore.add_used_link_args(&linkarg),
+                Some(ref linkarg) => self.cstore.add_used_link_args(&linkarg),
                 None => { /* fallthrough */ }
             }
         }
@@ -783,7 +766,7 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
                         self.ast_map.with_path(i.id, |path| {
                             cmeta.update_local_path(path)
                         });
-                        self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
+                        self.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
                     }
                     None => ()
                 }
@@ -801,7 +784,7 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
         // First, add all of the custom #[link_args] attributes
         for m in i.attrs.iter().filter(|a| a.check_name("link_args")) {
             if let Some(linkarg) = m.value_str() {
-                self.sess.cstore.add_used_link_args(&linkarg);
+                self.cstore.add_used_link_args(&linkarg);
             }
         }
 
@@ -836,7 +819,7 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
                     InternedString::new("foo")
                 }
             };
-            register_native_lib(self.sess, Some(m.span), n.to_string(), kind);
+            register_native_lib(self.sess, self.cstore, Some(m.span), n.to_string(), kind);
         }
 
         // Finally, process the #[linked_from = "..."] attribute
diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs
new file mode 100644
index 00000000000..3c97692ee56
--- /dev/null
+++ b/src/librustc_metadata/csearch.rs
@@ -0,0 +1,487 @@
+// Copyright 2015 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.
+
+use astencode;
+use cstore;
+use decoder;
+use encoder;
+use loader;
+
+use middle::cstore::{CrateStore, CrateSource, ChildItem, FoundAst};
+use middle::cstore::{NativeLibraryKind, LinkMeta, LinkagePreference};
+use middle::def;
+use middle::lang_items;
+use middle::ty::{self, Ty};
+use middle::def_id::{DefId, DefIndex};
+
+use rustc::front::map as ast_map;
+use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet};
+
+use std::cell::RefCell;
+use std::rc::Rc;
+use std::path::PathBuf;
+use syntax::ast;
+use syntax::attr;
+use rustc_back::svh::Svh;
+use rustc_back::target::Target;
+use rustc_front::hir;
+
+impl<'tcx> CrateStore<'tcx> for cstore::CStore {
+    fn stability(&self, def: DefId) -> Option<attr::Stability>
+    {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_stability(&*cdata, def.index)
+    }
+
+    fn closure_kind(&self, _tcx: &ty::ctxt<'tcx>, def_id: DefId) -> ty::ClosureKind
+    {
+        assert!(!def_id.is_local());
+        let cdata = self.get_crate_data(def_id.krate);
+        decoder::closure_kind(&*cdata, def_id.index)
+    }
+
+    fn closure_ty(&self, tcx: &ty::ctxt<'tcx>, def_id: DefId) -> ty::ClosureTy<'tcx>
+    {
+        assert!(!def_id.is_local());
+        let cdata = self.get_crate_data(def_id.krate);
+        decoder::closure_ty(&*cdata, def_id.index, tcx)
+    }
+
+    fn item_variances(&self, def: DefId) -> ty::ItemVariances {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_item_variances(&*cdata, def.index)
+    }
+
+    fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr> {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_repr_attrs(&*cdata, def.index)
+    }
+
+    fn item_type(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                 -> ty::TypeScheme<'tcx>
+    {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_type(&*cdata, def.index, tcx)
+    }
+
+    fn item_predicates(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                       -> ty::GenericPredicates<'tcx>
+    {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_predicates(&*cdata, def.index, tcx)
+    }
+
+    fn item_super_predicates(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                             -> ty::GenericPredicates<'tcx>
+    {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_super_predicates(&*cdata, def.index, tcx)
+    }
+
+    fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>
+    {
+        let cdata = self.get_crate_data(def_id.krate);
+        decoder::get_item_attrs(&*cdata, def_id.index)
+    }
+
+    fn item_symbol(&self, def: DefId) -> String
+    {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_symbol(&cdata, def.index)
+    }
+
+    fn trait_def(&self, tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::TraitDef<'tcx>
+    {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_trait_def(&*cdata, def.index, tcx)
+    }
+
+    fn adt_def(&self, tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
+    {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_adt_def(&self.intr, &*cdata, def.index, tcx)
+    }
+
+    fn method_arg_names(&self, did: DefId) -> Vec<String>
+    {
+        let cdata = self.get_crate_data(did.krate);
+        decoder::get_method_arg_names(&cdata, did.index)
+    }
+
+    fn item_path(&self, def: DefId) -> Vec<ast_map::PathElem> {
+        let cdata = self.get_crate_data(def.krate);
+        let path = decoder::get_item_path(&*cdata, def.index);
+
+        cdata.with_local_path(|cpath| {
+            let mut r = Vec::with_capacity(cpath.len() + path.len());
+            r.push_all(cpath);
+            r.push_all(&path);
+            r
+        })
+    }
+
+    fn item_name(&self, def: DefId) -> ast::Name {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_item_name(&self.intr, &cdata, def.index)
+    }
+
+
+    fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>
+    {
+        let mut result = vec![];
+        let cdata = self.get_crate_data(def_id.krate);
+        decoder::each_inherent_implementation_for_type(&*cdata, def_id.index,
+                                                       |iid| result.push(iid));
+        result
+    }
+
+    fn implementations_of_trait(&self, def_id: DefId) -> Vec<DefId>
+    {
+        let mut result = vec![];
+        self.iter_crate_data(|_, cdata| {
+            decoder::each_implementation_for_trait(cdata, def_id, &mut |iid| {
+                result.push(iid)
+            })
+        });
+        result
+    }
+
+    fn provided_trait_methods(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                              -> Vec<Rc<ty::Method<'tcx>>>
+    {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_provided_trait_methods(self.intr.clone(), &*cdata, def.index, tcx)
+    }
+
+    fn trait_item_def_ids(&self, def: DefId)
+                          -> Vec<ty::ImplOrTraitItemId>
+    {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_trait_item_def_ids(&*cdata, def.index)
+    }
+
+    fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>
+    {
+        let cdata = self.get_crate_data(impl_def_id.krate);
+        decoder::get_impl_items(&*cdata, impl_def_id.index)
+    }
+
+    fn impl_polarity(&self, def: DefId) -> Option<hir::ImplPolarity>
+    {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_impl_polarity(&*cdata, def.index)
+    }
+
+    fn impl_trait_ref(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                      -> Option<ty::TraitRef<'tcx>>
+    {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_impl_trait(&*cdata, def.index, tcx)
+    }
+
+    fn custom_coerce_unsized_kind(&self, def: DefId)
+                                  -> Option<ty::adjustment::CustomCoerceUnsized>
+    {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_custom_coerce_unsized_kind(&*cdata, def.index)
+    }
+
+    // FIXME: killme
+    fn associated_consts(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                         -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_associated_consts(self.intr.clone(), &*cdata, def.index, tcx)
+    }
+
+    fn trait_of_item(&self, tcx: &ty::ctxt<'tcx>, def_id: DefId) -> Option<DefId>
+    {
+        let cdata = self.get_crate_data(def_id.krate);
+        decoder::get_trait_of_item(&*cdata, def_id.index, tcx)
+    }
+
+    fn impl_or_trait_item(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                          -> ty::ImplOrTraitItem<'tcx>
+    {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_impl_or_trait_item(
+            self.intr.clone(),
+            &*cdata,
+            def.index,
+            tcx)
+    }
+
+    fn is_const_fn(&self, did: DefId) -> bool
+    {
+        let cdata = self.get_crate_data(did.krate);
+        decoder::is_const_fn(&cdata, did.index)
+    }
+
+    fn is_defaulted_trait(&self, trait_def_id: DefId) -> bool
+    {
+        let cdata = self.get_crate_data(trait_def_id.krate);
+        decoder::is_defaulted_trait(&*cdata, trait_def_id.index)
+    }
+
+    fn is_impl(&self, did: DefId) -> bool
+    {
+        let cdata = self.get_crate_data(did.krate);
+        decoder::is_impl(&*cdata, did.index)
+    }
+
+    fn is_default_impl(&self, impl_did: DefId) -> bool {
+        let cdata = self.get_crate_data(impl_did.krate);
+        decoder::is_default_impl(&*cdata, impl_did.index)
+    }
+
+    fn is_extern_fn(&self, tcx: &ty::ctxt<'tcx>, did: DefId) -> bool
+    {
+        let cdata = self.get_crate_data(did.krate);
+        decoder::is_extern_fn(&*cdata, did.index, tcx)
+    }
+
+    fn is_static(&self, did: DefId) -> bool
+    {
+        let cdata = self.get_crate_data(did.krate);
+        decoder::is_static(&*cdata, did.index)
+    }
+
+    fn is_static_method(&self, def: DefId) -> bool
+    {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::is_static_method(&*cdata, def.index)
+    }
+
+    fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool
+    {
+        self.do_is_statically_included_foreign_item(id)
+    }
+
+    fn is_typedef(&self, did: DefId) -> bool {
+        let cdata = self.get_crate_data(did.krate);
+        decoder::is_typedef(&*cdata, did.index)
+    }
+
+    fn dylib_dependency_formats(&self, cnum: ast::CrateNum)
+                                -> Vec<(ast::CrateNum, LinkagePreference)>
+    {
+        let cdata = self.get_crate_data(cnum);
+        decoder::get_dylib_dependency_formats(&cdata)
+    }
+
+    fn lang_items(&self, cnum: ast::CrateNum) -> Vec<(DefIndex, usize)>
+    {
+        let mut result = vec![];
+        let crate_data = self.get_crate_data(cnum);
+        decoder::each_lang_item(&*crate_data, |did, lid| {
+            result.push((did, lid)); true
+        });
+        result
+    }
+
+    fn missing_lang_items(&self, cnum: ast::CrateNum)
+                          -> Vec<lang_items::LangItem>
+    {
+        let cdata = self.get_crate_data(cnum);
+        decoder::get_missing_lang_items(&*cdata)
+    }
+
+    fn is_staged_api(&self, cnum: ast::CrateNum) -> bool
+    {
+        self.get_crate_data(cnum).staged_api
+    }
+
+    fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool
+    {
+        self.get_crate_data(cnum).explicitly_linked.get()
+    }
+
+    fn is_allocator(&self, cnum: ast::CrateNum) -> bool
+    {
+        self.get_crate_data(cnum).is_allocator()
+    }
+
+    fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>
+    {
+        decoder::get_crate_attributes(self.get_crate_data(cnum).data())
+    }
+
+    fn crate_name(&self, cnum: ast::CrateNum) -> String
+    {
+        self.get_crate_data(cnum).name.clone()
+    }
+
+    fn crate_hash(&self, cnum: ast::CrateNum) -> Svh
+    {
+        let cdata = self.get_crate_data(cnum);
+        decoder::get_crate_hash(cdata.data())
+    }
+
+    fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
+                                -> FnvHashMap<DefId, Vec<ast::Attribute>>
+    {
+        decoder::get_struct_field_attrs(&*self.get_crate_data(cnum))
+    }
+
+    fn plugin_registrar_fn(&self, cnum: ast::CrateNum) -> Option<DefId>
+    {
+        let cdata = self.get_crate_data(cnum);
+        decoder::get_plugin_registrar_fn(cdata.data()).map(|index| DefId {
+            krate: cnum,
+            index: index
+        })
+    }
+
+    fn native_libraries(&self, cnum: ast::CrateNum) -> Vec<(NativeLibraryKind, String)>
+    {
+        let cdata = self.get_crate_data(cnum);
+        decoder::get_native_libraries(&*cdata)
+    }
+
+    fn reachable_ids(&self, cnum: ast::CrateNum) -> Vec<DefId>
+    {
+        let cdata = self.get_crate_data(cnum);
+        decoder::get_reachable_ids(&*cdata)
+    }
+
+    fn def_path(&self, def: DefId) -> ast_map::DefPath
+    {
+        let cdata = self.get_crate_data(def.krate);
+        let path = decoder::def_path(&*cdata, def.index);
+        let local_path = cdata.local_def_path();
+        local_path.into_iter().chain(path).collect()
+    }
+
+    fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option<DefId>
+    {
+        let cdata = self.get_crate_data(did.krate);
+        decoder::get_tuple_struct_definition_if_ctor(&*cdata, did.index)
+    }
+
+    fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>
+    {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_struct_field_names(&self.intr, &*cdata, def.index)
+    }
+
+    fn item_children(&self, def_id: DefId) -> Vec<ChildItem>
+    {
+        let mut result = vec![];
+        let crate_data = self.get_crate_data(def_id.krate);
+        let get_crate_data = |cnum| self.get_crate_data(cnum);
+        decoder::each_child_of_item(
+            self.intr.clone(), &*crate_data,
+            def_id.index, get_crate_data,
+            |def, name, vis| result.push(ChildItem {
+                def: def,
+                name: name,
+                vis: vis
+            }));
+        result
+    }
+
+    fn crate_top_level_items(&self, cnum: ast::CrateNum) -> Vec<ChildItem>
+    {
+        let mut result = vec![];
+        let crate_data = self.get_crate_data(cnum);
+        let get_crate_data = |cnum| self.get_crate_data(cnum);
+        decoder::each_top_level_item_of_crate(
+            self.intr.clone(), &*crate_data, get_crate_data,
+            |def, name, vis| result.push(ChildItem {
+                def: def,
+                name: name,
+                vis: vis
+            }));
+        result
+    }
+
+    fn maybe_get_item_ast(&'tcx self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                          -> FoundAst<'tcx>
+    {
+        let cdata = self.get_crate_data(def.krate);
+        let decode_inlined_item = Box::new(astencode::decode_inlined_item);
+        decoder::maybe_get_item_ast(&*cdata, tcx, def.index, decode_inlined_item)
+    }
+
+    fn crates(&self) -> Vec<ast::CrateNum>
+    {
+        let mut result = vec![];
+        self.iter_crate_data(|cnum, _| result.push(cnum));
+        result
+    }
+
+    fn used_libraries(&self) -> Vec<(String, NativeLibraryKind)>
+    {
+        self.get_used_libraries().borrow().clone()
+    }
+
+    fn used_link_args(&self) -> Vec<String>
+    {
+        self.get_used_link_args().borrow().clone()
+    }
+
+    fn metadata_filename(&self) -> &str
+    {
+        loader::METADATA_FILENAME
+    }
+
+    fn metadata_section_name(&self, target: &Target) -> &str
+    {
+        loader::meta_section_name(target)
+    }
+    fn encode_type(&self, tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Vec<u8>
+    {
+        encoder::encoded_ty(tcx, ty)
+    }
+
+    fn used_crates(&self, prefer: LinkagePreference) -> Vec<(ast::CrateNum, Option<PathBuf>)>
+    {
+        self.do_get_used_crates(prefer)
+    }
+
+    fn used_crate_source(&self, cnum: ast::CrateNum) -> CrateSource
+    {
+        self.opt_used_crate_source(cnum).unwrap()
+    }
+
+    fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum>
+    {
+        self.do_extern_mod_stmt_cnum(emod_id)
+    }
+
+    fn encode_metadata(&self,
+                       tcx: &ty::ctxt<'tcx>,
+                       reexports: &def::ExportMap,
+                       item_symbols: &RefCell<NodeMap<String>>,
+                       link_meta: &LinkMeta,
+                       reachable: &NodeSet,
+                       krate: &hir::Crate) -> Vec<u8>
+    {
+        let encode_inlined_item: encoder::EncodeInlinedItem =
+            Box::new(|ecx, rbml_w, ii| astencode::encode_inlined_item(ecx, rbml_w, ii));
+
+        let encode_params = encoder::EncodeParams {
+            diag: tcx.sess.diagnostic(),
+            tcx: tcx,
+            reexports: reexports,
+            item_symbols: item_symbols,
+            link_meta: link_meta,
+            cstore: self,
+            encode_inlined_item: encode_inlined_item,
+            reachable: reachable
+        };
+        encoder::encode_metadata(encode_params, krate)
+
+    }
+
+    fn metadata_encoding_version(&self) -> &[u8]
+    {
+        encoder::metadata_encoding_version
+    }
+}
diff --git a/src/librustc/metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 873c22c35d8..b0eef29467b 100644
--- a/src/librustc/metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -14,13 +14,15 @@
 // crates and libraries
 
 pub use self::MetadataBlob::*;
-pub use self::LinkagePreference::*;
-pub use self::NativeLibraryKind::*;
 
-use back::svh::Svh;
-use metadata::{creader, decoder, index, loader};
-use session::search_paths::PathKind;
-use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
+use creader;
+use decoder;
+use index;
+use loader;
+
+use rustc::back::svh::Svh;
+use rustc::front::map as ast_map;
+use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet};
 
 use std::cell::{RefCell, Ref, Cell};
 use std::rc::Rc;
@@ -32,7 +34,10 @@ use syntax::codemap;
 use syntax::parse::token;
 use syntax::parse::token::IdentInterner;
 use syntax::util::small_vector::SmallVector;
-use front::map as ast_map;
+
+pub use middle::cstore::{NativeLibraryKind, LinkagePreference};
+pub use middle::cstore::{NativeStatic, NativeFramework, NativeUnknown};
+pub use middle::cstore::{CrateSource, LinkMeta};
 
 // A map from external crate numbers (as decoded from some crate file) to
 // local crate numbers (as generated during this session). Each external
@@ -77,30 +82,6 @@ pub struct crate_metadata {
     pub explicitly_linked: Cell<bool>,
 }
 
-#[derive(Copy, Debug, PartialEq, Clone)]
-pub enum LinkagePreference {
-    RequireDynamic,
-    RequireStatic,
-}
-
-enum_from_u32! {
-    #[derive(Copy, Clone, PartialEq)]
-    pub enum NativeLibraryKind {
-        NativeStatic,    // native static library (.a archive)
-        NativeFramework, // OSX-specific
-        NativeUnknown,   // default way to specify a dynamic library
-    }
-}
-
-// Where a crate came from on the local filesystem. One of these two options
-// must be non-None.
-#[derive(PartialEq, Clone)]
-pub struct CrateSource {
-    pub dylib: Option<(PathBuf, PathKind)>,
-    pub rlib: Option<(PathBuf, PathKind)>,
-    pub cnum: ast::CrateNum,
-}
-
 pub struct CStore {
     metas: RefCell<FnvHashMap<ast::CrateNum, Rc<crate_metadata>>>,
     /// Map from NodeId's of local extern crate statements to crate numbers
@@ -112,10 +93,6 @@ pub struct CStore {
     pub intr: Rc<IdentInterner>,
 }
 
-/// Item definitions in the currently-compiled crate would have the CrateNum
-/// LOCAL_CRATE in their DefId.
-pub const LOCAL_CRATE: ast::CrateNum = 0;
-
 impl CStore {
     pub fn new(intr: Rc<IdentInterner>) -> CStore {
         CStore {
@@ -159,7 +136,7 @@ impl CStore {
         I: FnMut(ast::CrateNum, &crate_metadata, Option<CrateSource>),
     {
         for (&k, v) in self.metas.borrow().iter() {
-            let origin = self.get_used_crate_source(k);
+            let origin = self.opt_used_crate_source(k);
             origin.as_ref().map(|cs| { assert!(k == cs.cnum); });
             i(k, &**v, origin);
         }
@@ -172,8 +149,8 @@ impl CStore {
         }
     }
 
-    pub fn get_used_crate_source(&self, cnum: ast::CrateNum)
-                                     -> Option<CrateSource> {
+    pub fn opt_used_crate_source(&self, cnum: ast::CrateNum)
+                                 -> Option<CrateSource> {
         self.used_crate_sources.borrow_mut()
             .iter().find(|source| source.cnum == cnum).cloned()
     }
@@ -196,8 +173,8 @@ impl CStore {
     // In order to get this left-to-right dependency ordering, we perform a
     // topological sort of all crates putting the leaves at the right-most
     // positions.
-    pub fn get_used_crates(&self, prefer: LinkagePreference)
-                           -> Vec<(ast::CrateNum, Option<PathBuf>)> {
+    pub fn do_get_used_crates(&self, prefer: LinkagePreference)
+                              -> Vec<(ast::CrateNum, Option<PathBuf>)> {
         let mut ordering = Vec::new();
         fn visit(cstore: &CStore, cnum: ast::CrateNum,
                  ordering: &mut Vec<ast::CrateNum>) {
@@ -216,8 +193,8 @@ impl CStore {
         let mut libs = self.used_crate_sources.borrow()
             .iter()
             .map(|src| (src.cnum, match prefer {
-                RequireDynamic => src.dylib.clone().map(|p| p.0),
-                RequireStatic => src.rlib.clone().map(|p| p.0),
+                LinkagePreference::RequireDynamic => src.dylib.clone().map(|p| p.0),
+                LinkagePreference::RequireStatic => src.rlib.clone().map(|p| p.0),
             }))
             .collect::<Vec<_>>();
         libs.sort_by(|&(a, _), &(b, _)| {
@@ -255,18 +232,18 @@ impl CStore {
         self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum);
     }
 
-    pub fn find_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId)
-                                     -> Option<ast::CrateNum> {
-        self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
-    }
-
     pub fn add_statically_included_foreign_item(&self, id: ast::NodeId) {
         self.statically_included_foreign_items.borrow_mut().insert(id);
     }
 
-    pub fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool {
+    pub fn do_is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool {
         self.statically_included_foreign_items.borrow().contains(&id)
     }
+
+    pub fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum>
+    {
+        self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
+    }
 }
 
 impl crate_metadata {
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index b102213eff0..092f7849115 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -12,30 +12,27 @@
 
 #![allow(non_camel_case_types)]
 
-pub use self::DefLike::*;
 use self::Family::*;
 
-use front::map as hir_map;
+use cstore::{self, crate_metadata};
+use common::*;
+use encoder::def_to_u64;
+use index;
+use tydecode::TyDecoder;
+
+use rustc::back::svh::Svh;
+use rustc::front::map as hir_map;
+use rustc::util::nodemap::FnvHashMap;
 use rustc_front::hir;
 
-use back::svh::Svh;
-use metadata::cstore::crate_metadata;
-use metadata::cstore::LOCAL_CRATE;
-use metadata::common::*;
-use metadata::csearch::MethodInfo;
-use metadata::csearch;
-use metadata::cstore;
-use metadata::encoder::def_to_u64;
-use metadata::index;
-use metadata::inline::InlinedItem;
-use metadata::tydecode::TyDecoder;
+use middle::cstore::{LOCAL_CRATE, FoundAst, InlinedItem, LinkagePreference};
+use middle::cstore::{DefLike, DlDef, DlField, DlImpl};
 use middle::def;
 use middle::def_id::{DefId, DefIndex};
 use middle::lang_items;
 use middle::subst;
 use middle::ty::{ImplContainer, TraitContainer};
 use middle::ty::{self, RegionEscape, Ty};
-use util::nodemap::FnvHashMap;
 
 use std::cell::{Cell, RefCell};
 use std::io::prelude::*;
@@ -591,14 +588,6 @@ pub fn get_symbol_from_buf(data: &[u8], id: DefIndex) -> String {
     item_symbol(doc)
 }
 
-// Something that a name can resolve to.
-#[derive(Copy, Clone, Debug)]
-pub enum DefLike {
-    DlDef(def::Def),
-    DlImpl(DefId),
-    DlField
-}
-
 /// Iterates over the language items in the given crate.
 pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
     F: FnMut(DefIndex, usize) -> bool,
@@ -771,24 +760,24 @@ pub type DecodeInlinedItem<'a> =
 
 pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: DefIndex,
                                 mut decode_inlined_item: DecodeInlinedItem)
-                                -> csearch::FoundAst<'tcx> {
+                                -> FoundAst<'tcx> {
     debug!("Looking up item: {:?}", id);
     let item_doc = cdata.lookup_item(id);
     let item_did = item_def_id(item_doc, cdata);
     let path = item_path(item_doc).split_last().unwrap().1.to_vec();
     let def_path = def_path(cdata, id);
     match decode_inlined_item(cdata, tcx, path, def_path, item_doc, item_did) {
-        Ok(ii) => csearch::FoundAst::Found(ii),
+        Ok(ii) => FoundAst::Found(ii),
         Err((path, def_path)) => {
             match item_parent_item(cdata, item_doc) {
                 Some(did) => {
                     let parent_item = cdata.lookup_item(did.index);
                     match decode_inlined_item(cdata, tcx, path, def_path, parent_item, did) {
-                        Ok(ii) => csearch::FoundAst::FoundParent(did, ii),
-                        Err(_) => csearch::FoundAst::NotFound
+                        Ok(ii) => FoundAst::FoundParent(did, ii),
+                        Err(_) => FoundAst::NotFound
                     }
                 }
-                None => csearch::FoundAst::NotFound
+                None => FoundAst::NotFound
             }
         }
     }
@@ -997,42 +986,6 @@ pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
     }).collect()
 }
 
-pub fn get_methods_if_impl(intr: Rc<IdentInterner>,
-                                  cdata: Cmd,
-                                  node_id: DefIndex)
-                               -> Option<Vec<MethodInfo> > {
-    let item = cdata.lookup_item(node_id);
-    if item_family(item) != Impl {
-        return None;
-    }
-
-    // If this impl implements a trait, don't consider it.
-    if reader::tagged_docs(item, tag_item_trait_ref).next().is_some() {
-        return None;
-    }
-
-    let impl_method_ids = reader::tagged_docs(item, tag_item_impl_item)
-        .map(|impl_method_doc| item_def_id(impl_method_doc, cdata));
-
-    let mut impl_methods = Vec::new();
-    for impl_method_id in impl_method_ids {
-        let impl_method_doc = cdata.lookup_item(impl_method_id.index);
-        let family = item_family(impl_method_doc);
-        match family {
-            StaticMethod | Method => {
-                impl_methods.push(MethodInfo {
-                    name: item_name(&*intr, impl_method_doc),
-                    def_id: item_def_id(impl_method_doc, cdata),
-                    vis: item_visibility(impl_method_doc),
-                });
-            }
-            _ => {}
-        }
-    }
-
-    return Some(impl_methods);
-}
-
 /// If node_id is the constructor of a tuple struct, retrieve the NodeId of
 /// the actual type definition, otherwise, return None
 pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
@@ -1352,7 +1305,7 @@ pub fn each_exported_macro<F>(data: &[u8], intr: &IdentInterner, mut f: F) where
 }
 
 pub fn get_dylib_dependency_formats(cdata: Cmd)
-    -> Vec<(ast::CrateNum, cstore::LinkagePreference)>
+    -> Vec<(ast::CrateNum, LinkagePreference)>
 {
     let formats = reader::get_doc(rbml::Doc::new(cdata.data()),
                                   tag_dylib_dependency_formats);
@@ -1369,9 +1322,9 @@ pub fn get_dylib_dependency_formats(cdata: Cmd)
             None => panic!("didn't find a crate in the cnum_map")
         };
         result.push((cnum, if link == "d" {
-            cstore::RequireDynamic
+            LinkagePreference::RequireDynamic
         } else {
-            cstore::RequireStatic
+            LinkagePreference::RequireStatic
         }));
     }
     return result;
diff --git a/src/librustc_metadata/diagnostics.rs b/src/librustc_metadata/diagnostics.rs
new file mode 100644
index 00000000000..2340efd2cae
--- /dev/null
+++ b/src/librustc_metadata/diagnostics.rs
@@ -0,0 +1,77 @@
+// Copyright 2015 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.
+
+#![allow(non_snake_case)]
+
+register_long_diagnostics! {
+E0454: r##"
+A link name was given with an empty name. Erroneous code example:
+
+```
+#[link(name = "")] extern {} // error: #[link(name = "")] given with empty name
+```
+
+The rust compiler cannot link to an external library if you don't give it its
+name. Example:
+
+```
+#[link(name = "some_lib")] extern {} // ok!
+```
+"##,
+
+E0458: r##"
+An unknown "kind" was specified for a link attribute. Erroneous code example:
+
+```
+#[link(kind = "wonderful_unicorn")] extern {}
+// error: unknown kind: `wonderful_unicorn`
+```
+
+Please specify a valid "kind" value, from one of the following:
+ * static
+ * dylib
+ * framework
+"##,
+
+E0459: r##"
+A link was used without a name parameter. Erroneous code example:
+
+```
+#[link(kind = "dylib")] extern {}
+// error: #[link(...)] specified without `name = "foo"`
+```
+
+Please add the name parameter to allow the rust compiler to find the library
+you want. Example:
+
+```
+#[link(kind = "dylib", name = "some_lib")] extern {} // ok!
+```
+"##,
+
+}
+
+register_diagnostics! {
+    E0455, // native frameworks are only available on OSX targets
+    E0456, // plugin `..` is not available for triple `..`
+    E0457, // plugin `..` only found in rlib format, but must be available...
+    E0514, // metadata version mismatch
+    E0460, // found possibly newer version of crate `..`
+    E0461, // couldn't find crate `..` with expected target triple ..
+    E0462, // found staticlib `..` instead of rlib or dylib
+    E0463, // can't find crate for `..`
+    E0464, // multiple matching crates for `..`
+    E0465, // multiple .. candidates for `..` found
+    E0466, // bad macro import
+    E0467, // bad macro reexport
+    E0468, // an `extern crate` loading macros must be at the crate root
+    E0469, // imported macro not found
+    E0470, // reexported macro not found
+}
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index e543d8708b5..1d88fa4454b 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -13,22 +13,25 @@
 #![allow(unused_must_use)] // everything is just a MemWriter, can't fail
 #![allow(non_camel_case_types)]
 
-use back::svh::Svh;
-use session::config;
-use metadata::common::*;
-use metadata::cstore;
-use metadata::cstore::LOCAL_CRATE;
-use metadata::decoder;
-use metadata::tyencode;
-use metadata::index::{self, IndexData};
-use metadata::inline::InlinedItemRef;
+use common::*;
+use cstore;
+use decoder;
+use tyencode;
+use index::{self, IndexData};
+
+use middle::cstore::{LOCAL_CRATE, CrateStore, InlinedItemRef, LinkMeta};
 use middle::def;
 use middle::def_id::{CRATE_DEF_INDEX, DefId};
 use middle::dependency_format::Linkage;
 use middle::stability;
 use middle::subst;
 use middle::ty::{self, Ty};
-use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
+
+use rustc::back::svh::Svh;
+use rustc::front::map::{LinkedPath, PathElem, PathElems};
+use rustc::front::map as ast_map;
+use rustc::session::config;
+use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet};
 
 use serialize::Encodable;
 use std::cell::RefCell;
@@ -48,8 +51,6 @@ use rbml::writer::Encoder;
 use rustc_front::hir;
 use rustc_front::intravisit::Visitor;
 use rustc_front::intravisit;
-use front::map::{LinkedPath, PathElem, PathElems};
-use front::map as ast_map;
 
 pub type EncodeInlinedItem<'a> =
     Box<FnMut(&EncodeContext, &mut Encoder, InlinedItemRef) + 'a>;
@@ -1652,8 +1653,7 @@ fn encode_lang_items(ecx: &EncodeContext, rbml_w: &mut Encoder) {
 fn encode_native_libraries(ecx: &EncodeContext, rbml_w: &mut Encoder) {
     rbml_w.start_tag(tag_native_libraries);
 
-    for &(ref lib, kind) in ecx.tcx.sess.cstore.get_used_libraries()
-                               .borrow().iter() {
+    for &(ref lib, kind) in ecx.tcx.sess.cstore.used_libraries().iter() {
         match kind {
             cstore::NativeStatic => {} // these libraries are not propagated
             cstore::NativeFramework | cstore::NativeUnknown => {
diff --git a/src/librustc/metadata/index.rs b/src/librustc_metadata/index.rs
index 60bbdaddd75..60bbdaddd75 100644
--- a/src/librustc/metadata/index.rs
+++ b/src/librustc_metadata/index.rs
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
new file mode 100644
index 00000000000..6affbd2b593
--- /dev/null
+++ b/src/librustc_metadata/lib.rs
@@ -0,0 +1,61 @@
+// Copyright 2015 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.
+
+#![cfg_attr(stage0, feature(custom_attribute))]
+#![crate_name = "rustc_metadata"]
+#![unstable(feature = "rustc_private", issue = "27812")]
+#![cfg_attr(stage0, staged_api)]
+#![crate_type = "dylib"]
+#![crate_type = "rlib"]
+#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
+      html_root_url = "https://doc.rust-lang.org/nightly/")]
+
+#![feature(box_patterns)]
+#![feature(duration_span)]
+#![feature(enumset)]
+#![feature(quote)]
+#![feature(staged_api)]
+#![feature(vec_push_all)]
+#![feature(rustc_diagnostic_macros)]
+#![feature(rustc_private)]
+
+#[macro_use] extern crate log;
+#[macro_use] extern crate syntax;
+#[macro_use] #[no_link] extern crate rustc_bitflags;
+
+extern crate flate;
+extern crate rbml;
+extern crate serialize;
+
+extern crate rustc;
+extern crate rustc_back;
+extern crate rustc_front;
+extern crate rustc_llvm;
+
+pub use rustc::middle;
+
+#[macro_use]
+mod macros;
+
+pub mod diagnostics;
+
+pub mod astencode;
+pub mod common;
+pub mod tyencode;
+pub mod tydecode;
+pub mod encoder;
+pub mod decoder;
+pub mod creader;
+pub mod csearch;
+pub mod cstore;
+pub mod index;
+pub mod loader;
+pub mod macro_import;
diff --git a/src/librustc/metadata/loader.rs b/src/librustc_metadata/loader.rs
index ca1562683ef..72938a7660a 100644
--- a/src/librustc/metadata/loader.rs
+++ b/src/librustc_metadata/loader.rs
@@ -212,19 +212,21 @@
 //! no means all of the necessary details. Take a look at the rest of
 //! metadata::loader or metadata::creader for all the juicy details!
 
-use back::svh::Svh;
-use session::Session;
-use session::search_paths::PathKind;
-use llvm;
-use llvm::{False, ObjectFile, mk_section_iter};
-use llvm::archive_ro::ArchiveRO;
-use metadata::cstore::{MetadataBlob, MetadataVec, MetadataArchive};
-use metadata::decoder;
-use metadata::encoder;
-use metadata::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
+use cstore::{MetadataBlob, MetadataVec, MetadataArchive};
+use decoder;
+use encoder;
+
+use rustc::back::svh::Svh;
+use rustc::session::Session;
+use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
+use rustc::session::search_paths::PathKind;
+use rustc::util::common;
+
+use rustc_llvm as llvm;
+use rustc_llvm::{False, ObjectFile, mk_section_iter};
+use rustc_llvm::archive_ro::ArchiveRO;
 use syntax::codemap::Span;
 use syntax::diagnostic::SpanHandler;
-use util::common;
 use rustc_back::target::Target;
 
 use std::cmp;
diff --git a/src/librustc/metadata/macro_import.rs b/src/librustc_metadata/macro_import.rs
index ca5999afbd3..d67fc3a0eab 100644
--- a/src/librustc/metadata/macro_import.rs
+++ b/src/librustc_metadata/macro_import.rs
@@ -10,8 +10,10 @@
 
 //! Used by `rustc` when loading a crate with exported macros.
 
-use session::Session;
-use metadata::creader::CrateReader;
+use creader::CrateReader;
+use cstore::CStore;
+
+use rustc::session::Session;
 
 use std::collections::{HashSet, HashMap};
 use syntax::codemap::Span;
@@ -30,11 +32,11 @@ struct MacroLoader<'a> {
 }
 
 impl<'a> MacroLoader<'a> {
-    fn new(sess: &'a Session) -> MacroLoader<'a> {
+    fn new(sess: &'a Session, cstore: &'a CStore) -> MacroLoader<'a> {
         MacroLoader {
             sess: sess,
             span_whitelist: HashSet::new(),
-            reader: CrateReader::new(sess),
+            reader: CrateReader::new(sess, cstore),
             macros: vec![],
         }
     }
@@ -45,8 +47,10 @@ pub fn call_bad_macro_reexport(a: &Session, b: Span) {
 }
 
 /// Read exported macros.
-pub fn read_macro_defs(sess: &Session, krate: &ast::Crate) -> Vec<ast::MacroDef> {
-    let mut loader = MacroLoader::new(sess);
+pub fn read_macro_defs(sess: &Session, cstore: &CStore, krate: &ast::Crate)
+                       -> Vec<ast::MacroDef>
+{
+    let mut loader = MacroLoader::new(sess, cstore);
 
     // We need to error on `#[macro_use] extern crate` when it isn't at the
     // crate root, because `$crate` won't work properly. Identify these by
diff --git a/src/librustc_metadata/macros.rs b/src/librustc_metadata/macros.rs
new file mode 100644
index 00000000000..ed764ebd9f9
--- /dev/null
+++ b/src/librustc_metadata/macros.rs
@@ -0,0 +1,46 @@
+// Copyright 2015 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.
+
+macro_rules! enum_from_u32 {
+    ($(#[$attr:meta])* pub enum $name:ident {
+        $($variant:ident = $e:expr,)*
+    }) => {
+        $(#[$attr])*
+        pub enum $name {
+            $($variant = $e),*
+        }
+
+        impl $name {
+            pub fn from_u32(u: u32) -> Option<$name> {
+                $(if u == $name::$variant as u32 {
+                    return Some($name::$variant)
+                })*
+                None
+            }
+        }
+    };
+    ($(#[$attr:meta])* pub enum $name:ident {
+        $($variant:ident,)*
+    }) => {
+        $(#[$attr])*
+        pub enum $name {
+            $($variant,)*
+        }
+
+        impl $name {
+            pub fn from_u32(u: u32) -> Option<$name> {
+                $(if u == $name::$variant as u32 {
+                    return Some($name::$variant)
+                })*
+                None
+            }
+        }
+    }
+}
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc_metadata/tydecode.rs
index d03af6b6722..d03af6b6722 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc_metadata/tydecode.rs
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc_metadata/tyencode.rs
index 1b993a00e28..bc1edd5c767 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc_metadata/tyencode.rs
@@ -23,7 +23,7 @@ use middle::subst;
 use middle::subst::VecPerParamSpace;
 use middle::ty::ParamTy;
 use middle::ty::{self, Ty};
-use util::nodemap::FnvHashMap;
+use rustc::util::nodemap::FnvHashMap;
 
 use rustc_front::hir;
 
diff --git a/src/librustc/plugin/build.rs b/src/librustc_plugin/build.rs
index 00f58c6af91..00f58c6af91 100644
--- a/src/librustc/plugin/build.rs
+++ b/src/librustc_plugin/build.rs
diff --git a/src/librustc/metadata/mod.rs b/src/librustc_plugin/diagnostics.rs
index e532388d52e..100c1db1439 100644
--- a/src/librustc/metadata/mod.rs
+++ b/src/librustc_plugin/diagnostics.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,16 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub mod common;
-pub mod tyencode;
-pub mod tydecode;
-pub mod encoder;
-pub mod decoder;
-pub mod creader;
-pub mod cstore;
-pub mod csearch;
-pub mod index;
-pub mod loader;
-pub mod filesearch;
-pub mod macro_import;
-pub mod inline;
+#![allow(non_snake_case)]
+
+register_long_diagnostics! {
+
+}
+
+register_diagnostics! {
+    E0498  // malformed plugin attribute
+}
diff --git a/src/librustc/plugin/mod.rs b/src/librustc_plugin/lib.rs
index 4a85e1893f0..5dedef7ab6c 100644
--- a/src/librustc/plugin/mod.rs
+++ b/src/librustc_plugin/lib.rs
@@ -50,8 +50,32 @@
 //! See the [Plugins Chapter](../../book/compiler-plugins.html) of the book
 //! for more examples.
 
+#![cfg_attr(stage0, feature(custom_attribute))]
+#![crate_name = "rustc_plugin"]
+#![unstable(feature = "rustc_private", issue = "27812")]
+#![cfg_attr(stage0, staged_api)]
+#![crate_type = "dylib"]
+#![crate_type = "rlib"]
+#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
+      html_root_url = "https://doc.rust-lang.org/nightly/")]
+
+#![feature(dynamic_lib)]
+#![feature(staged_api)]
+#![feature(rustc_diagnostic_macros)]
+#![feature(rustc_private)]
+
+#[macro_use] extern crate log;
+#[macro_use] extern crate syntax;
+#[macro_use] #[no_link] extern crate rustc_bitflags;
+
+extern crate rustc;
+extern crate rustc_front;
+extern crate rustc_metadata;
+
 pub use self::registry::Registry;
 
+pub mod diagnostics;
 pub mod registry;
 pub mod load;
 pub mod build;
diff --git a/src/librustc/plugin/load.rs b/src/librustc_plugin/load.rs
index 751e748094d..51eec07505a 100644
--- a/src/librustc/plugin/load.rs
+++ b/src/librustc_plugin/load.rs
@@ -10,9 +10,10 @@
 
 //! Used by `rustc` when loading a plugin.
 
-use session::Session;
-use metadata::creader::CrateReader;
-use plugin::registry::Registry;
+use rustc::session::Session;
+use rustc_metadata::creader::CrateReader;
+use rustc_metadata::cstore::CStore;
+use registry::Registry;
 
 use std::borrow::ToOwned;
 use std::env;
@@ -43,9 +44,9 @@ fn call_malformed_plugin_attribute(a: &Session, b: Span) {
 }
 
 /// Read plugin metadata and dynamically load registrar functions.
-pub fn load_plugins(sess: &Session, krate: &ast::Crate,
+pub fn load_plugins(sess: &Session, cstore: &CStore, krate: &ast::Crate,
                     addl_plugins: Option<Vec<String>>) -> Vec<PluginRegistrar> {
-    let mut loader = PluginLoader::new(sess);
+    let mut loader = PluginLoader::new(sess, cstore);
 
     for attr in &krate.attrs {
         if !attr.check_name("plugin") {
@@ -81,10 +82,10 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
 }
 
 impl<'a> PluginLoader<'a> {
-    fn new(sess: &'a Session) -> PluginLoader<'a> {
+    fn new(sess: &'a Session, cstore: &'a CStore) -> PluginLoader<'a> {
         PluginLoader {
             sess: sess,
-            reader: CrateReader::new(sess),
+            reader: CrateReader::new(sess, cstore),
             plugins: vec![],
         }
     }
diff --git a/src/librustc/plugin/registry.rs b/src/librustc_plugin/registry.rs
index 50ca092dfe6..3138d7fa1db 100644
--- a/src/librustc/plugin/registry.rs
+++ b/src/librustc_plugin/registry.rs
@@ -10,8 +10,8 @@
 
 //! Used by plugin crates to tell `rustc` about the plugins they provide.
 
-use lint::{EarlyLintPassObject, LateLintPassObject, LintId, Lint};
-use session::Session;
+use rustc::lint::{EarlyLintPassObject, LateLintPassObject, LintId, Lint};
+use rustc::session::Session;
 
 use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
 use syntax::ext::base::{IdentTT, MultiModifier, MultiDecorator};
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 236d9cbe78c..13f7e318163 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -28,8 +28,7 @@ use {resolve_error, ResolutionError};
 
 use self::DuplicateCheckingMode::*;
 
-use rustc::metadata::csearch;
-use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
+use rustc::middle::cstore::{CrateStore, ChildItem, DlDef, DlField, DlImpl};
 use rustc::middle::def::*;
 use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
 
@@ -310,7 +309,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
             ItemExternCrate(_) => {
                 // n.b. we don't need to look at the path option here, because cstore already
                 // did
-                if let Some(crate_id) = self.session.cstore.find_extern_mod_stmt_cnum(item.id) {
+                if let Some(crate_id) = self.session.cstore.extern_mod_stmt_cnum(item.id) {
                     let def_id = DefId {
                         krate: crate_id,
                         index: CRATE_DEF_INDEX,
@@ -625,7 +624,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
             }
             DefFn(ctor_id, true) => {
                 child_name_bindings.define_value(
-                csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
+                self.session.cstore.tuple_struct_definition_if_ctor(ctor_id)
                     .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers);
             }
             DefFn(..) |
@@ -654,11 +653,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 // If this is a trait, add all the trait item names to the trait
                 // info.
 
-                let trait_item_def_ids = csearch::get_trait_item_def_ids(&self.session.cstore,
-                                                                         def_id);
+                let trait_item_def_ids = self.session.cstore.trait_item_def_ids(def_id);
                 for trait_item_def in &trait_item_def_ids {
-                    let trait_item_name = csearch::get_trait_name(&self.session.cstore,
-                                                                  trait_item_def.def_id());
+                    let trait_item_name =
+                        self.session.cstore.item_name(trait_item_def.def_id());
 
                     debug!("(building reduced graph for external crate) ... adding trait item \
                             '{}'",
@@ -695,7 +693,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 debug!("(building reduced graph for external crate) building type and value for \
                         {}",
                        final_ident);
-                let fields = csearch::get_struct_field_names(&self.session.cstore, def_id);
+                child_name_bindings.define_type(def, DUMMY_SP, modifiers);
+                let fields = self.session.cstore.struct_field_names(def_id);
 
                 if fields.is_empty() {
                     child_name_bindings.define_value(def, DUMMY_SP, modifiers);
@@ -719,39 +718,29 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
     /// Builds the reduced graph for a single item in an external crate.
     fn build_reduced_graph_for_external_crate_def(&mut self,
                                                   root: &Rc<Module>,
-                                                  def_like: DefLike,
-                                                  name: Name,
-                                                  def_visibility: Visibility) {
-        match def_like {
+                                                  xcdef: ChildItem) {
+        match xcdef.def {
             DlDef(def) => {
                 // Add the new child item, if necessary.
                 match def {
                     DefForeignMod(def_id) => {
                         // Foreign modules have no names. Recur and populate
                         // eagerly.
-                        csearch::each_child_of_item(&self.session.cstore,
-                                                    def_id,
-                                                    |def_like,
-                                                     child_name,
-                                                     vis| {
-                            self.build_reduced_graph_for_external_crate_def(
-                                root,
-                                def_like,
-                                child_name,
-                                vis)
-                        });
+                        for child in self.session.cstore.item_children(def_id) {
+                            self.build_reduced_graph_for_external_crate_def(root, child)
+                        }
                     }
                     _ => {
-                        let child_name_bindings = self.add_child(name,
+                        let child_name_bindings = self.add_child(xcdef.name,
                                                                  root,
                                                                  OverwriteDuplicates,
                                                                  DUMMY_SP);
 
                         self.handle_external_def(def,
-                                                 def_visibility,
+                                                 xcdef.vis,
                                                  &child_name_bindings,
-                                                 &name.as_str(),
-                                                 name,
+                                                 &xcdef.name.as_str(),
+                                                 xcdef.name,
                                                  root);
                     }
                 }
@@ -778,16 +767,11 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
             Some(def_id) => def_id,
         };
 
-        csearch::each_child_of_item(&self.session.cstore,
-                                    def_id,
-                                    |def_like, child_name, visibility| {
-                                        debug!("(populating external module) ... found ident: {}",
-                                               child_name);
-                                        self.build_reduced_graph_for_external_crate_def(module,
-                                                                                        def_like,
-                                                                                        child_name,
-                                                                                        visibility)
-                                    });
+        for child in self.session.cstore.item_children(def_id) {
+            debug!("(populating external module) ... found ident: {}",
+                   child.name);
+            self.build_reduced_graph_for_external_crate_def(module, child);
+        }
         module.populated.set(true)
     }
 
@@ -803,13 +787,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
     /// Builds the reduced graph rooted at the 'use' directive for an external
     /// crate.
     fn build_reduced_graph_for_external_crate(&mut self, root: &Rc<Module>) {
-        csearch::each_top_level_item_of_crate(&self.session.cstore,
-                                              root.def_id()
-                                                  .unwrap()
-                                                  .krate,
-                                              |def_like, name, visibility| {
-            self.build_reduced_graph_for_external_crate_def(root, def_like, name, visibility)
-        });
+        let root_cnum = root.def_id().unwrap().krate;
+        for child in self.session.cstore.crate_top_level_items(root_cnum) {
+            self.build_reduced_graph_for_external_crate_def(root, child);
+        }
     }
 
     /// Creates and adds an import directive to the given module.
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
index 439caf20b6b..7f740f9c033 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/src/librustc_resolve/check_unused.rs
@@ -123,7 +123,7 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
 
         match item.node {
             hir::ItemExternCrate(_) => {
-                if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(item.id) {
+                if let Some(crate_num) = self.session.cstore.extern_mod_stmt_cnum(item.id) {
                     if !self.used_crates.contains(&crate_num) {
                         self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
                                               item.id,
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 0e5384d19f5..ef03ac520df 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -54,8 +54,7 @@ use self::FallbackChecks::*;
 use rustc::front::map as hir_map;
 use rustc::session::Session;
 use rustc::lint;
-use rustc::metadata::csearch;
-use rustc::metadata::decoder::{DefLike, DlDef};
+use rustc::middle::cstore::{CrateStore, DefLike, DlDef};
 use rustc::middle::def::*;
 use rustc::middle::def_id::DefId;
 use rustc::middle::pat_util::pat_bindings_hygienic;
@@ -1235,7 +1234,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         if let Some(node_id) = self.ast_map.as_local_node_id(did) {
             self.ast_map.expect_item(node_id).name
         } else {
-            csearch::get_trait_name(&self.session.cstore, did)
+            self.session.cstore.item_name(did)
         }
     }
 
@@ -3298,7 +3297,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 };
                 sig.explicit_self.node == hir::SelfStatic
             } else {
-                csearch::is_static_method(&this.session.cstore, did)
+                this.session.cstore.is_static_method(did)
             }
         }
 
diff --git a/src/librustc_trans/back/archive.rs b/src/librustc_trans/back/archive.rs
index 1b3242eb97d..f5431554a75 100644
--- a/src/librustc_trans/back/archive.rs
+++ b/src/librustc_trans/back/archive.rs
@@ -21,10 +21,11 @@ use std::process::{Command, Output, Stdio};
 use std::ptr;
 use std::str;
 
+use middle::cstore::CrateStore;
+
 use libc;
 use llvm::archive_ro::{ArchiveRO, Child};
 use llvm::{self, ArchiveKind};
-use rustc::metadata::loader::METADATA_FILENAME;
 use rustc::session::Session;
 use rustc_back::tempdir::TempDir;
 
@@ -169,11 +170,13 @@ impl<'a> ArchiveBuilder<'a> {
         // Ignoring all bytecode files, no matter of
         // name
         let bc_ext = ".bytecode.deflate";
+        let metadata_filename =
+            self.config.sess.cstore.metadata_filename().to_owned();
 
         self.add_archive(rlib, &name[..], move |fname: &str| {
             let skip_obj = lto && fname.starts_with(&obj_start)
                 && fname.ends_with(".o");
-            skip_obj || fname.ends_with(bc_ext) || fname == METADATA_FILENAME
+            skip_obj || fname.ends_with(bc_ext) || fname == metadata_filename
         })
     }
 
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index e0cbdbeaef3..d7b4243afee 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -17,11 +17,11 @@ use super::svh::Svh;
 use session::config;
 use session::config::NoDebugInfo;
 use session::config::{OutputFilenames, Input, OutputType};
+use session::filesearch;
 use session::search_paths::PathKind;
 use session::Session;
-use metadata::common::LinkMeta;
-use metadata::loader::METADATA_FILENAME;
-use metadata::{encoder, cstore, filesearch, csearch, creader};
+use middle::cstore::{self, CrateStore, LinkMeta};
+use middle::cstore::{LinkagePreference, NativeLibraryKind};
 use middle::dependency_format::Linkage;
 use middle::ty::{self, Ty};
 use rustc::front::map::DefPath;
@@ -137,7 +137,7 @@ pub fn find_crate_name(sess: Option<&Session>,
                        attrs: &[ast::Attribute],
                        input: &Input) -> String {
     let validate = |s: String, span: Option<Span>| {
-        creader::validate_crate_name(sess, &s[..], span);
+        cstore::validate_crate_name(sess, &s[..], span);
         s
     };
 
@@ -216,7 +216,7 @@ fn symbol_hash<'tcx>(tcx: &ty::ctxt<'tcx>,
         symbol_hasher.input_str(&meta[..]);
     }
     symbol_hasher.input_str("-");
-    symbol_hasher.input(&encoder::encoded_ty(tcx, t));
+    symbol_hasher.input(&tcx.sess.cstore.encode_type(tcx, t));
     // Prefix with 'h' so that it never blends into adjacent digits
     let mut hash = String::from("h");
     hash.push_str(&truncated_hash_result(symbol_hasher));
@@ -504,7 +504,7 @@ pub fn filename_for_input(sess: &Session,
 
 pub fn each_linked_rlib(sess: &Session,
                         f: &mut FnMut(ast::CrateNum, &Path)) {
-    let crates = sess.cstore.get_used_crates(cstore::RequireStatic).into_iter();
+    let crates = sess.cstore.used_crates(LinkagePreference::RequireStatic).into_iter();
     let fmts = sess.dependency_formats.borrow();
     let fmts = fmts.get(&config::CrateTypeExecutable).or_else(|| {
         fmts.get(&config::CrateTypeStaticlib)
@@ -516,7 +516,7 @@ pub fn each_linked_rlib(sess: &Session,
             Linkage::NotLinked | Linkage::IncludedFromDylib => continue,
             _ => {}
         }
-        let name = sess.cstore.get_crate_data(cnum).name.clone();
+        let name = sess.cstore.crate_name(cnum).clone();
         let path = match path {
             Some(p) => p,
             None => {
@@ -621,10 +621,11 @@ fn link_rlib<'a>(sess: &'a Session,
         ab.add_file(obj);
     }
 
-    for &(ref l, kind) in sess.cstore.get_used_libraries().borrow().iter() {
+    for (l, kind) in sess.cstore.used_libraries() {
         match kind {
-            cstore::NativeStatic => ab.add_native_library(&l),
-            cstore::NativeFramework | cstore::NativeUnknown => {}
+            NativeLibraryKind::NativeStatic => ab.add_native_library(&l),
+            NativeLibraryKind::NativeFramework |
+            NativeLibraryKind::NativeUnknown => {}
         }
     }
 
@@ -666,7 +667,7 @@ fn link_rlib<'a>(sess: &'a Session,
             // contain the metadata in a separate file. We use a temp directory
             // here so concurrent builds in the same directory don't try to use
             // the same filename for metadata (stomping over one another)
-            let metadata = tmpdir.join(METADATA_FILENAME);
+            let metadata = tmpdir.join(sess.cstore.metadata_filename());
             match fs::File::create(&metadata).and_then(|mut f| {
                 f.write_all(&trans.metadata)
             }) {
@@ -805,10 +806,10 @@ fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path,
     let mut all_native_libs = vec![];
 
     each_linked_rlib(sess, &mut |cnum, path| {
-        let name = sess.cstore.get_crate_data(cnum).name();
+        let name = sess.cstore.crate_name(cnum);
         ab.add_rlib(path, &name, sess.lto()).unwrap();
 
-        let native_libs = csearch::get_native_libraries(&sess.cstore, cnum);
+        let native_libs = sess.cstore.native_libraries(cnum);
         all_native_libs.extend(native_libs);
     });
 
@@ -824,9 +825,9 @@ fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path,
 
     for &(kind, ref lib) in &all_native_libs {
         let name = match kind {
-            cstore::NativeStatic => "static library",
-            cstore::NativeUnknown => "library",
-            cstore::NativeFramework => "framework",
+            NativeLibraryKind::NativeStatic => "static library",
+            NativeLibraryKind::NativeUnknown => "library",
+            NativeLibraryKind::NativeFramework => "framework",
         };
         sess.note(&format!("{}: {}", name, *lib));
     }
@@ -968,7 +969,7 @@ fn link_args(cmd: &mut Linker,
     // sections if possible. See more comments in linker.rs
     cmd.gc_sections(dylib);
 
-    let used_link_args = sess.cstore.get_used_link_args().borrow();
+    let used_link_args = sess.cstore.used_link_args();
 
     if !dylib && t.options.position_independent_executables {
         let empty_vec = Vec::new();
@@ -1049,7 +1050,7 @@ fn link_args(cmd: &mut Linker,
             path
         };
         let mut rpath_config = RPathConfig {
-            used_crates: sess.cstore.get_used_crates(cstore::RequireDynamic),
+            used_crates: sess.cstore.used_crates(LinkagePreference::RequireDynamic),
             out_filename: out_filename.to_path_buf(),
             has_rpath: sess.target.target.options.has_rpath,
             is_like_osx: sess.target.target.options.is_like_osx,
@@ -1085,14 +1086,13 @@ fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
         }
     });
 
-    let libs = sess.cstore.get_used_libraries();
-    let libs = libs.borrow();
+    let libs = sess.cstore.used_libraries();
 
     let staticlibs = libs.iter().filter_map(|&(ref l, kind)| {
-        if kind == cstore::NativeStatic {Some(l)} else {None}
+        if kind == NativeLibraryKind::NativeStatic {Some(l)} else {None}
     });
     let others = libs.iter().filter(|&&(_, kind)| {
-        kind != cstore::NativeStatic
+        kind != NativeLibraryKind::NativeStatic
     });
 
     // Some platforms take hints about whether a library is static or dynamic.
@@ -1116,9 +1116,9 @@ fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
 
     for &(ref l, kind) in others {
         match kind {
-            cstore::NativeUnknown => cmd.link_dylib(l),
-            cstore::NativeFramework => cmd.link_framework(l),
-            cstore::NativeStatic => unreachable!(),
+            NativeLibraryKind::NativeUnknown => cmd.link_dylib(l),
+            NativeLibraryKind::NativeFramework => cmd.link_framework(l),
+            NativeLibraryKind::NativeStatic => unreachable!(),
         }
     }
 }
@@ -1147,13 +1147,13 @@ fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session,
 
     // Invoke get_used_crates to ensure that we get a topological sorting of
     // crates.
-    let deps = sess.cstore.get_used_crates(cstore::RequireDynamic);
+    let deps = sess.cstore.used_crates(LinkagePreference::RequireDynamic);
 
     for &(cnum, _) in &deps {
         // We may not pass all crates through to the linker. Some crates may
         // appear statically in an existing dylib, meaning we'll pick up all the
         // symbols from the dylib.
-        let src = sess.cstore.get_used_crate_source(cnum).unwrap();
+        let src = sess.cstore.used_crate_source(cnum);
         match data[cnum as usize - 1] {
             Linkage::NotLinked |
             Linkage::IncludedFromDylib => {}
@@ -1217,7 +1217,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session,
         time(sess.time_passes(), &format!("altering {}.rlib", name), || {
             let cfg = archive_config(sess, &dst, Some(cratepath));
             let mut archive = ArchiveBuilder::new(cfg);
-            archive.remove_file(METADATA_FILENAME);
+            archive.remove_file(sess.cstore.metadata_filename());
             archive.update_symbols();
 
             let mut any_objects = false;
@@ -1292,14 +1292,14 @@ fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session) {
     // This passes RequireStatic, but the actual requirement doesn't matter,
     // we're just getting an ordering of crate numbers, we're not worried about
     // the paths.
-    let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
+    let crates = sess.cstore.used_crates(LinkagePreference::RequireStatic);
     for (cnum, _) in crates {
-        let libs = csearch::get_native_libraries(&sess.cstore, cnum);
+        let libs = sess.cstore.native_libraries(cnum);
         for &(kind, ref lib) in &libs {
             match kind {
-                cstore::NativeUnknown => cmd.link_dylib(lib),
-                cstore::NativeFramework => cmd.link_framework(lib),
-                cstore::NativeStatic => {
+                NativeLibraryKind::NativeUnknown => cmd.link_dylib(lib),
+                NativeLibraryKind::NativeFramework => cmd.link_framework(lib),
+                NativeLibraryKind::NativeStatic => {
                     sess.bug("statics shouldn't be propagated");
                 }
             }
diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs
index 79a91e4f416..1ee1c9f1912 100644
--- a/src/librustc_trans/back/linker.rs
+++ b/src/librustc_trans/back/linker.rs
@@ -16,7 +16,7 @@ use std::path::{Path, PathBuf};
 use std::process::Command;
 
 use back::archive;
-use metadata::csearch;
+use middle::cstore::CrateStore;
 use middle::dependency_format::Linkage;
 use session::Session;
 use session::config::CrateTypeDylib;
@@ -342,9 +342,9 @@ impl<'a> Linker for MsvcLinker<'a> {
                     None
                 }
             }).flat_map(|cnum| {
-                csearch::get_reachable_ids(cstore, cnum)
+                cstore.reachable_ids(cnum)
             }).map(|did| {
-                csearch::get_symbol(cstore, did)
+                cstore.item_symbol(did)
             });
             for symbol in symbols {
                 try!(writeln!(f, "  {}", symbol));
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 58949a63ebe..b672c49bdca 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -62,10 +62,8 @@ extern crate serialize;
 #[macro_use] extern crate syntax;
 
 pub use rustc::session;
-pub use rustc::metadata;
 pub use rustc::middle;
 pub use rustc::lint;
-pub use rustc::plugin;
 pub use rustc::util;
 
 pub mod back {
diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs
index 682e203f856..2964d87ec1c 100644
--- a/src/librustc_trans/save/dump_csv.rs
+++ b/src/librustc_trans/save/dump_csv.rs
@@ -909,7 +909,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                     None => item.ident.to_string(),
                 };
                 let alias_span = self.span.span_for_last_ident(item.span);
-                let cnum = match self.sess.cstore.find_extern_mod_stmt_cnum(item.id) {
+                let cnum = match self.sess.cstore.extern_mod_stmt_cnum(item.id) {
                     Some(cnum) => cnum,
                     None => 0,
                 };
@@ -1216,4 +1216,3 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
         walk_list!(self, visit_expr, &l.init);
     }
 }
-
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index 53f2d93c3f1..cc5322d7f9f 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -199,12 +199,12 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
     pub fn get_external_crates(&self) -> Vec<CrateData> {
         let mut result = Vec::new();
 
-        self.tcx.sess.cstore.iter_crate_data(|n, cmd| {
+        for n in self.tcx.sess.cstore.crates() {
             result.push(CrateData {
-                name: cmd.name.clone(),
+                name: self.tcx.sess.cstore.crate_name(n),
                 number: n,
             });
-        });
+        }
 
         result
     }
diff --git a/src/librustc_trans/save/recorder.rs b/src/librustc_trans/save/recorder.rs
index 34eb1d28263..a95a4c052fa 100644
--- a/src/librustc_trans/save/recorder.rs
+++ b/src/librustc_trans/save/recorder.rs
@@ -13,7 +13,7 @@ pub use self::Row::*;
 use super::escape;
 use super::span_utils::SpanUtils;
 
-use metadata::cstore::LOCAL_CRATE;
+use middle::cstore::LOCAL_CRATE;
 use middle::def_id::{CRATE_DEF_INDEX, DefId};
 use middle::ty;
 
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index e291482a4aa..d6b33672df0 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -34,9 +34,8 @@ use back::{link, abi};
 use lint;
 use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
 use llvm;
-use metadata::{csearch, encoder, loader};
-use middle::astencode;
 use middle::cfg;
+use middle::cstore::CrateStore;
 use middle::def_id::DefId;
 use middle::infer;
 use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
@@ -199,7 +198,7 @@ fn get_extern_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     let f = declare::declare_rust_fn(ccx, name, fn_ty);
 
-    let attrs = csearch::get_item_attrs(&ccx.sess().cstore, did);
+    let attrs = ccx.sess().cstore.item_attrs(did);
     attributes::from_fn_attrs(ccx, &attrs[..], f);
 
     ccx.externs().borrow_mut().insert(name.to_string(), f);
@@ -230,7 +229,7 @@ pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                   did: DefId,
                                   t: Ty<'tcx>)
                                   -> ValueRef {
-    let name = csearch::get_symbol(&ccx.sess().cstore, did);
+    let name = ccx.sess().cstore.item_symbol(did);
     let ty = type_of(ccx, t);
     match ccx.externs().borrow_mut().get(&name) {
         Some(n) => return *n,
@@ -874,7 +873,7 @@ pub fn trans_external_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                      did: DefId,
                                      t: Ty<'tcx>)
                                      -> ValueRef {
-    let name = csearch::get_symbol(&ccx.sess().cstore, did);
+    let name = ccx.sess().cstore.item_symbol(did);
     match t.sty {
         ty::TyBareFn(_, ref fn_ty) => {
             match ccx.sess().target.target.adjust_abi(fn_ty.abi) {
@@ -885,7 +884,7 @@ pub fn trans_external_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                     ccx.sess().bug("unexpected intrinsic in trans_external_path")
                 }
                 _ => {
-                    let attrs = csearch::get_item_attrs(&ccx.sess().cstore, did);
+                    let attrs = ccx.sess().cstore.item_attrs(did);
                     foreign::register_foreign_item_fn(ccx, fn_ty.abi, t, &name, &attrs)
                 }
             }
@@ -2513,10 +2512,9 @@ pub fn create_entry_wrapper(ccx: &CrateContext, sp: Span, main_llfn: ValueRef) {
                                                                .as_local_node_id(start_def_id) {
                     get_item_val(ccx, start_node_id)
                 } else {
-                    let start_fn_type = csearch::get_type(ccx.tcx(), start_def_id).ty;
+                    let start_fn_type = ccx.tcx().lookup_item_type(start_def_id).ty;
                     trans_external_path(ccx, start_def_id, start_fn_type)
                 };
-
                 let args = {
                     let opaque_rust_main =
                         llvm::LLVMBuildPointerCast(bld,
@@ -2552,7 +2550,7 @@ fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                            -> String {
     match ccx.external_srcs().borrow().get(&id) {
         Some(&did) => {
-            let sym = csearch::get_symbol(&ccx.sess().cstore, did);
+            let sym = ccx.sess().cstore.item_symbol(did);
             debug!("found item {} in other crate...", sym);
             return sym;
         }
@@ -2602,7 +2600,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
             let v = match i.node {
                 hir::ItemStatic(..) => {
                     // If this static came from an external crate, then
-                    // we need to get the symbol from csearch instead of
+                    // we need to get the symbol from metadata instead of
                     // using the current crate's name/version
                     // information in the hash of the symbol
                     let sym = sym();
@@ -2757,22 +2755,6 @@ fn register_method(ccx: &CrateContext,
     }
 }
 
-pub fn crate_ctxt_to_encode_parms<'a, 'tcx>(cx: &'a SharedCrateContext<'a, 'tcx>,
-                                            ie: encoder::EncodeInlinedItem<'a>,
-                                            reachable: &'a NodeSet)
-                                            -> encoder::EncodeParams<'a, 'tcx> {
-    encoder::EncodeParams {
-        diag: cx.sess().diagnostic(),
-        tcx: cx.tcx(),
-        reexports: cx.export_map(),
-        item_symbols: cx.item_symbols(),
-        link_meta: cx.link_meta(),
-        cstore: &cx.sess().cstore,
-        encode_inlined_item: ie,
-        reachable: reachable,
-    }
-}
-
 pub fn write_metadata(cx: &SharedCrateContext, krate: &hir::Crate, reachable: &NodeSet) -> Vec<u8> {
     use flate;
 
@@ -2785,14 +2767,13 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &hir::Crate, reachable: &N
         return Vec::new();
     }
 
-    let encode_inlined_item: encoder::EncodeInlinedItem = Box::new(|ecx, rbml_w, ii| {
-        astencode::encode_inlined_item(ecx, rbml_w, ii)
-    });
-
-    let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item, reachable);
-    let metadata = encoder::encode_metadata(encode_parms, krate);
-    let mut compressed = encoder::metadata_encoding_version.to_vec();
+    let cstore = &cx.tcx().sess.cstore;
+    let metadata = cstore.encode_metadata(
+        cx.tcx(), cx.export_map(), cx.item_symbols(), cx.link_meta(), reachable,
+        krate);
+    let mut compressed = cstore.metadata_encoding_version().to_vec();
     compressed.push_all(&flate::deflate_bytes(&metadata));
+
     let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed[..]);
     let llconst = C_struct_in_context(cx.metadata_llcx(), &[llmeta], false);
     let name = format!("rust_metadata_{}_{}",
@@ -2804,7 +2785,8 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &hir::Crate, reachable: &N
     };
     unsafe {
         llvm::LLVMSetInitializer(llglobal, llconst);
-        let name = loader::meta_section_name(&cx.sess().target.target);
+        let name =
+            cx.tcx().sess.cstore.metadata_section_name(&cx.sess().target.target);
         let name = CString::new(name).unwrap();
         llvm::LLVMSetSection(llglobal, name.as_ptr())
     }
@@ -3105,15 +3087,15 @@ pub fn trans_crate<'tcx>(tcx: &ty::ctxt<'tcx>,
     // reachable extern fns. These functions are all part of the public ABI of
     // the final product, so LTO needs to preserve them.
     if sess.lto() {
-        sess.cstore.iter_crate_data(|cnum, _| {
-            let syms = csearch::get_reachable_ids(&sess.cstore, cnum);
+        for cnum in sess.cstore.crates() {
+            let syms = sess.cstore.reachable_ids(cnum);
             reachable_symbols.extend(syms.into_iter().filter(|did| {
-                csearch::is_extern_fn(&sess.cstore, *did, shared_ccx.tcx()) ||
-                csearch::is_static(&sess.cstore, *did)
+                sess.cstore.is_extern_fn(shared_ccx.tcx(), *did) ||
+                sess.cstore.is_static(*did)
             }).map(|did| {
-                csearch::get_symbol(&sess.cstore, did)
+                sess.cstore.item_symbol(did)
             }));
-        });
+        }
     }
 
     if codegen_units > 1 {
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index a52c7f94c3a..0c0bda45d8c 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -22,7 +22,7 @@ use arena::TypedArena;
 use back::link;
 use session;
 use llvm::{self, ValueRef, get_params};
-use metadata::cstore::LOCAL_CRATE;
+use middle::cstore::LOCAL_CRATE;
 use middle::def;
 use middle::def_id::DefId;
 use middle::infer;
diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs
index 91f17a50e2c..6f40283064b 100644
--- a/src/librustc_trans/trans/consts.rs
+++ b/src/librustc_trans/trans/consts.rs
@@ -13,8 +13,8 @@ use back::abi;
 use llvm;
 use llvm::{ConstFCmp, ConstICmp, SetLinkage, SetUnnamedAddr};
 use llvm::{InternalLinkage, ValueRef, Bool, True};
-use metadata::cstore::LOCAL_CRATE;
 use middle::{check_const, def};
+use middle::cstore::LOCAL_CRATE;
 use middle::const_eval::{self, ConstVal, ConstEvalErr};
 use middle::const_eval::{const_int_checked_neg, const_uint_checked_neg};
 use middle::const_eval::{const_int_checked_add, const_uint_checked_add};
diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs
index 1f1d43feeb3..c6ca2e176aa 100644
--- a/src/librustc_trans/trans/context.rs
+++ b/src/librustc_trans/trans/context.rs
@@ -10,7 +10,7 @@
 
 use llvm;
 use llvm::{ContextRef, ModuleRef, ValueRef, BuilderRef};
-use metadata::common::LinkMeta;
+use middle::cstore::LinkMeta;
 use middle::def::ExportMap;
 use middle::def_id::DefId;
 use middle::traits;
diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs
index 11b8a6a5faa..9eed014ac73 100644
--- a/src/librustc_trans/trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/trans/debuginfo/metadata.rs
@@ -343,7 +343,7 @@ impl<'tcx> TypeMap<'tcx> {
             let crate_hash = if source_def_id.is_local() {
                 cx.link_meta().crate_hash.clone()
             } else {
-                cx.sess().cstore.get_crate_hash(source_def_id.krate)
+                cx.sess().cstore.crate_hash(source_def_id.krate)
             };
 
             output.push_str(crate_hash.as_str());
diff --git a/src/librustc_trans/trans/inline.rs b/src/librustc_trans/trans/inline.rs
index 0e837d83686..29965755eac 100644
--- a/src/librustc_trans/trans/inline.rs
+++ b/src/librustc_trans/trans/inline.rs
@@ -9,9 +9,7 @@
 // except according to those terms.
 
 use llvm::{AvailableExternallyLinkage, InternalLinkage, SetLinkage};
-use metadata::csearch;
-use metadata::inline::InlinedItem;
-use middle::astencode;
+use middle::cstore::{CrateStore, FoundAst, InlinedItem};
 use middle::def_id::DefId;
 use middle::subst::Substs;
 use trans::base::{push_ctxt, trans_item, get_item_val, trans_fn};
@@ -19,7 +17,6 @@ use trans::common::*;
 
 use rustc_front::hir;
 
-
 fn instantiate_inline(ccx: &CrateContext, fn_id: DefId)
     -> Option<DefId> {
     debug!("instantiate_inline({:?})", fn_id);
@@ -41,17 +38,13 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId)
         }
     }
 
-    let csearch_result =
-        csearch::maybe_get_item_ast(
-            ccx.tcx(), fn_id,
-            Box::new(astencode::decode_inlined_item));
-
-    let inline_id = match csearch_result {
-        csearch::FoundAst::NotFound => {
+    let inlined = ccx.tcx().sess.cstore.maybe_get_item_ast(ccx.tcx(), fn_id);
+    let inline_id = match inlined {
+        FoundAst::NotFound => {
             ccx.external().borrow_mut().insert(fn_id, None);
             return None;
         }
-        csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => {
+        FoundAst::Found(&InlinedItem::Item(ref item)) => {
             ccx.external().borrow_mut().insert(fn_id, Some(item.id));
             ccx.external_srcs().borrow_mut().insert(item.id, fn_id);
 
@@ -94,12 +87,12 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId)
 
             item.id
         }
-        csearch::FoundAst::Found(&InlinedItem::Foreign(ref item)) => {
+        FoundAst::Found(&InlinedItem::Foreign(ref item)) => {
             ccx.external().borrow_mut().insert(fn_id, Some(item.id));
             ccx.external_srcs().borrow_mut().insert(item.id, fn_id);
             item.id
         }
-        csearch::FoundAst::FoundParent(parent_id, &InlinedItem::Item(ref item)) => {
+        FoundAst::FoundParent(parent_id, &InlinedItem::Item(ref item)) => {
             ccx.external().borrow_mut().insert(parent_id, Some(item.id));
             ccx.external_srcs().borrow_mut().insert(item.id, parent_id);
 
@@ -129,11 +122,11 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId)
             trans_item(ccx, &**item);
             my_id
         }
-        csearch::FoundAst::FoundParent(_, _) => {
+        FoundAst::FoundParent(_, _) => {
             ccx.sess().bug("maybe_get_item_ast returned a FoundParent \
                             with a non-item parent");
         }
-        csearch::FoundAst::Found(&InlinedItem::TraitItem(_, ref trait_item)) => {
+        FoundAst::Found(&InlinedItem::TraitItem(_, ref trait_item)) => {
             ccx.external().borrow_mut().insert(fn_id, Some(trait_item.id));
             ccx.external_srcs().borrow_mut().insert(trait_item.id, fn_id);
 
@@ -153,7 +146,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId)
             // don't.
             trait_item.id
         }
-        csearch::FoundAst::Found(&InlinedItem::ImplItem(impl_did, ref impl_item)) => {
+        FoundAst::Found(&InlinedItem::ImplItem(impl_did, ref impl_item)) => {
             ccx.external().borrow_mut().insert(fn_id, Some(impl_item.id));
             ccx.external_srcs().borrow_mut().insert(impl_item.id, fn_id);
 
diff --git a/src/librustc_trans/trans/mod.rs b/src/librustc_trans/trans/mod.rs
index fa37b005539..b102e96af20 100644
--- a/src/librustc_trans/trans/mod.rs
+++ b/src/librustc_trans/trans/mod.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use llvm::{ContextRef, ModuleRef};
-use metadata::common::LinkMeta;
+use middle::cstore::LinkMeta;
 
 pub use self::base::trans_crate;
 pub use self::context::CrateContext;
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 988d5537e5d..6a23be682e9 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -25,7 +25,7 @@ use super::UnresolvedTypeAction;
 use super::write_call;
 
 use CrateCtxt;
-use metadata::cstore::LOCAL_CRATE;
+use middle::cstore::LOCAL_CRATE;
 use middle::def_id::DefId;
 use middle::infer;
 use middle::ty::{self, LvaluePreference, Ty};
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 69770cd33b3..955bc92a8f3 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -17,12 +17,12 @@ use astconv::AstConv;
 use check::{self, FnCtxt};
 use front::map as hir_map;
 use middle::ty::{self, Ty, ToPolyTraitRef, ToPredicate, HasTypeFlags};
+use middle::cstore::{self, CrateStore, DefLike};
 use middle::def;
 use middle::def_id::DefId;
 use middle::lang_items::FnOnceTraitLangItem;
 use middle::subst::Substs;
 use middle::traits::{Obligation, SelectionContext};
-use metadata::{csearch, cstore, decoder};
 use util::nodemap::{FnvHashSet};
 
 use syntax::ast;
@@ -418,32 +418,32 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> {
         fn handle_external_def(traits: &mut AllTraitsVec,
                                external_mods: &mut FnvHashSet<DefId>,
                                ccx: &CrateCtxt,
-                               cstore: &cstore::CStore,
-                               dl: decoder::DefLike) {
+                               cstore: &for<'a> cstore::CrateStore<'a>,
+                               dl: cstore::DefLike) {
             match dl {
-                decoder::DlDef(def::DefTrait(did)) => {
+                cstore::DlDef(def::DefTrait(did)) => {
                     traits.push(TraitInfo::new(did));
                 }
-                decoder::DlDef(def::DefMod(did)) => {
+                cstore::DlDef(def::DefMod(did)) => {
                     if !external_mods.insert(did) {
                         return;
                     }
-                    csearch::each_child_of_item(cstore, did, |dl, _, _| {
+                    for child in cstore.item_children(did) {
                         handle_external_def(traits, external_mods,
-                                            ccx, cstore, dl)
-                    })
+                                            ccx, cstore, child.def)
+                    }
                 }
                 _ => {}
             }
         }
-        let cstore = &ccx.tcx.sess.cstore;
-        cstore.iter_crate_data(|cnum, _| {
-            csearch::each_top_level_item_of_crate(cstore, cnum, |dl, _, _| {
-                handle_external_def(&mut traits,
-                                    &mut external_mods,
-                                    ccx, cstore, dl)
-            })
-        });
+        let cstore = &*ccx.tcx.sess.cstore;
+
+        for cnum in ccx.tcx.sess.cstore.crates() {
+            for child in cstore.crate_top_level_items(cnum) {
+                handle_external_def(&mut traits, &mut external_mods,
+                                    ccx, cstore, child.def)
+            }
+        }
 
         *ccx.all_traits.borrow_mut() = Some(traits);
     }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index c375eb19a37..be60d2f3dcf 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -83,8 +83,8 @@ use self::TupleArgumentsFlag::*;
 use astconv::{self, ast_region_to_region, ast_ty_to_ty, AstConv, PathParamMode};
 use check::_match::pat_ctxt;
 use fmt_macros::{Parser, Piece, Position};
-use metadata::cstore::LOCAL_CRATE;
 use middle::astconv_util::prohibit_type_params;
+use middle::cstore::LOCAL_CRATE;
 use middle::def;
 use middle::def_id::DefId;
 use middle::infer;
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index 8eeafb9b432..e6e31ba0819 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -11,7 +11,7 @@
 //! Orphan checker: every impl either implements a trait defined in this
 //! crate or pertains to a type defined in this crate.
 
-use metadata::cstore::LOCAL_CRATE;
+use middle::cstore::LOCAL_CRATE;
 use middle::def_id::DefId;
 use middle::traits;
 use middle::ty;
diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs
index e91702e64ba..693c8716ab5 100644
--- a/src/librustc_typeck/coherence/overlap.rs
+++ b/src/librustc_typeck/coherence/overlap.rs
@@ -11,7 +11,7 @@
 //! Overlap: No two impls for the same trait are implemented for the
 //! same type.
 
-use metadata::cstore::LOCAL_CRATE;
+use middle::cstore::{CrateStore, LOCAL_CRATE};
 use middle::def_id::DefId;
 use middle::traits;
 use middle::ty;
@@ -156,9 +156,8 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
             span_note!(self.tcx.sess, self.span_of_impl(impl2),
                        "note conflicting implementation here");
         } else {
-            let crate_store = &self.tcx.sess.cstore;
-            let cdata = crate_store.get_crate_data(impl2.krate);
-            self.tcx.sess.note(&format!("conflicting implementation in crate `{}`", cdata.name));
+            let cname = self.tcx.sess.cstore.crate_name(impl2.krate);
+            self.tcx.sess.note(&format!("conflicting implementation in crate `{}`", cname));
         }
     }
 
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 3d28a912179..4c09df41895 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -99,7 +99,6 @@ extern crate rustc_back;
 
 pub use rustc::front;
 pub use rustc::lint;
-pub use rustc::metadata;
 pub use rustc::middle;
 pub use rustc::session;
 pub use rustc::util;
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index d6343abfd15..40cd5e5bf27 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -16,8 +16,7 @@ use syntax::ast;
 use syntax::attr::AttrMetaMethods;
 use rustc_front::hir;
 
-use rustc::metadata::csearch;
-use rustc::metadata::decoder;
+use rustc::middle::cstore::{self, CrateStore};
 use rustc::middle::def;
 use rustc::middle::def_id::DefId;
 use rustc::middle::ty;
@@ -129,8 +128,7 @@ fn try_inline_def(cx: &DocContext, tcx: &ty::ctxt,
 
 pub fn load_attrs(cx: &DocContext, tcx: &ty::ctxt,
                   did: DefId) -> Vec<clean::Attribute> {
-    let attrs = csearch::get_item_attrs(&tcx.sess.cstore, did);
-    attrs.into_iter().map(|a| a.clean(cx)).collect()
+    tcx.get_attrs(did).iter().map(|a| a.clean(cx)).collect()
 }
 
 /// Record an external fully qualified name in the external_paths cache.
@@ -140,7 +138,7 @@ pub fn load_attrs(cx: &DocContext, tcx: &ty::ctxt,
 pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) {
     match cx.tcx_opt() {
         Some(tcx) => {
-            let fqn = csearch::get_item_path(tcx, did);
+            let fqn = tcx.sess.cstore.item_path(did);
             let fqn = fqn.into_iter().map(|i| i.to_string()).collect();
             cx.external_paths.borrow_mut().as_mut().unwrap().insert(did, (fqn, kind));
         }
@@ -171,7 +169,7 @@ fn build_external_function(cx: &DocContext, tcx: &ty::ctxt, did: DefId) -> clean
         _ => panic!("bad function"),
     };
 
-    let constness = if csearch::is_const_fn(&tcx.sess.cstore, did) {
+    let constness = if tcx.sess.cstore.is_const_fn(did) {
         hir::Constness::Const
     } else {
         hir::Constness::NotConst
@@ -211,7 +209,7 @@ fn build_type(cx: &DocContext, tcx: &ty::ctxt, did: DefId) -> clean::ItemEnum {
     let t = tcx.lookup_item_type(did);
     let predicates = tcx.lookup_predicates(did);
     match t.ty.sty {
-        ty::TyEnum(edef, _) if !csearch::is_typedef(&tcx.sess.cstore, did) => {
+        ty::TyEnum(edef, _) if !tcx.sess.cstore.is_typedef(did) => {
             return clean::EnumItem(clean::Enum {
                 generics: (&t.generics, &predicates, subst::TypeSpace).clean(cx),
                 variants_stripped: false,
@@ -250,23 +248,19 @@ pub fn build_impls(cx: &DocContext, tcx: &ty::ctxt,
     // type being inlined, but impls can also be used when generating
     // documentation for primitives (no way to find those specifically).
     if cx.populated_crate_impls.borrow_mut().insert(did.krate) {
-        csearch::each_top_level_item_of_crate(&tcx.sess.cstore,
-                                              did.krate,
-                                              |def, _, _| {
-            populate_impls(cx, tcx, def, &mut impls)
-        });
+        for item in tcx.sess.cstore.crate_top_level_items(did.krate) {
+            populate_impls(cx, tcx, item.def, &mut impls);
+        }
 
         fn populate_impls(cx: &DocContext, tcx: &ty::ctxt,
-                          def: decoder::DefLike,
+                          def: cstore::DefLike,
                           impls: &mut Vec<clean::Item>) {
             match def {
-                decoder::DlImpl(did) => build_impl(cx, tcx, did, impls),
-                decoder::DlDef(def::DefMod(did)) => {
-                    csearch::each_child_of_item(&tcx.sess.cstore,
-                                                did,
-                                                |def, _, _| {
-                        populate_impls(cx, tcx, def, impls)
-                    })
+                cstore::DlImpl(did) => build_impl(cx, tcx, did, impls),
+                cstore::DlDef(def::DefMod(did)) => {
+                    for item in tcx.sess.cstore.item_children(did) {
+                        populate_impls(cx, tcx, item.def, impls)
+                    }
                 }
                 _ => {}
             }
@@ -285,7 +279,7 @@ pub fn build_impl(cx: &DocContext,
     }
 
     let attrs = load_attrs(cx, tcx, did);
-    let associated_trait = csearch::get_impl_trait(tcx, did);
+    let associated_trait = tcx.impl_trait_ref(did);
     if let Some(ref t) = associated_trait {
         // If this is an impl for a #[doc(hidden)] trait, be sure to not inline
         let trait_attrs = load_attrs(cx, tcx, t.def_id);
@@ -295,7 +289,7 @@ pub fn build_impl(cx: &DocContext,
     }
 
     // If this is a defaulted impl, then bail out early here
-    if csearch::is_default_impl(&tcx.sess.cstore, did) {
+    if tcx.sess.cstore.is_default_impl(did) {
         return ret.push(clean::Item {
             inner: clean::DefaultImplItem(clean::DefaultImpl {
                 // FIXME: this should be decoded
@@ -315,7 +309,7 @@ pub fn build_impl(cx: &DocContext,
     }
 
     let predicates = tcx.lookup_predicates(did);
-    let trait_items = csearch::get_impl_items(&tcx.sess.cstore, did)
+    let trait_items = tcx.sess.cstore.impl_items(did)
             .iter()
             .filter_map(|did| {
         let did = did.def_id();
@@ -352,7 +346,7 @@ pub fn build_impl(cx: &DocContext,
                     clean::TyMethodItem(clean::TyMethod {
                         unsafety, decl, self_, generics, abi
                     }) => {
-                        let constness = if csearch::is_const_fn(&tcx.sess.cstore, did) {
+                        let constness = if tcx.sess.cstore.is_const_fn(did) {
                             hir::Constness::Const
                         } else {
                             hir::Constness::NotConst
@@ -393,7 +387,7 @@ pub fn build_impl(cx: &DocContext,
             }
         }
     }).collect::<Vec<_>>();
-    let polarity = csearch::get_impl_polarity(tcx, did);
+    let polarity = tcx.trait_impl_polarity(did);
     let ty = tcx.lookup_item_type(did);
     let trait_ = associated_trait.clean(cx).map(|bound| {
         match bound {
@@ -454,24 +448,24 @@ fn build_module(cx: &DocContext, tcx: &ty::ctxt,
         // two namespaces, so the target may be listed twice. Make sure we only
         // visit each node at most once.
         let mut visited = HashSet::new();
-        csearch::each_child_of_item(&tcx.sess.cstore, did, |def, _, vis| {
-            match def {
-                decoder::DlDef(def::DefForeignMod(did)) => {
+        for item in tcx.sess.cstore.item_children(did) {
+            match item.def {
+                cstore::DlDef(def::DefForeignMod(did)) => {
                     fill_in(cx, tcx, did, items);
                 }
-                decoder::DlDef(def) if vis == hir::Public => {
+                cstore::DlDef(def) if item.vis == hir::Public => {
                     if !visited.insert(def) { return }
                     match try_inline_def(cx, tcx, def) {
                         Some(i) => items.extend(i),
                         None => {}
                     }
                 }
-                decoder::DlDef(..) => {}
+                cstore::DlDef(..) => {}
                 // All impls were inlined above
-                decoder::DlImpl(..) => {}
-                decoder::DlField => panic!("unimplemented field"),
+                cstore::DlImpl(..) => {}
+                cstore::DlField => panic!("unimplemented field"),
             }
-        });
+        }
     }
 }
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index c88b2dcdb74..a1b3d88f083 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -35,9 +35,7 @@ use syntax::parse::token::{self, InternedString, special_idents};
 use syntax::ptr::P;
 
 use rustc_trans::back::link;
-use rustc::metadata::cstore;
-use rustc::metadata::csearch;
-use rustc::metadata::decoder;
+use rustc::middle::cstore::{self, CrateStore};
 use rustc::middle::def;
 use rustc::middle::def_id::{DefId, DefIndex};
 use rustc::middle::subst::{self, ParamSpace, VecPerParamSpace};
@@ -126,6 +124,8 @@ pub struct Crate {
     pub external_traits: HashMap<DefId, Trait>,
 }
 
+struct CrateNum(ast::CrateNum);
+
 impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
     fn clean(&self, cx: &DocContext) -> Crate {
         use rustc::session::config::Input;
@@ -135,9 +135,9 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
         }
 
         let mut externs = Vec::new();
-        cx.sess().cstore.iter_crate_data(|n, meta| {
-            externs.push((n, meta.clean(cx)));
-        });
+        for cnum in cx.sess().cstore.crates() {
+            externs.push((cnum, CrateNum(cnum).clean(cx)));
+        }
         externs.sort_by(|&(a, _), &(b, _)| a.cmp(&b));
 
         // Figure out the name of this crate
@@ -219,24 +219,22 @@ pub struct ExternalCrate {
     pub primitives: Vec<PrimitiveType>,
 }
 
-impl Clean<ExternalCrate> for cstore::crate_metadata {
+impl Clean<ExternalCrate> for CrateNum {
     fn clean(&self, cx: &DocContext) -> ExternalCrate {
         let mut primitives = Vec::new();
         cx.tcx_opt().map(|tcx| {
-            csearch::each_top_level_item_of_crate(&tcx.sess.cstore,
-                                                  self.cnum,
-                                                  |def, _, _| {
-                let did = match def {
-                    decoder::DlDef(def::DefMod(did)) => did,
-                    _ => return
+            for item in tcx.sess.cstore.crate_top_level_items(self.0) {
+                let did = match item.def {
+                    cstore::DlDef(def::DefMod(did)) => did,
+                    _ => continue
                 };
                 let attrs = inline::load_attrs(cx, tcx, did);
                 PrimitiveType::find(&attrs).map(|prim| primitives.push(prim));
-            })
+            }
         });
         ExternalCrate {
-            name: self.name.to_string(),
-            attrs: decoder::get_crate_attributes(self.data()).clean(cx),
+            name: cx.sess().cstore.crate_name(self.0),
+            attrs: cx.sess().cstore.crate_attrs(self.0).clean(cx),
             primitives: primitives,
         }
     }
@@ -656,7 +654,7 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
                 (tcx.lang_items.sync_trait().unwrap(),
                  external_path(cx, "Sync", None, vec![], &empty)),
         };
-        let fqn = csearch::get_item_path(tcx, did);
+        let fqn = tcx.sess.cstore.item_path(did);
         let fqn = fqn.into_iter().map(|i| i.to_string()).collect();
         cx.external_paths.borrow_mut().as_mut().unwrap().insert(did,
                                                                 (fqn, TypeTrait));
@@ -678,7 +676,7 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
             Some(tcx) => tcx,
             None => return RegionBound(Lifetime::statik())
         };
-        let fqn = csearch::get_item_path(tcx, self.def_id);
+        let fqn = tcx.sess.cstore.item_path(self.def_id);
         let fqn = fqn.into_iter().map(|i| i.to_string())
                      .collect::<Vec<String>>();
         let path = external_path(cx, fqn.last().unwrap(),
@@ -1140,7 +1138,7 @@ impl<'a, 'tcx> Clean<FnDecl> for (DefId, &'a ty::PolyFnSig<'tcx>) {
         let mut names = if let Some(_) = cx.map.as_local_node_id(did) {
             vec![].into_iter()
         } else {
-            csearch::get_method_arg_names(&cx.tcx().sess.cstore, did).into_iter()
+            cx.tcx().sess.cstore.method_arg_names(did).into_iter()
         }.peekable();
         if names.peek().map(|s| &**s) == Some("self") {
             let _ = names.next();
@@ -1665,7 +1663,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
             ty::TyStruct(def, substs) |
             ty::TyEnum(def, substs) => {
                 let did = def.did;
-                let fqn = csearch::get_item_path(cx.tcx(), did);
+                let fqn = cx.tcx().sess.cstore.item_path(did);
                 let fqn: Vec<_> = fqn.into_iter().map(|i| i.to_string()).collect();
                 let kind = match self.sty {
                     ty::TyStruct(..) => TypeStruct,
@@ -1683,7 +1681,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
             }
             ty::TyTrait(box ty::TraitTy { ref principal, ref bounds }) => {
                 let did = principal.def_id();
-                let fqn = csearch::get_item_path(cx.tcx(), did);
+                let fqn = cx.tcx().sess.cstore.item_path(did);
                 let fqn: Vec<_> = fqn.into_iter().map(|i| i.to_string()).collect();
                 let (typarams, bindings) = bounds.clean(cx);
                 let path = external_path(cx, &fqn.last().unwrap().to_string(),
@@ -1737,9 +1735,9 @@ impl Clean<Item> for hir::StructField {
 impl<'tcx> Clean<Item> for ty::FieldDefData<'tcx, 'static> {
     fn clean(&self, cx: &DocContext) -> Item {
         use syntax::parse::token::special_idents::unnamed_field;
-        use rustc::metadata::csearch;
-
-        let attr_map = csearch::get_struct_field_attrs(&cx.tcx().sess.cstore, self.did);
+        // FIXME: possible O(n^2)-ness! Not my fault.
+        let attr_map =
+            cx.tcx().sess.cstore.crate_struct_field_attrs(self.did.krate);
 
         let (name, attrs) = if self.name == unnamed_field.name {
             (None, None)
@@ -2815,7 +2813,7 @@ fn lang_struct(cx: &DocContext, did: Option<DefId>,
         Some(did) => did,
         None => return fallback(box t.clean(cx)),
     };
-    let fqn = csearch::get_item_path(cx.tcx(), did);
+    let fqn = cx.tcx().sess.cstore.item_path(did);
     let fqn: Vec<String> = fqn.into_iter().map(|i| {
         i.to_string()
     }).collect();
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index f20f5dbbc4e..1ccab1b16eb 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -20,12 +20,15 @@ use rustc::lint;
 use rustc_trans::back::link;
 use rustc_resolve as resolve;
 use rustc_front::lowering::{lower_crate, LoweringContext};
+use rustc_metadata::cstore::CStore;
 
 use syntax::{ast, codemap, diagnostic};
 use syntax::feature_gate::UnstableFeatures;
+use syntax::parse::token;
 
 use std::cell::{RefCell, Cell};
 use std::collections::{HashMap, HashSet};
+use std::rc::Rc;
 
 use visit_ast::RustdocVisitor;
 use clean;
@@ -118,8 +121,10 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
     let span_diagnostic_handler =
         diagnostic::SpanHandler::new(diagnostic_handler, codemap);
 
+    let cstore = Rc::new(CStore::new(token::get_ident_interner()));
+    let cstore_ = ::rustc_driver::cstore_to_cratestore(cstore.clone());
     let sess = session::build_session_(sessopts, cpath,
-                                       span_diagnostic_handler);
+                                       span_diagnostic_handler, cstore_);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
 
     let mut cfg = config::build_configuration(&sess);
@@ -130,7 +135,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
     let name = link::find_crate_name(Some(&sess), &krate.attrs,
                                      &input);
 
-    let krate = driver::phase_2_configure_and_expand(&sess, krate, &name, None)
+    let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, &name, None)
                     .expect("phase_2_configure_and_expand aborted in rustdoc!");
 
     let krate = driver::assign_node_ids(&sess, krate);
@@ -141,6 +146,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
     let hir_map = driver::make_map(&sess, &mut hir_forest);
 
     driver::phase_3_run_analysis_passes(&sess,
+                                        &cstore,
                                         hir_map,
                                         &arenas,
                                         &name,
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 79585a94cd0..1a4085e30e8 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -18,7 +18,7 @@
 use std::fmt;
 use std::iter::repeat;
 
-use rustc::metadata::cstore::LOCAL_CRATE;
+use rustc::middle::cstore::LOCAL_CRATE;
 use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
 use syntax::abi::Abi;
 use rustc_front::hir;
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 1b98f5bae0c..574b9b599f5 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -54,7 +54,7 @@ use externalfiles::ExternalHtml;
 
 use serialize::json::{self, ToJson};
 use syntax::{abi, ast};
-use rustc::metadata::cstore::LOCAL_CRATE;
+use rustc::middle::cstore::LOCAL_CRATE;
 use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
 use rustc::middle::privacy::AccessLevels;
 use rustc::middle::stability;
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 9afe573936d..6997fa45cec 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -43,6 +43,7 @@ extern crate rustc_resolve;
 extern crate rustc_lint;
 extern crate rustc_back;
 extern crate rustc_front;
+extern crate rustc_metadata;
 extern crate serialize;
 extern crate syntax;
 extern crate test as testing;
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 1ea30a8763e..3e303b29d5c 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -19,6 +19,7 @@ use std::io::prelude::*;
 use std::io;
 use std::path::PathBuf;
 use std::process::Command;
+use std::rc::Rc;
 use std::str;
 use std::sync::{Arc, Mutex};
 
@@ -31,8 +32,10 @@ use rustc::session::search_paths::{SearchPaths, PathKind};
 use rustc_front::lowering::{lower_crate, LoweringContext};
 use rustc_back::tempdir::TempDir;
 use rustc_driver::{driver, Compilation};
+use rustc_metadata::cstore::CStore;
 use syntax::codemap::CodeMap;
 use syntax::diagnostic;
+use syntax::parse::token;
 
 use core;
 use clean;
@@ -73,15 +76,18 @@ pub fn run(input: &str,
     let span_diagnostic_handler =
     diagnostic::SpanHandler::new(diagnostic_handler, codemap);
 
+    let cstore = Rc::new(CStore::new(token::get_ident_interner()));
+    let cstore_ = ::rustc_driver::cstore_to_cratestore(cstore.clone());
     let sess = session::build_session_(sessopts,
-                                      Some(input_path.clone()),
-                                      span_diagnostic_handler);
+                                       Some(input_path.clone()),
+                                       span_diagnostic_handler,
+                                       cstore_);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
 
     let mut cfg = config::build_configuration(&sess);
     cfg.extend(config::parse_cfgspecs(cfgs));
     let krate = driver::phase_1_parse_input(&sess, cfg, &input);
-    let krate = driver::phase_2_configure_and_expand(&sess, krate,
+    let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate,
                                                      "rustdoc-test", None)
         .expect("phase_2_configure_and_expand aborted in rustdoc!");
     let krate = driver::assign_node_ids(&sess, krate);
@@ -223,9 +229,12 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
     let span_diagnostic_handler =
         diagnostic::SpanHandler::new(diagnostic_handler, codemap);
 
+    let cstore = Rc::new(CStore::new(token::get_ident_interner()));
+    let cstore_ = ::rustc_driver::cstore_to_cratestore(cstore.clone());
     let sess = session::build_session_(sessopts,
                                        None,
-                                       span_diagnostic_handler);
+                                       span_diagnostic_handler,
+                                       cstore_);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
 
     let outdir = TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir");
@@ -236,7 +245,7 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
     if no_run {
         control.after_analysis.stop = Compilation::Stop;
     }
-    driver::compile_input(sess, cfg, &input, &out, &None, None, control);
+    driver::compile_input(sess, &cstore, cfg, &input, &out, &None, None, control);
 
     if no_run { return }
 
diff --git a/src/test/auxiliary/attr_plugin_test.rs b/src/test/auxiliary/attr_plugin_test.rs
index a6cae743ceb..bab3721a313 100644
--- a/src/test/auxiliary/attr_plugin_test.rs
+++ b/src/test/auxiliary/attr_plugin_test.rs
@@ -16,9 +16,10 @@
 extern crate syntax;
 
 extern crate rustc;
+extern crate rustc_plugin;
 
 use syntax::feature_gate::AttributeType;
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 
 
diff --git a/src/test/auxiliary/custom_derive_plugin.rs b/src/test/auxiliary/custom_derive_plugin.rs
index 44ab4cc89a0..542b10fd1c6 100644
--- a/src/test/auxiliary/custom_derive_plugin.rs
+++ b/src/test/auxiliary/custom_derive_plugin.rs
@@ -16,6 +16,7 @@
 
 extern crate syntax;
 extern crate rustc;
+extern crate rustc_plugin;
 
 use syntax::ast;
 use syntax::codemap::Span;
@@ -25,7 +26,7 @@ use syntax::ext::deriving::generic::{cs_fold, TraitDef, MethodDef, combine_subst
 use syntax::ext::deriving::generic::ty::{Literal, LifetimeBounds, Path, borrowed_explicit_self};
 use syntax::parse::token;
 use syntax::ptr::P;
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
diff --git a/src/test/auxiliary/custom_derive_plugin_attr.rs b/src/test/auxiliary/custom_derive_plugin_attr.rs
index 82d0edfb163..f44e77d563a 100644
--- a/src/test/auxiliary/custom_derive_plugin_attr.rs
+++ b/src/test/auxiliary/custom_derive_plugin_attr.rs
@@ -16,6 +16,7 @@
 
 extern crate syntax;
 extern crate rustc;
+extern crate rustc_plugin;
 
 use syntax::ast;
 use syntax::attr::AttrMetaMethods;
@@ -27,7 +28,7 @@ use syntax::ext::deriving::generic::{Substructure, Struct, EnumMatching};
 use syntax::ext::deriving::generic::ty::{Literal, LifetimeBounds, Path, borrowed_explicit_self};
 use syntax::parse::token;
 use syntax::ptr::P;
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
diff --git a/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs b/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs
index 7be5c3cf47c..25a75c2d295 100644
--- a/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs
+++ b/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs
@@ -15,12 +15,13 @@
 
 extern crate syntax;
 extern crate rustc;
+extern crate rustc_plugin;
 
 use syntax::ast;
 use syntax::codemap;
 use syntax::ext::base::{ExtCtxt, MacResult, MacEager};
 use syntax::util::small_vector::SmallVector;
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
diff --git a/src/test/auxiliary/lint_for_crate.rs b/src/test/auxiliary/lint_for_crate.rs
index 7ae161a86a3..1933188ccbf 100644
--- a/src/test/auxiliary/lint_for_crate.rs
+++ b/src/test/auxiliary/lint_for_crate.rs
@@ -15,10 +15,11 @@
 
 #[macro_use] extern crate rustc;
 extern crate rustc_front;
+extern crate rustc_plugin;
 extern crate syntax;
 
 use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray};
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 use rustc_front::hir;
 use syntax::attr;
 
diff --git a/src/test/auxiliary/lint_group_plugin_test.rs b/src/test/auxiliary/lint_group_plugin_test.rs
index 81bd76211c3..98ed86bb390 100644
--- a/src/test/auxiliary/lint_group_plugin_test.rs
+++ b/src/test/auxiliary/lint_group_plugin_test.rs
@@ -18,10 +18,11 @@ extern crate rustc_front;
 // Load rustc as a plugin to get macros
 #[macro_use]
 extern crate rustc;
+extern crate rustc_plugin;
 
 use rustc_front::hir;
 use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray};
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
 
diff --git a/src/test/auxiliary/lint_plugin_test.rs b/src/test/auxiliary/lint_plugin_test.rs
index a0036745d90..8ea131da338 100644
--- a/src/test/auxiliary/lint_plugin_test.rs
+++ b/src/test/auxiliary/lint_plugin_test.rs
@@ -18,10 +18,11 @@ extern crate syntax;
 // Load rustc as a plugin to get macros
 #[macro_use]
 extern crate rustc;
+extern crate rustc_plugin;
 
 use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass,
                   EarlyLintPassObject, LintArray};
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 use syntax::ast;
 declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
 
diff --git a/src/test/auxiliary/llvm_pass_plugin.rs b/src/test/auxiliary/llvm_pass_plugin.rs
index bacc1acd3c4..59cfdd1e04a 100644
--- a/src/test/auxiliary/llvm_pass_plugin.rs
+++ b/src/test/auxiliary/llvm_pass_plugin.rs
@@ -14,8 +14,9 @@
 #![feature(rustc_private)]
 
 extern crate rustc;
+extern crate rustc_plugin;
 
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
diff --git a/src/test/auxiliary/lto-syntax-extension-plugin.rs b/src/test/auxiliary/lto-syntax-extension-plugin.rs
index c3778326a4d..9cf0d756f40 100644
--- a/src/test/auxiliary/lto-syntax-extension-plugin.rs
+++ b/src/test/auxiliary/lto-syntax-extension-plugin.rs
@@ -14,8 +14,9 @@
 #![feature(rustc_private)]
 
 extern crate rustc;
+extern crate rustc_plugin;
 
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 #[plugin_registrar]
 pub fn plugin_registrar(_reg: &mut Registry) {}
diff --git a/src/test/auxiliary/macro_crate_MacroRulesTT.rs b/src/test/auxiliary/macro_crate_MacroRulesTT.rs
index 03cd70d9494..9e693fcc564 100644
--- a/src/test/auxiliary/macro_crate_MacroRulesTT.rs
+++ b/src/test/auxiliary/macro_crate_MacroRulesTT.rs
@@ -14,10 +14,11 @@
 
 extern crate syntax;
 extern crate rustc;
+extern crate rustc_plugin;
 
 use syntax::parse::token;
 use syntax::ext::base::MacroRulesTT;
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
diff --git a/src/test/auxiliary/macro_crate_test.rs b/src/test/auxiliary/macro_crate_test.rs
index 7ce80a5647c..fe61c80b4c3 100644
--- a/src/test/auxiliary/macro_crate_test.rs
+++ b/src/test/auxiliary/macro_crate_test.rs
@@ -14,13 +14,14 @@
 
 extern crate syntax;
 extern crate rustc;
+extern crate rustc_plugin;
 
 use syntax::ast::{self, TokenTree, Item, MetaItem, ImplItem, TraitItem};
 use syntax::codemap::Span;
 use syntax::ext::base::*;
 use syntax::parse::{self, token};
 use syntax::ptr::P;
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 #[macro_export]
 macro_rules! exported_macro { () => (2) }
diff --git a/src/test/auxiliary/plugin_args.rs b/src/test/auxiliary/plugin_args.rs
index 1920185d4e5..f6e80266a15 100644
--- a/src/test/auxiliary/plugin_args.rs
+++ b/src/test/auxiliary/plugin_args.rs
@@ -15,6 +15,7 @@
 
 extern crate syntax;
 extern crate rustc;
+extern crate rustc_plugin;
 
 use std::borrow::ToOwned;
 use syntax::ast;
@@ -24,7 +25,7 @@ use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacEager, NormalTT}
 use syntax::parse::token;
 use syntax::print::pprust;
 use syntax::ptr::P;
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 struct Expander {
     args: Vec<P<ast::MetaItem>>,
diff --git a/src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs b/src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs
index 5d93c131cad..f56983c14b1 100644
--- a/src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs
+++ b/src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs
@@ -14,10 +14,11 @@
 #![feature(box_syntax, rustc_private)]
 
 extern crate rustc;
+extern crate rustc_plugin;
 
 use std::any::Any;
 use std::cell::RefCell;
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 struct Foo {
     foo: isize
diff --git a/src/test/auxiliary/plugin_with_plugin_lib.rs b/src/test/auxiliary/plugin_with_plugin_lib.rs
index 75f404c96cd..8b5ff7cf07c 100644
--- a/src/test/auxiliary/plugin_with_plugin_lib.rs
+++ b/src/test/auxiliary/plugin_with_plugin_lib.rs
@@ -15,8 +15,9 @@
 
 extern crate macro_crate_test;
 extern crate rustc;
+extern crate rustc_plugin;
 
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 #[plugin_registrar]
 pub fn plugin_registrar(_: &mut Registry) { }
diff --git a/src/test/auxiliary/procedural_mbe_matching.rs b/src/test/auxiliary/procedural_mbe_matching.rs
index a92361b8106..713a7d1e811 100644
--- a/src/test/auxiliary/procedural_mbe_matching.rs
+++ b/src/test/auxiliary/procedural_mbe_matching.rs
@@ -15,6 +15,7 @@
 
 extern crate syntax;
 extern crate rustc;
+extern crate rustc_plugin;
 
 use syntax::codemap::Span;
 use syntax::parse::token::{self, str_to_ident, NtExpr, NtPat};
@@ -24,7 +25,7 @@ use syntax::ext::build::AstBuilder;
 use syntax::ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
 use syntax::ext::tt::macro_parser::{Success, Failure, Error};
 use syntax::ptr::P;
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 fn expand_mbe_matches(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         -> Box<MacResult + 'static> {
diff --git a/src/test/auxiliary/rlib_crate_test.rs b/src/test/auxiliary/rlib_crate_test.rs
index 86ce3df9ba6..ae1568b2f88 100644
--- a/src/test/auxiliary/rlib_crate_test.rs
+++ b/src/test/auxiliary/rlib_crate_test.rs
@@ -14,8 +14,9 @@
 #![feature(plugin_registrar, rustc_private)]
 
 extern crate rustc;
+extern crate rustc_plugin;
 
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 #[plugin_registrar]
 pub fn plugin_registrar(_: &mut Registry) {}
diff --git a/src/test/auxiliary/roman_numerals.rs b/src/test/auxiliary/roman_numerals.rs
index c9249fb3357..c262b0dba25 100644
--- a/src/test/auxiliary/roman_numerals.rs
+++ b/src/test/auxiliary/roman_numerals.rs
@@ -16,13 +16,14 @@
 
 extern crate syntax;
 extern crate rustc;
+extern crate rustc_plugin;
 
 use syntax::codemap::Span;
 use syntax::ast::TokenTree;
 use syntax::parse::token;
 use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
 use syntax::ext::build::AstBuilder;  // trait for expr_usize
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 // WARNING WARNING WARNING WARNING WARNING
 // =======================================
diff --git a/src/test/auxiliary/syntax_extension_with_dll_deps_2.rs b/src/test/auxiliary/syntax_extension_with_dll_deps_2.rs
index 4980eb8b913..7281698a7fb 100644
--- a/src/test/auxiliary/syntax_extension_with_dll_deps_2.rs
+++ b/src/test/auxiliary/syntax_extension_with_dll_deps_2.rs
@@ -16,11 +16,12 @@
 extern crate syntax_extension_with_dll_deps_1 as other;
 extern crate syntax;
 extern crate rustc;
+extern crate rustc_plugin;
 
 use syntax::ast::{TokenTree, Item, MetaItem};
 use syntax::codemap::Span;
 use syntax::ext::base::*;
-use rustc::plugin::Registry;
+use rustc_plugin::Registry;
 
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
diff --git a/src/test/compile-fail/use-from-trait-xc.rs b/src/test/compile-fail/use-from-trait-xc.rs
index 4f7e38bd26b..e6c9b1b41c0 100644
--- a/src/test/compile-fail/use-from-trait-xc.rs
+++ b/src/test/compile-fail/use-from-trait-xc.rs
@@ -22,13 +22,13 @@ use use_from_trait_xc::Trait::CONST;
 //~^ ERROR `CONST` is not directly importable
 
 use use_from_trait_xc::Foo::new;
-//~^ ERROR `new` is not directly importable
+//~^ ERROR unresolved import `use_from_trait_xc::Foo::new`
 
 use use_from_trait_xc::Foo::C;
 //~^ ERROR unresolved import `use_from_trait_xc::Foo::C`
 
 use use_from_trait_xc::Bar::new as bnew;
-//~^ ERROR `bnew` is not directly importable
+//~^ ERROR unresolved import `use_from_trait_xc::Bar::new`
 
 use use_from_trait_xc::Baz::new as baznew;
 //~^ ERROR `baznew` is not directly importable
diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs
index 8ca64e866a0..20dd16872a6 100644
--- a/src/test/run-make/execution-engine/test.rs
+++ b/src/test/run-make/execution-engine/test.rs
@@ -16,26 +16,30 @@ extern crate rustc;
 extern crate rustc_driver;
 extern crate rustc_front;
 extern crate rustc_lint;
+extern crate rustc_metadata;
 extern crate rustc_resolve;
 extern crate syntax;
 
 use std::ffi::{CStr, CString};
 use std::mem::transmute;
 use std::path::PathBuf;
+use std::rc::Rc;
 use std::thread::Builder;
 
 use rustc::front::map as ast_map;
 use rustc::llvm;
-use rustc::metadata::cstore::RequireDynamic;
+use rustc::middle::cstore::{CrateStore, LinkagePreference};
 use rustc::middle::ty;
 use rustc::session::config::{self, basic_options, build_configuration, Input, Options};
 use rustc::session::build_session;
 use rustc_driver::driver;
 use rustc_front::lowering::{lower_crate, LoweringContext};
 use rustc_resolve::MakeGlobMap;
+use rustc_metadata::cstore::CStore;
 use libc::c_void;
 
 use syntax::diagnostics::registry::Registry;
+use syntax::parse::token;
 
 fn main() {
     let program = r#"
@@ -210,7 +214,10 @@ fn compile_program(input: &str, sysroot: PathBuf)
 
     let handle = thread.spawn(move || {
         let opts = build_exec_options(sysroot);
-        let sess = build_session(opts, None, Registry::new(&rustc::DIAGNOSTICS));
+        let cstore = Rc::new(CStore::new(token::get_ident_interner()));
+        let cstore_ = ::rustc_driver::cstore_to_cratestore(cstore.clone());
+        let sess = build_session(opts, None, Registry::new(&rustc::DIAGNOSTICS),
+                                 cstore_);
         rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
 
         let cfg = build_configuration(&sess);
@@ -219,7 +226,7 @@ fn compile_program(input: &str, sysroot: PathBuf)
 
         let krate = driver::phase_1_parse_input(&sess, cfg, &input);
 
-        let krate = driver::phase_2_configure_and_expand(&sess, krate, &id, None)
+        let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, &id, None)
             .expect("phase_2 returned `None`");
 
         let krate = driver::assign_node_ids(&sess, krate);
@@ -229,11 +236,12 @@ fn compile_program(input: &str, sysroot: PathBuf)
         let ast_map = driver::make_map(&sess, &mut hir_forest);
 
         driver::phase_3_run_analysis_passes(
-            &sess, ast_map, &arenas, &id, MakeGlobMap::No, |tcx, mir_map, analysis| {
+            &sess, &cstore, ast_map, &arenas, &id,
+            MakeGlobMap::No, |tcx, mir_map, analysis| {
 
             let trans = driver::phase_4_translate_to_llvm(tcx, mir_map, analysis);
 
-            let crates = tcx.sess.cstore.get_used_crates(RequireDynamic);
+            let crates = tcx.sess.cstore.used_crates(LinkagePreference::RequireDynamic);
 
             // Collect crates used in the session.
             // Reverse order finds dependencies first.
diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make/issue-19371/foo.rs
index bd8c735df31..58bf5049cf1 100644
--- a/src/test/run-make/issue-19371/foo.rs
+++ b/src/test/run-make/issue-19371/foo.rs
@@ -13,14 +13,18 @@
 extern crate rustc;
 extern crate rustc_driver;
 extern crate rustc_lint;
+extern crate rustc_metadata;
 extern crate syntax;
 
 use rustc::session::{build_session, Session};
 use rustc::session::config::{basic_options, build_configuration, Input, OutputType};
 use rustc_driver::driver::{compile_input, CompileController};
+use rustc_metadata::cstore::CStore;
 use syntax::diagnostics::registry::Registry;
+use syntax::parse::token;
 
 use std::path::PathBuf;
+use std::rc::Rc;
 
 fn main() {
     let src = r#"
@@ -44,23 +48,25 @@ fn main() {
     compile(src.to_string(), tmpdir.join("out"), sysroot.clone());
 }
 
-fn basic_sess(sysroot: PathBuf) -> Session {
+fn basic_sess(sysroot: PathBuf) -> (Session, Rc<CStore>) {
     let mut opts = basic_options();
     opts.output_types.insert(OutputType::Exe, None);
     opts.maybe_sysroot = Some(sysroot);
 
     let descriptions = Registry::new(&rustc::DIAGNOSTICS);
-    let sess = build_session(opts, None, descriptions);
+    let cstore = Rc::new(CStore::new(token::get_ident_interner()));
+    let cstore_ = ::rustc_driver::cstore_to_cratestore(cstore.clone());
+    let sess = build_session(opts, None, descriptions, cstore_);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
-    sess
+    (sess, cstore)
 }
 
 fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
-    let sess = basic_sess(sysroot);
+    let (sess, cstore) = basic_sess(sysroot);
     let cfg = build_configuration(&sess);
     let control = CompileController::basic();
 
-    compile_input(sess,
+    compile_input(sess, &cstore,
             cfg,
             &Input::Str(code),
             &None,
diff --git a/src/test/run-make/libs-through-symlinks/Makefile b/src/test/run-make/libs-through-symlinks/Makefile
index f097d8fabd1..2f425121f66 100644
--- a/src/test/run-make/libs-through-symlinks/Makefile
+++ b/src/test/run-make/libs-through-symlinks/Makefile
@@ -10,5 +10,5 @@ all:
 	mkdir -p $(TMPDIR)/outdir
 	$(RUSTC) foo.rs -o $(TMPDIR)/outdir/$(NAME)
 	ln -nsf outdir/$(NAME) $(TMPDIR)
-	RUST_LOG=rustc::metadata::loader $(RUSTC) bar.rs
+	RUST_LOG=rustc_metadata::loader $(RUSTC) bar.rs
 endif