about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <ariel.byd@gmail.com>2015-11-21 21:39:05 +0200
committerAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2015-11-26 18:21:17 +0200
commitd45dd9423e0fa11510f3e62dd0f286bf6c0cdf37 (patch)
tree4c37217cfff610906c14faf3b6ae2448c2b2d001
parent11dbb69bd14f52940d54981b883814d52153dc57 (diff)
downloadrust-d45dd9423e0fa11510f3e62dd0f286bf6c0cdf37.tar.gz
rust-d45dd9423e0fa11510f3e62dd0f286bf6c0cdf37.zip
make CrateStore a trait object
rustdoc still broken
-rw-r--r--src/librustc/metadata/creader.rs55
-rw-r--r--src/librustc/metadata/cstore.rs4
-rw-r--r--src/librustc/metadata/decoder.rs49
-rw-r--r--src/librustc/metadata/encoder.rs4
-rw-r--r--src/librustc/metadata/macro_import.rs11
-rw-r--r--src/librustc/metadata/mod.rs1
-rw-r--r--src/librustc/metadata/util.rs49
-rw-r--r--src/librustc/middle/dependency_format.rs31
-rw-r--r--src/librustc/middle/lang_items.rs10
-rw-r--r--src/librustc/middle/stability.rs2
-rw-r--r--src/librustc/middle/ty/util.rs2
-rw-r--r--src/librustc/middle/weak_lang_items.rs4
-rw-r--r--src/librustc/plugin/load.rs9
-rw-r--r--src/librustc/session/mod.rs16
-rw-r--r--src/librustc_driver/driver.rs12
-rw-r--r--src/librustc_driver/lib.rs32
-rw-r--r--src/librustc_driver/pretty.rs9
-rw-r--r--src/librustc_driver/test.rs4
-rw-r--r--src/librustc_lint/builtin.rs2
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs2
-rw-r--r--src/librustc_resolve/check_unused.rs2
-rw-r--r--src/librustc_trans/back/link.rs7
-rw-r--r--src/librustc_trans/lib.rs1
-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/trans/base.rs4
-rw-r--r--src/librustc_trans/trans/debuginfo/metadata.rs2
-rw-r--r--src/librustc_trans/trans/inline.rs1
-rw-r--r--src/librustc_typeck/check/method/suggest.rs9
29 files changed, 200 insertions, 143 deletions
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index 39c9ac32801..191b1705371 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc/metadata/creader.rs
@@ -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>>,
 }
@@ -113,6 +115,7 @@ pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
 
 
 fn register_native_lib(sess: &Session,
+                       cstore: &CStore,
                        span: Option<Span>,
                        name: String,
                        kind: cstore::NativeLibraryKind) {
@@ -139,7 +142,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 +167,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 +228,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 +246,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.do_get_used_crate_source(cnum).unwrap();
+            let source = self.cstore.do_get_used_crate_source(cnum).unwrap();
             if let Some(locs) = self.sess.opts.externs.get(name) {
                 let found = locs.iter().any(|l| {
                     let l = fs::canonicalize(l).ok();
@@ -342,8 +346,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 +402,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 +414,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.do_get_used_crate_source(cnum).unwrap())
+                (cnum, data, self.cstore.do_get_used_crate_source(cnum).unwrap())
             }
             LookupResult::Loaded(library) => {
                 self.register_crate(root, ident, name, span, library,
@@ -512,7 +516,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 +597,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 +618,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 +697,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 +711,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 +730,11 @@ 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 +748,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 +760,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 +788,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 +806,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 +841,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/cstore.rs b/src/librustc/metadata/cstore.rs
index 6cfec87e704..706033f815c 100644
--- a/src/librustc/metadata/cstore.rs
+++ b/src/librustc/metadata/cstore.rs
@@ -94,7 +94,7 @@ enum_from_u32! {
 
 // Where a crate came from on the local filesystem. One of these two options
 // must be non-None.
-#[derive(PartialEq, Clone)]
+#[derive(PartialEq, Clone, Debug)]
 pub struct CrateSource {
     pub dylib: Option<(PathBuf, PathKind)>,
     pub rlib: Option<(PathBuf, PathKind)>,
@@ -266,7 +266,7 @@ impl CStore {
         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)
     }
 }
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index b102213eff0..84a95f04795 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -22,13 +22,12 @@ 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 metadata::util::FoundAst;
 use middle::def;
 use middle::def_id::{DefId, DefIndex};
 use middle::lang_items;
@@ -771,24 +770,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 +996,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,
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index e543d8708b5..d86d6c25cce 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -22,6 +22,7 @@ use metadata::decoder;
 use metadata::tyencode;
 use metadata::index::{self, IndexData};
 use metadata::inline::InlinedItemRef;
+use metadata::util::CrateStore;
 use middle::def;
 use middle::def_id::{CRATE_DEF_INDEX, DefId};
 use middle::dependency_format::Linkage;
@@ -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/macro_import.rs b/src/librustc/metadata/macro_import.rs
index ca5999afbd3..b08f5d0640e 100644
--- a/src/librustc/metadata/macro_import.rs
+++ b/src/librustc/metadata/macro_import.rs
@@ -12,6 +12,7 @@
 
 use session::Session;
 use metadata::creader::CrateReader;
+use metadata::cstore::CStore;
 
 use std::collections::{HashSet, HashMap};
 use syntax::codemap::Span;
@@ -30,11 +31,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 +46,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/mod.rs b/src/librustc/metadata/mod.rs
index 008228e713b..052ed81394b 100644
--- a/src/librustc/metadata/mod.rs
+++ b/src/librustc/metadata/mod.rs
@@ -15,7 +15,6 @@ pub mod encoder;
 pub mod decoder;
 pub mod creader;
 pub mod cstore;
-pub mod csearch;
 pub mod index;
 pub mod loader;
 pub mod filesearch;
diff --git a/src/librustc/metadata/util.rs b/src/librustc/metadata/util.rs
index 23ae8df0e97..4618bd46ffa 100644
--- a/src/librustc/metadata/util.rs
+++ b/src/librustc/metadata/util.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use back::svh::Svh;
 use front::map as ast_map;
 use metadata::cstore;
 use metadata::decoder;
@@ -31,7 +32,6 @@ use rustc_front::hir;
 
 pub use metadata::common::LinkMeta;
 pub use metadata::creader::validate_crate_name;
-pub use metadata::csearch::FoundAst;
 pub use metadata::cstore::CrateSource;
 pub use metadata::cstore::LinkagePreference;
 pub use metadata::cstore::NativeLibraryKind;
@@ -48,6 +48,12 @@ pub struct ChildItem {
     pub vis: hir::Visibility
 }
 
+pub enum FoundAst<'ast> {
+    Found(&'ast InlinedItem),
+    FoundParent(DefId, &'ast InlinedItem),
+    NotFound,
+}
+
 pub trait CrateStore<'tcx> : Any {
     // item info
     fn stability(&self, def: DefId) -> Option<attr::Stability>;
@@ -101,6 +107,7 @@ pub trait CrateStore<'tcx> : Any {
     fn is_static_method(&self, did: DefId) -> bool;
     fn is_extern_fn(&self, tcx: &ty::ctxt<'tcx>, did: DefId) -> bool;
     fn is_static(&self, did: DefId) -> bool;
+    fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
 
     // crate metadata
     fn dylib_dependency_formats(&self, cnum: ast::CrateNum)
@@ -111,6 +118,7 @@ pub trait CrateStore<'tcx> : Any {
     fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool;
     fn is_allocator(&self, cnum: ast::CrateNum) -> bool;
     fn crate_name(&self, cnum: ast::CrateNum) -> String;
+    fn crate_hash(&self, cnum: ast::CrateNum) -> Svh;
     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>;
@@ -125,6 +133,11 @@ pub trait CrateStore<'tcx> : Any {
     // 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;
@@ -132,6 +145,7 @@ pub trait CrateStore<'tcx> : Any {
     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,
@@ -356,6 +370,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         decoder::is_static(&*cdata, did.index)
     }
 
+    fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool
+    {
+        self.do_is_statically_included_foreign_item(id)
+    }
+
     fn dylib_dependency_formats(&self, cnum: ast::CrateNum)
                                 -> Vec<(ast::CrateNum, LinkagePreference)>
     {
@@ -400,6 +419,12 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         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 plugin_registrar_fn(&self, cnum: ast::CrateNum) -> Option<DefId>
     {
         let cdata = self.get_crate_data(cnum);
@@ -480,6 +505,23 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         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
@@ -504,6 +546,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         self.do_get_used_crate_source(cnum).unwrap()
     }
 
+    fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum>
+    {
+        self.find_extern_mod_stmt_cnum(emod_id)
+    }
+
     fn encode_metadata(&self,
                        tcx: &ty::ctxt<'tcx>,
                        reexports: &def::ExportMap,
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs
index 786d2a8b81f..229ed5984b0 100644
--- a/src/librustc/middle/dependency_format.rs
+++ b/src/librustc/middle/dependency_format.rs
@@ -123,12 +123,12 @@ fn calculate_type(sess: &session::Session,
                 Some(v) => return v,
                 None => {}
             }
-            sess.cstore.iter_crate_data(|cnum, data| {
+            for cnum in sess.cstore.crates() {
                 let src = sess.cstore.used_crate_source(cnum);
-                if src.rlib.is_some() { return }
+                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,10 +151,11 @@ 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| {
+    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);
+            info!("adding dylib: {}", name);
             add_library(sess, cnum, RequireDynamic, &mut formats);
             let deps = sess.cstore.dylib_dependency_formats(cnum);
             for &(depnum, style) in &deps {
@@ -163,11 +164,12 @@ fn calculate_type(sess: &session::Session,
                 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) {
+    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,
@@ -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| {
+    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);
+            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.
@@ -259,7 +261,8 @@ fn attempt_static(sess: &session::Session) -> Option<DependencyList> {
 
     // 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| {
+    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 {
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 470c12f1221..c9be73892e4 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -203,13 +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| {
-            for (index, item_index) in crate_store.lang_items(crate_number) {
-                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);
             }
-        })
+        }
     }
 
     pub fn collect(&mut self, krate: &hir::Crate) {
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 96c9f424e3e..f70dce90fed 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -448,7 +448,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,
             };
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 464d5a89995..a6c2fd08e87 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -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 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/plugin/load.rs b/src/librustc/plugin/load.rs
index 751e748094d..ed721b6dab0 100644
--- a/src/librustc/plugin/load.rs
+++ b/src/librustc/plugin/load.rs
@@ -12,6 +12,7 @@
 
 use session::Session;
 use metadata::creader::CrateReader;
+use metadata::cstore::CStore;
 use plugin::registry::Registry;
 
 use std::borrow::ToOwned;
@@ -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/session/mod.rs b/src/librustc/session/mod.rs
index cab61b96b07..bf9c4c8bca6 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 use lint;
-use metadata::cstore::CStore;
 use metadata::filesearch;
+use metadata::util::CrateStore;
 use middle::dependency_format;
 use session::search_paths::PathKind;
 use util::nodemap::{NodeMap, FnvHashMap};
@@ -21,7 +21,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,6 +31,7 @@ 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 search_paths;
@@ -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..8d7e97440dd 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -18,6 +18,7 @@ use rustc::session::search_paths::PathKind;
 use rustc::lint;
 use rustc::metadata;
 use rustc::metadata::creader::LocalCrateReader;
+use rustc::metadata::cstore::CStore;
 use rustc::middle::{stability, ty, reachable};
 use rustc::middle::dependency_format;
 use rustc::middle;
@@ -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));
+                      || metadata::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..d28bd5b511d 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;
@@ -69,6 +70,8 @@ use rustc::session::config::{Input, PrintRequest, OutputType};
 use rustc::lint::Lint;
 use rustc::lint;
 use rustc::metadata;
+use rustc::metadata::cstore::CStore;
+use rustc::metadata::util::CrateStore;
 use rustc::util::common::time;
 
 use std::cmp::Ordering::Equal;
@@ -77,6 +80,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 +91,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 +104,20 @@ pub mod target_features;
 const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\
                                       md#bug-reports";
 
+// [stage0]: kill this
+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 +154,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 +171,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 +181,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 +351,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 {
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 8815d574725..ddd5f931a80 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -19,6 +19,7 @@ use rustc_trans::back::link;
 
 use driver;
 
+use rustc::metadata::cstore::CStore;
 use rustc::middle::ty;
 use rustc::middle::cfg;
 use rustc::middle::cfg::graphviz::LabelledCFG;
@@ -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..7af301bec77 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -107,7 +107,9 @@ 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 = ::rustc::metadata::cstore::CStore::new(token::get_ident_interner());
+    let sess = session::build_session_(options, None, span_diagnostic_handler,
+                                       Box::new(cstore));
     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());
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 3fd35e04fbc..7327170c52b 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -936,7 +936,7 @@ impl LateLintPass for PluginAsLibrary {
             _ => return,
         };
 
-        let prfn = match cx.sess().cstore.find_extern_mod_stmt_cnum(it.id) {
+        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.
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 2740c81e34a..752e7e55f55 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -309,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,
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_trans/back/link.rs b/src/librustc_trans/back/link.rs
index 621c99a8717..cefe04f5e35 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -622,7 +622,7 @@ 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 {
             NativeLibraryKind::NativeStatic => ab.add_native_library(&l),
             NativeLibraryKind::NativeFramework |
@@ -970,7 +970,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();
@@ -1087,8 +1087,7 @@ 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 == NativeLibraryKind::NativeStatic {Some(l)} else {None}
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 58949a63ebe..67a7f3efb27 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -65,7 +65,6 @@ 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/trans/base.rs b/src/librustc_trans/trans/base.rs
index 4f823b82daa..30ec1e662b0 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -3087,7 +3087,7 @@ 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, _| {
+        for cnum in sess.cstore.crates() {
             let syms = sess.cstore.reachable_ids(cnum);
             reachable_symbols.extend(syms.into_iter().filter(|did| {
                 sess.cstore.is_extern_fn(shared_ccx.tcx(), *did) ||
@@ -3095,7 +3095,7 @@ pub fn trans_crate<'tcx>(tcx: &ty::ctxt<'tcx>,
             }).map(|did| {
                 sess.cstore.item_symbol(did)
             }));
-        });
+        }
     }
 
     if codegen_units > 1 {
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 6178ffe14d6..5be4892484b 100644
--- a/src/librustc_trans/trans/inline.rs
+++ b/src/librustc_trans/trans/inline.rs
@@ -17,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);
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 6050e8bd95b..f4f4dc90feb 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -418,7 +418,7 @@ 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: &mdutil::CrateStore,
+                               cstore: &for<'a> mdutil::CrateStore<'a>,
                                dl: mdutil::DefLike) {
             match dl {
                 mdutil::DlDef(def::DefTrait(did)) => {
@@ -436,15 +436,14 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> {
                 _ => {}
             }
         }
-        let cstore: &mdutil::CrateStore = &ccx.tcx.sess.cstore;
+        let cstore = &*ccx.tcx.sess.cstore;
 
-        // FIXME: privatize this
-        ccx.tcx.sess.cstore.iter_crate_data(|cnum, _| {
+        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);
     }