]> git.lizzy.rs Git - rust.git/commitdiff
rustc_metadata: move all encoding/decoding helpers to methods.
authorEduard Burtescu <edy.burt@gmail.com>
Thu, 15 Sep 2016 08:04:00 +0000 (11:04 +0300)
committerEduard Burtescu <edy.burt@gmail.com>
Tue, 20 Sep 2016 17:08:05 +0000 (20:08 +0300)
src/librustc/middle/cstore.rs
src/librustc_metadata/astencode.rs
src/librustc_metadata/creader.rs
src/librustc_metadata/csearch.rs
src/librustc_metadata/cstore.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/loader.rs
src/librustc_metadata/rbml/reader.rs
src/librustdoc/clean/mod.rs

index 87fdc858cf0f5e90b6724a132a3692cc10ccb8ff..6324995f328b9c1e830b6b255e24813674844d03 100644 (file)
@@ -188,7 +188,6 @@ fn dylib_dependency_formats(&self, cnum: CrateNum)
     fn is_compiler_builtins(&self, cnum: CrateNum) -> bool;
     fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy;
     fn extern_crate(&self, cnum: CrateNum) -> Option<ExternCrate>;
-    fn crate_attrs(&self, cnum: CrateNum) -> Vec<ast::Attribute>;
     /// The name of the crate as it is referred to in source code of the current
     /// crate.
     fn crate_name(&self, cnum: CrateNum) -> InternedString;
@@ -365,8 +364,6 @@ fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy {
         bug!("panic_strategy")
     }
     fn extern_crate(&self, cnum: CrateNum) -> Option<ExternCrate> { bug!("extern_crate") }
-    fn crate_attrs(&self, cnum: CrateNum) -> Vec<ast::Attribute>
-        { bug!("crate_attrs") }
     fn crate_name(&self, cnum: CrateNum) -> InternedString { bug!("crate_name") }
     fn original_crate_name(&self, cnum: CrateNum) -> InternedString {
         bug!("original_crate_name")
index 518e6624412189ef200c2e2e03c8a0cfb452413e..f48c31fc2f9ddd5e07d7c46576ba35949f79248c 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(non_camel_case_types)]
-
 use rustc::hir::map as ast_map;
 
 use rustc::hir::intravisit::{Visitor, IdRangeComputingVisitor, IdRange};
@@ -64,9 +62,7 @@ pub fn decode_inlined_item<'a, 'tcx>(cdata: &CrateMetadata,
                                      orig_did: DefId)
                                      -> &'tcx InlinedItem {
     debug!("> Decoding inlined fn: {:?}", tcx.item_path_str(orig_did));
-    let dcx = &mut ast_doc.decoder();
-    dcx.tcx = Some(tcx);
-    dcx.cdata = Some(cdata);
+    let dcx = &mut DecodeContext::new(ast_doc, Some(cdata)).typed(tcx);
     dcx.from_id_range = IdRange::decode(dcx).unwrap();
     let cnt = dcx.from_id_range.max.as_usize() - dcx.from_id_range.min.as_usize();
     dcx.to_id_range.min = tcx.sess.reserve_node_ids(cnt);
index 73dcf9470183b7311d18a5cbfed67185c689ed02..77a583f7379c1fd0139af6f486c7b72c8321f3c2 100644 (file)
@@ -14,7 +14,6 @@
 
 use common::CrateInfo;
 use cstore::{self, CStore, CrateSource, MetadataBlob};
-use decoder;
 use loader::{self, CratePaths};
 
 use rustc::hir::def_id::{CrateNum, DefIndex};
@@ -28,6 +27,7 @@
 use rustc::hir::map as hir_map;
 
 use std::cell::{RefCell, Cell};
+use std::ops::Deref;
 use std::path::PathBuf;
 use std::rc::Rc;
 use std::fs;
@@ -143,11 +143,13 @@ enum PMDSource {
     Owned(loader::Library),
 }
 
-impl PMDSource {
-    pub fn as_slice<'a>(&'a self) -> &'a [u8] {
+impl Deref for PMDSource {
+    type Target = MetadataBlob;
+
+    fn deref(&self) -> &MetadataBlob {
         match *self {
-            PMDSource::Registered(ref cmd) => cmd.data(),
-            PMDSource::Owned(ref lib) => lib.metadata.as_slice(),
+            PMDSource::Registered(ref cmd) => &cmd.data,
+            PMDSource::Owned(ref lib) => &lib.metadata
         }
     }
 }
@@ -295,7 +297,7 @@ fn register_crate(&mut self,
                       -> (CrateNum, Rc<cstore::CrateMetadata>,
                           cstore::CrateSource) {
         info!("register crate `extern crate {} as {}`", name, ident);
-        let crate_info = decoder::get_crate_info(lib.metadata.as_slice());
+        let crate_info = lib.metadata.get_crate_info();
         self.verify_no_symbol_conflicts(span, &crate_info);
 
         // Claim this crate number and cache it
@@ -317,7 +319,7 @@ fn register_crate(&mut self,
 
         let loader::Library { dylib, rlib, metadata } = lib;
 
-        let cnum_map = self.resolve_crate_deps(root, metadata.as_slice(), cnum, span);
+        let cnum_map = self.resolve_crate_deps(root, &metadata, cnum, span);
 
         if crate_info.macro_derive_registrar.is_some() {
             self.sess.span_err(span, "crates of the `rustc-macro` crate type \
@@ -328,8 +330,8 @@ fn register_crate(&mut self,
             name: name.to_string(),
             extern_crate: Cell::new(None),
             info: crate_info,
-            index: decoder::load_index(metadata.as_slice()),
-            key_map: decoder::load_key_map(metadata.as_slice()),
+            index: metadata.load_index(),
+            key_map: metadata.load_key_map(),
             data: metadata,
             cnum_map: RefCell::new(cnum_map),
             cnum: cnum,
@@ -414,7 +416,7 @@ fn load(&mut self, loader: &mut loader::Context) -> Option<LoadResult> {
         // Note that we only do this for target triple crates, though, as we
         // don't want to match a host crate against an equivalent target one
         // already loaded.
-        let crate_info = decoder::get_crate_info(library.metadata.as_slice());
+        let crate_info = library.metadata.get_crate_info();
         if loader.triple == self.sess.opts.target_triple {
             let mut result = LoadResult::Loaded(library);
             self.cstore.iter_crate_data(|cnum, data| {
@@ -465,14 +467,14 @@ fn update_extern_crate(&mut self,
     // Go through the crate metadata and load any crates that it references
     fn resolve_crate_deps(&mut self,
                           root: &Option<CratePaths>,
-                          cdata: &[u8],
+                          metadata: &MetadataBlob,
                           krate: CrateNum,
                           span: Span)
                           -> cstore::CrateNumMap {
         debug!("resolving deps of external crate");
         // The map from crate numbers in the crate we're resolving to local crate
         // numbers
-        let map: FnvHashMap<_, _> = decoder::get_crate_deps(cdata).iter().map(|dep| {
+        let map: FnvHashMap<_, _> = metadata.get_crate_deps().iter().map(|dep| {
             debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
             let (local_cnum, ..) = self.resolve_crate(root,
                                                         &dep.name,
@@ -566,7 +568,7 @@ pub fn read_macros(&mut self, item: &ast::Item) -> Macros {
         let ci = self.extract_crate_info(item).unwrap();
         let ekrate = self.read_extension_crate(item.span, &ci);
 
-        let crate_info = decoder::get_crate_info(ekrate.metadata.as_slice());
+        let crate_info = ekrate.metadata.get_crate_info();
         let source_name = format!("<{} macros>", item.ident);
         let mut ret = Macros {
             macro_rules: Vec::new(),
@@ -574,8 +576,7 @@ pub fn read_macros(&mut self, item: &ast::Item) -> Macros {
             svh: crate_info.hash,
             dylib: None,
         };
-        decoder::each_exported_macro(ekrate.metadata.as_slice(),
-                                     |name, attrs, span, body| {
+        ekrate.metadata.each_exported_macro(|name, attrs, span, body| {
             // NB: Don't use parse::parse_tts_from_source_str because it parses with
             // quote_depth > 0.
             let mut p = parse::new_parser_from_source_str(&self.sess.parse_sess,
@@ -670,7 +671,7 @@ pub fn find_plugin_registrar(&mut self, span: Span, name: &str)
             span_fatal!(self.sess, span, E0456, "{}", &message[..]);
         }
 
-        let crate_info = decoder::get_crate_info(ekrate.metadata.as_slice());
+        let crate_info = ekrate.metadata.get_crate_info();
         match (ekrate.dylib.as_ref(), crate_info.plugin_registrar_fn) {
             (Some(dylib), Some(reg)) => {
                 Some((dylib.to_path_buf(), crate_info.hash, reg))
@@ -1111,7 +1112,7 @@ pub fn read_local_crates(sess: & Session,
 pub fn import_codemap(local_codemap: &codemap::CodeMap,
                       metadata: &MetadataBlob)
                       -> Vec<cstore::ImportedFileMap> {
-    let external_codemap = decoder::get_imported_filemaps(metadata.as_slice());
+    let external_codemap = metadata.get_imported_filemaps();
 
     let imported_filemaps = external_codemap.into_iter().map(|filemap_to_import| {
         // Try to find an existing FileMap that can be reused for the filemap to
index f650155c03546a8af55447730f2f8626695ce512..8136fc7e845f3962dda1ed3b9304e9ede58f67ae 100644 (file)
@@ -10,7 +10,6 @@
 
 use cstore;
 use common;
-use decoder;
 use encoder;
 use loader;
 
 impl<'tcx> CrateStore<'tcx> for cstore::CStore {
     fn stability(&self, def: DefId) -> Option<attr::Stability> {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_stability(&cdata, def.index)
+        self.get_crate_data(def.krate).get_stability(def.index)
     }
 
     fn deprecation(&self, def: DefId) -> Option<attr::Deprecation> {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_deprecation(&cdata, def.index)
+        self.get_crate_data(def.krate).get_deprecation(def.index)
     }
 
     fn visibility(&self, def: DefId) -> ty::Visibility {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_visibility(&cdata, def.index)
+        self.get_crate_data(def.krate).get_visibility(def.index)
     }
 
     fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind
     {
         assert!(!def_id.is_local());
         self.dep_graph.read(DepNode::MetaData(def_id));
-        let cdata = self.get_crate_data(def_id.krate);
-        decoder::closure_kind(&cdata, def_id.index)
+        self.get_crate_data(def_id.krate).closure_kind(def_id.index)
     }
 
     fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::ClosureTy<'tcx> {
         assert!(!def_id.is_local());
         self.dep_graph.read(DepNode::MetaData(def_id));
-        let cdata = self.get_crate_data(def_id.krate);
-        decoder::closure_ty(&cdata, def_id.index, tcx)
+        self.get_crate_data(def_id.krate).closure_ty(def_id.index, tcx)
     }
 
     fn item_variances(&self, def: DefId) -> Vec<ty::Variance> {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_item_variances(&cdata, def.index)
+        self.get_crate_data(def.krate).get_item_variances(def.index)
     }
 
     fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
                      -> Ty<'tcx>
     {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_type(&cdata, def.index, tcx)
+        self.get_crate_data(def.krate).get_type(def.index, tcx)
     }
 
     fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
                            -> ty::GenericPredicates<'tcx>
     {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_predicates(&cdata, def.index, tcx)
+        self.get_crate_data(def.krate).get_predicates(def.index, tcx)
     }
 
     fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
                                  -> ty::GenericPredicates<'tcx>
     {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_super_predicates(&cdata, def.index, tcx)
+        self.get_crate_data(def.krate).get_super_predicates(def.index, tcx)
     }
 
     fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
                          -> &'tcx ty::Generics<'tcx>
     {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_generics(&cdata, def.index, tcx)
+        self.get_crate_data(def.krate).get_generics(def.index, tcx)
     }
 
     fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>
     {
         self.dep_graph.read(DepNode::MetaData(def_id));
-        let cdata = self.get_crate_data(def_id.krate);
-        decoder::get_item_attrs(&cdata, def_id.index)
+        self.get_crate_data(def_id.krate).get_item_attrs(def_id.index)
     }
 
     fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::TraitDef<'tcx>
     {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_trait_def(&cdata, def.index, tcx)
+        self.get_crate_data(def.krate).get_trait_def(def.index, tcx)
     }
 
     fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
     {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_adt_def(&cdata, def.index, tcx)
+        self.get_crate_data(def.krate).get_adt_def(def.index, tcx)
     }
 
     fn fn_arg_names(&self, did: DefId) -> Vec<String>
     {
         self.dep_graph.read(DepNode::MetaData(did));
-        let cdata = self.get_crate_data(did.krate);
-        decoder::get_fn_arg_names(&cdata, did.index)
+        self.get_crate_data(did.krate).get_fn_arg_names(did.index)
     }
 
     fn opt_item_name(&self, def: DefId) -> Option<ast::Name> {
@@ -143,7 +128,7 @@ fn opt_item_name(&self, def: DefId) -> Option<ast::Name> {
         if def.index == CRATE_DEF_INDEX {
             Some(token::intern(&cdata.name()))
         } else {
-            decoder::maybe_get_item_name(&cdata, def.index)
+            cdata.maybe_get_item_name(def.index)
         }
     }
 
@@ -151,9 +136,8 @@ fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>
     {
         self.dep_graph.read(DepNode::MetaData(def_id));
         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));
+        self.get_crate_data(def_id.krate)
+            .each_inherent_implementation_for_type(def_id.index, |iid| result.push(iid));
         result
     }
 
@@ -164,7 +148,7 @@ fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>
         }
         let mut result = vec![];
         self.iter_crate_data(|_, cdata| {
-            decoder::each_implementation_for_trait(cdata, filter, &mut |iid| {
+            cdata.each_implementation_for_trait(filter, &mut |iid| {
                 result.push(iid)
             })
         });
@@ -174,85 +158,74 @@ fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>
     fn impl_or_trait_items(&self, def_id: DefId) -> Vec<DefId> {
         self.dep_graph.read(DepNode::MetaData(def_id));
         let mut result = vec![];
-        let crate_data = self.get_crate_data(def_id.krate);
         let get_crate_data = &mut |cnum| self.get_crate_data(cnum);
-        decoder::each_child_of_item(&crate_data, def_id.index, get_crate_data,
-                                    &mut |def, _, _| result.push(def.def_id()));
+        self.get_crate_data(def_id.krate)
+            .each_child_of_item(def_id.index, get_crate_data,
+                                &mut |def, _, _| result.push(def.def_id()));
         result
     }
 
     fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity
     {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_impl_polarity(&cdata, def.index)
+        self.get_crate_data(def.krate).get_impl_polarity(def.index)
     }
 
     fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
                           -> Option<ty::TraitRef<'tcx>>
     {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_impl_trait(&cdata, def.index, tcx)
+        self.get_crate_data(def.krate).get_impl_trait(def.index, tcx)
     }
 
     fn custom_coerce_unsized_kind(&self, def: DefId)
                                   -> Option<ty::adjustment::CustomCoerceUnsized>
     {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_custom_coerce_unsized_kind(&cdata, def.index)
+        self.get_crate_data(def.krate).get_custom_coerce_unsized_kind(def.index)
     }
 
     fn impl_parent(&self, impl_def: DefId) -> Option<DefId> {
         self.dep_graph.read(DepNode::MetaData(impl_def));
-        let cdata = self.get_crate_data(impl_def.krate);
-        decoder::get_parent_impl(&*cdata, impl_def.index)
+        self.get_crate_data(impl_def.krate).get_parent_impl(impl_def.index)
     }
 
     fn trait_of_item(&self, def_id: DefId) -> Option<DefId> {
         self.dep_graph.read(DepNode::MetaData(def_id));
-        let cdata = self.get_crate_data(def_id.krate);
-        decoder::get_trait_of_item(&cdata, def_id.index)
+        self.get_crate_data(def_id.krate).get_trait_of_item(def_id.index)
     }
 
     fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
                               -> Option<ty::ImplOrTraitItem<'tcx>>
     {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_impl_or_trait_item(&cdata, def.index, tcx)
+        self.get_crate_data(def.krate).get_impl_or_trait_item(def.index, tcx)
     }
 
     fn is_const_fn(&self, did: DefId) -> bool
     {
         self.dep_graph.read(DepNode::MetaData(did));
-        let cdata = self.get_crate_data(did.krate);
-        decoder::is_const_fn(&cdata, did.index)
+        self.get_crate_data(did.krate).is_const_fn(did.index)
     }
 
     fn is_defaulted_trait(&self, trait_def_id: DefId) -> bool
     {
         self.dep_graph.read(DepNode::MetaData(trait_def_id));
-        let cdata = self.get_crate_data(trait_def_id.krate);
-        decoder::is_defaulted_trait(&cdata, trait_def_id.index)
+        self.get_crate_data(trait_def_id.krate).is_defaulted_trait(trait_def_id.index)
     }
 
     fn is_default_impl(&self, impl_did: DefId) -> bool {
         self.dep_graph.read(DepNode::MetaData(impl_did));
-        let cdata = self.get_crate_data(impl_did.krate);
-        decoder::is_default_impl(&cdata, impl_did.index)
+        self.get_crate_data(impl_did.krate).is_default_impl(impl_did.index)
     }
 
     fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool {
         self.dep_graph.read(DepNode::MetaData(did));
-        let cdata = self.get_crate_data(did.krate);
-        decoder::is_extern_item(&cdata, did.index, tcx)
+        self.get_crate_data(did.krate).is_extern_item(did.index, tcx)
     }
 
     fn is_foreign_item(&self, did: DefId) -> bool {
-        let cdata = self.get_crate_data(did.krate);
-        decoder::is_foreign_item(&cdata, did.index)
+        self.get_crate_data(did.krate).is_foreign_item(did.index)
     }
 
     fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool
@@ -263,21 +236,18 @@ fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool
     fn dylib_dependency_formats(&self, cnum: CrateNum)
                                 -> Vec<(CrateNum, LinkagePreference)>
     {
-        let cdata = self.get_crate_data(cnum);
-        decoder::get_dylib_dependency_formats(&cdata)
+        self.get_crate_data(cnum).get_dylib_dependency_formats()
     }
 
     fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)>
     {
-        let crate_data = self.get_crate_data(cnum);
-        decoder::get_lang_items(&crate_data)
+        self.get_crate_data(cnum).get_lang_items()
     }
 
     fn missing_lang_items(&self, cnum: CrateNum)
                           -> Vec<lang_items::LangItem>
     {
-        let cdata = self.get_crate_data(cnum);
-        decoder::get_missing_lang_items(&cdata)
+        self.get_crate_data(cnum).get_missing_lang_items()
     }
 
     fn is_staged_api(&self, cnum: CrateNum) -> bool
@@ -308,11 +278,6 @@ fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy {
         self.get_crate_data(cnum).panic_strategy()
     }
 
-    fn crate_attrs(&self, cnum: CrateNum) -> Vec<ast::Attribute>
-    {
-        decoder::get_item_attrs(&self.get_crate_data(cnum), CRATE_DEF_INDEX)
-    }
-
     fn crate_name(&self, cnum: CrateNum) -> token::InternedString
     {
         token::intern_and_get_ident(&self.get_crate_data(cnum).name[..])
@@ -348,18 +313,16 @@ fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>
 
     fn native_libraries(&self, cnum: CrateNum) -> Vec<(NativeLibraryKind, String)>
     {
-        let cdata = self.get_crate_data(cnum);
-        decoder::get_native_libraries(&cdata)
+        self.get_crate_data(cnum).get_native_libraries()
     }
 
     fn reachable_ids(&self, cnum: CrateNum) -> Vec<DefId>
     {
-        let cdata = self.get_crate_data(cnum);
-        decoder::get_reachable_ids(&cdata)
+        self.get_crate_data(cnum).get_reachable_ids()
     }
 
     fn is_no_builtins(&self, cnum: CrateNum) -> bool {
-        attr::contains_name(&self.crate_attrs(cnum), "no_builtins")
+        self.get_crate_data(cnum).is_no_builtins()
     }
 
     fn def_index_for_def_key(&self,
@@ -380,8 +343,7 @@ fn def_key(&self, def: DefId) -> hir_map::DefKey {
         // canonical name for an item.
         //
         // self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::def_key(&cdata, def.index)
+        self.get_crate_data(def.krate).def_key(def.index)
     }
 
     fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath> {
@@ -389,34 +351,35 @@ fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath> {
         // commented out:
         //
         // self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::def_path(&cdata, def.index)
+        self.get_crate_data(def.krate).def_path(def.index)
     }
 
     fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>
     {
         self.dep_graph.read(DepNode::MetaData(struct_def_id));
-        let cdata = self.get_crate_data(struct_def_id.krate);
-        decoder::get_struct_ctor_def_id(&cdata, struct_def_id.index)
+        self.get_crate_data(struct_def_id.krate).get_struct_ctor_def_id(struct_def_id.index)
     }
 
     fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>
     {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_struct_field_names(&cdata, def.index)
+        self.get_crate_data(def.krate).get_struct_field_names(def.index)
     }
 
     fn item_children(&self, def_id: DefId) -> Vec<ChildItem>
     {
         self.dep_graph.read(DepNode::MetaData(def_id));
         let mut result = vec![];
-        let crate_data = self.get_crate_data(def_id.krate);
         let get_crate_data = &mut |cnum| self.get_crate_data(cnum);
-        decoder::each_child_of_item(&crate_data, def_id.index, get_crate_data,
-                                    &mut |def, name, vis| {
-            result.push(ChildItem { def: def, name: name, vis: vis });
-        });
+        self.get_crate_data(def_id.krate)
+            .each_child_of_item(def_id.index, get_crate_data,
+                                &mut |def, name, vis| {
+                result.push(ChildItem {
+                    def: def,
+                    name: name,
+                    vis: vis
+                });
+            });
         result
     }
 
@@ -445,8 +408,7 @@ fn maybe_get_item_ast<'a>(&'tcx self,
 
         debug!("maybe_get_item_ast({}): inlining item", tcx.item_path_str(def_id));
 
-        let cdata = self.get_crate_data(def_id.krate);
-        let inlined = decoder::maybe_get_item_ast(&cdata, tcx, def_id.index);
+        let inlined = self.get_crate_data(def_id.krate).maybe_get_item_ast(tcx, def_id.index);
 
         let cache_inlined_item = |original_def_id, inlined_item_id, inlined_root_node_id| {
             let cache_entry = cstore::CachedInlinedItem {
@@ -534,14 +496,12 @@ fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId> {
     fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
                               -> Option<Mir<'tcx>> {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::maybe_get_item_mir(&cdata, tcx, def.index)
+        self.get_crate_data(def.krate).maybe_get_item_mir(tcx, def.index)
     }
 
     fn is_item_mir_available(&self, def: DefId) -> bool {
         self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::is_item_mir_available(&cdata, def.index)
+        self.get_crate_data(def.krate).is_item_mir_available(def.index)
     }
 
     fn crates(&self) -> Vec<CrateNum>
index 44fdf29aa73c461efaa1e7c2871f431b0c5c2026..4151f98b3daeeef83ce6265a91f801111de98972 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(non_camel_case_types)]
-
 // The crate store - a central repo for information collected about external
 // crates and libraries
 
@@ -17,7 +15,6 @@
 
 use common;
 use creader;
-use decoder;
 use index;
 use loader;
 
@@ -297,7 +294,6 @@ pub fn add_used_for_derive_macros(&self, i: &ast::Item) {
 }
 
 impl CrateMetadata {
-    pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
     pub fn name(&self) -> &str { &self.info.name }
     pub fn hash(&self) -> Svh { self.info.hash }
     pub fn disambiguator(&self) -> &str { &self.info.disambiguator }
@@ -317,37 +313,41 @@ pub fn imported_filemaps<'a>(&'a self, codemap: &codemap::CodeMap)
     }
 
     pub fn is_staged_api(&self) -> bool {
-        let attrs = decoder::get_item_attrs(self, CRATE_DEF_INDEX);
-        attrs.iter().any(|attr| {
+        self.get_item_attrs(CRATE_DEF_INDEX).iter().any(|attr| {
             attr.name() == "stable" || attr.name() == "unstable"
         })
     }
 
     pub fn is_allocator(&self) -> bool {
-        let attrs = decoder::get_item_attrs(self, CRATE_DEF_INDEX);
+        let attrs = self.get_item_attrs(CRATE_DEF_INDEX);
         attr::contains_name(&attrs, "allocator")
     }
 
     pub fn needs_allocator(&self) -> bool {
-        let attrs = decoder::get_item_attrs(self, CRATE_DEF_INDEX);
+        let attrs = self.get_item_attrs(CRATE_DEF_INDEX);
         attr::contains_name(&attrs, "needs_allocator")
     }
 
     pub fn is_panic_runtime(&self) -> bool {
-        let attrs = decoder::get_item_attrs(self, CRATE_DEF_INDEX);
+        let attrs = self.get_item_attrs(CRATE_DEF_INDEX);
         attr::contains_name(&attrs, "panic_runtime")
     }
 
     pub fn needs_panic_runtime(&self) -> bool {
-        let attrs = decoder::get_item_attrs(self, CRATE_DEF_INDEX);
+        let attrs = self.get_item_attrs(CRATE_DEF_INDEX);
         attr::contains_name(&attrs, "needs_panic_runtime")
     }
 
     pub fn is_compiler_builtins(&self) -> bool {
-        let attrs = decoder::get_crate_attributes(self.data());
+        let attrs = self.get_item_attrs(CRATE_DEF_INDEX);
         attr::contains_name(&attrs, "compiler_builtins")
     }
 
+    pub fn is_no_builtins(&self) -> bool {
+        let attrs = self.get_item_attrs(CRATE_DEF_INDEX);
+        attr::contains_name(&attrs, "no_builtins")
+    }
+
     pub fn panic_strategy(&self) -> PanicStrategy {
         self.info.panic_strategy.clone()
     }
index c665a7be955dc372dee451d79719c7ca9c06b5bf..05bd9e97234e542902029e4bb1ecfd3111ecbd12 100644 (file)
 
 // Decoding metadata from a single crate's metadata
 
-#![allow(non_camel_case_types)]
-
 use astencode::decode_inlined_item;
-use cstore::{self, CrateMetadata};
+use cstore::{CrateMetadata, MetadataBlob, NativeLibraryKind};
 use common::*;
 use index;
 
-use rustc::hir::def_id::CRATE_DEF_INDEX;
 use rustc::hir::svh::Svh;
 use rustc::hir::map as hir_map;
 use rustc::hir::map::{DefKey, DefPathData};
@@ -43,7 +40,6 @@
 use std::str;
 use std::u32;
 
-use rbml::reader;
 use rbml;
 use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque};
 use syntax::attr;
 
 pub struct DecodeContext<'a, 'tcx: 'a> {
     pub opaque: opaque::Decoder<'a>,
-    pub tcx: Option<TyCtxt<'a, 'tcx, 'tcx>>,
-    pub cdata: Option<&'a cstore::CrateMetadata>,
+    tcx: Option<TyCtxt<'a, 'tcx, 'tcx>>,
+    cdata: Option<&'a CrateMetadata>,
     pub from_id_range: IdRange,
     pub to_id_range: IdRange,
     // Cache the last used filemap for translating spans as an optimization.
     last_filemap_index: usize,
 }
 
-impl<'doc> rbml::Doc<'doc> {
-    pub fn decoder<'tcx>(self) -> DecodeContext<'doc, 'tcx> {
+impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
+    pub fn new(doc: rbml::Doc<'a>, cdata: Option<&'a CrateMetadata>)
+               -> DecodeContext<'a, 'tcx> {
         let id_range = IdRange {
             min: NodeId::from_u32(u32::MIN),
             max: NodeId::from_u32(u32::MAX)
         };
         DecodeContext {
-            opaque: opaque::Decoder::new(self.data, self.start),
-            cdata: None,
+            opaque: opaque::Decoder::new(doc.data, doc.start),
+            cdata: cdata,
             tcx: None,
             from_id_range: id_range,
             to_id_range: id_range,
             last_filemap_index: 0
         }
     }
-}
 
-impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
     pub fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
         self.tcx.expect("missing TyCtxt in DecodeContext")
     }
 
-    pub fn cdata(&self) -> &'a cstore::CrateMetadata {
+    pub fn cdata(&self) -> &'a CrateMetadata {
         self.cdata.expect("missing CrateMetadata in DecodeContext")
     }
 
@@ -91,6 +86,11 @@ pub fn decode<T: Decodable>(&mut self) -> T {
         T::decode(self).unwrap()
     }
 
+    pub fn typed(mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
+        self.tcx = Some(tcx);
+        self
+    }
+
     /// Iterate over the indices of a sequence.
     /// This will work solely because of `serialize::opaque`'s
     /// simple encoding of `n: usize` followed by `n` elements.
@@ -295,124 +295,84 @@ fn specialized_decode(&mut self) -> Result<ty::AdtDef<'tcx>, Self::Error> {
     }
 }
 
-pub type Cmd<'a> = &'a CrateMetadata;
+#[derive(Clone)]
+pub struct CrateDep {
+    pub cnum: CrateNum,
+    pub name: String,
+    pub hash: Svh,
+    pub explicitly_linked: bool,
+}
 
-impl CrateMetadata {
-    fn get_item(&self, item_id: DefIndex) -> Option<rbml::Doc> {
-        self.index.lookup_item(self.data(), item_id).map(|pos| {
-            rbml::Doc::at(self.data(), pos as usize)
-        })
+impl<'a, 'tcx> MetadataBlob {
+    fn root(&self) -> rbml::Doc {
+        rbml::Doc::new(self.as_slice())
     }
 
-    fn lookup_item(&self, item_id: DefIndex) -> rbml::Doc {
-        match self.get_item(item_id) {
-            None => bug!("lookup_item: id not found: {:?} in crate {:?} with number {}",
-                         item_id,
-                         self.name,
-                         self.cnum),
-            Some(d) => d
-        }
+    fn child_at(&'a self, pos: usize, tag: usize) -> DecodeContext<'a, 'tcx> {
+        DecodeContext::new(rbml::Doc::at(self.as_slice(), pos).child(tag), None)
     }
 
-    fn local_def_id(&self, index: DefIndex) -> DefId {
-        DefId {
-            krate: self.cnum,
-            index: index
-        }
+    fn get(&'a self, tag: usize) -> DecodeContext<'a, 'tcx> {
+        DecodeContext::new(self.root().child(tag), None)
     }
-}
-
-pub fn load_index(data: &[u8]) -> index::Index {
-    index::Index::from_rbml(rbml::Doc::new(data).get(root_tag::index))
-}
-
-pub fn crate_rustc_version(data: &[u8]) -> Option<String> {
-    let doc = rbml::Doc::new(data);
-    reader::maybe_get_doc(doc, root_tag::rustc_version).map(|s| {
-        str::from_utf8(&s.data[s.start..s.end]).unwrap().to_string()
-    })
-}
-
-// Go through each item in the metadata and create a map from that
-// item's def-key to the item's DefIndex.
-pub fn load_key_map(data: &[u8]) -> FnvHashMap<DefKey, DefIndex> {
-    load_index(data).iter_enumerated(data).map(|(index, pos)| {
-        // load def-key from item
-        let key = item_def_key(rbml::Doc::at(data, pos as usize));
-        (key, index)
-    }).collect()
-}
-
-fn item_family(item: rbml::Doc) -> Family {
-    item.get(item_tag::family).decoder().decode()
-}
 
-fn item_visibility(item: rbml::Doc) -> ty::Visibility {
-    item.get(item_tag::visibility).decoder().decode()
-}
-
-fn entry_data(doc: rbml::Doc, cdata: Cmd) -> EntryData {
-    let mut dcx = doc.get(item_tag::data).decoder();
-    dcx.cdata = Some(cdata);
+    pub fn load_index(&self) -> index::Index {
+        index::Index::from_rbml(self.root().child(root_tag::index))
+    }
 
-    dcx.decode()
-}
+    pub fn crate_rustc_version(&self) -> Option<String> {
+        self.root().maybe_child(root_tag::rustc_version).map(|s| {
+            str::from_utf8(&s.data[s.start..s.end]).unwrap().to_string()
+        })
+    }
 
-fn entry_typed_data<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd)
-                              -> EntryTypedData<'tcx> {
-    let mut dcx = doc.get(item_tag::typed_data).decoder();
-    dcx.cdata = Some(cdata);
-    dcx.tcx = Some(tcx);
+    // Go through each item in the metadata and create a map from that
+    // item's def-key to the item's DefIndex.
+    pub fn load_key_map(&self) -> FnvHashMap<DefKey, DefIndex> {
+        self.load_index().iter_enumerated(self.as_slice()).map(|(index, pos)| {
+            (self.child_at(pos as usize, item_tag::def_key).decode(), index)
+        }).collect()
+    }
 
-    dcx.decode()
-}
+    pub fn get_crate_deps(&self) -> Vec<CrateDep> {
+        let dcx = self.get(root_tag::crate_deps);
 
-fn item_parent_item(cdata: Cmd, d: rbml::Doc) -> Option<DefId> {
-    item_def_key(d).parent.map(|index| cdata.local_def_id(index))
-}
+        dcx.seq().enumerate().map(|(crate_num, (name, hash, explicitly_linked))| {
+            CrateDep {
+                cnum: CrateNum::new(crate_num + 1),
+                name: name,
+                hash: hash,
+                explicitly_linked: explicitly_linked,
+            }
+        }).collect()
+    }
 
-fn doc_type<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd) -> Ty<'tcx> {
-    maybe_doc_type(doc, tcx, cdata).expect("missing item_tag::ty")
-}
+    pub fn get_crate_info(&self) -> CrateInfo {
+        self.get(root_tag::crate_info).decode()
+    }
 
-fn maybe_doc_type<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd)
-                            -> Option<Ty<'tcx>> {
-    reader::maybe_get_doc(doc, item_tag::ty).map(|tp| {
-        let mut dcx = tp.decoder();
-        dcx.tcx = Some(tcx);
-        dcx.cdata = Some(cdata);
-        dcx.decode()
-    })
-}
+    pub fn list_crate_metadata(&self, out: &mut io::Write) -> io::Result<()> {
+        write!(out, "=External Dependencies=\n")?;
+        for dep in &self.get_crate_deps() {
+            write!(out, "{} {}-{}\n", dep.cnum, dep.name, dep.hash)?;
+        }
+        write!(out, "\n")?;
+        Ok(())
+    }
 
-fn item_name(item: rbml::Doc) -> ast::Name {
-    maybe_item_name(item).expect("no item in item_name")
-}
+    pub fn get_imported_filemaps(&self) -> Vec<syntax_pos::FileMap> {
+        self.get(root_tag::codemap).decode()
+    }
 
-fn maybe_item_name(item: rbml::Doc) -> Option<ast::Name> {
-    let name = match item_def_key(item).disambiguated_data.data {
-        DefPathData::TypeNs(name) |
-        DefPathData::ValueNs(name) |
-        DefPathData::Module(name) |
-        DefPathData::MacroDef(name) |
-        DefPathData::TypeParam(name) |
-        DefPathData::LifetimeDef(name) |
-        DefPathData::EnumVariant(name) |
-        DefPathData::Field(name) |
-        DefPathData::Binding(name) => Some(name),
-
-        DefPathData::InlinedRoot(_) => bug!("unexpected DefPathData"),
-
-        DefPathData::CrateRoot |
-        DefPathData::Misc |
-        DefPathData::Impl |
-        DefPathData::ClosureExpr |
-        DefPathData::StructCtor |
-        DefPathData::Initializer |
-        DefPathData::ImplTrait => None
-    };
-
-    name.map(|s| token::intern(&s))
+    pub fn each_exported_macro<F>(&self, mut f: F) where
+        F: FnMut(ast::Name, Vec<ast::Attribute>, Span, String) -> bool,
+    {
+        for (name, attrs, span, body) in self.get(root_tag::macro_defs).seq() {
+            if !f(name, attrs, span, body) {
+                break;
+            }
+        }
+    }
 }
 
 impl Family {
@@ -444,729 +404,698 @@ fn to_def(&self, did: DefId) -> Option<Def> {
     }
 }
 
-pub fn get_trait_def<'a, 'tcx>(cdata: Cmd,
-                               item_id: DefIndex,
-                               tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::TraitDef<'tcx>
-{
-    let item_doc = cdata.lookup_item(item_id);
-    let generics = doc_generics(item_doc, tcx, cdata);
-
-    let data = match entry_data(item_doc, cdata) {
-        EntryData::Trait(data) => data,
-        _ => bug!()
-    };
-    let typed_data = match entry_typed_data(item_doc, tcx, cdata) {
-        EntryTypedData::Trait(data) => data,
-        _ => bug!()
-    };
-
-    ty::TraitDef::new(data.unsafety, data.paren_sugar, generics, typed_data.trait_ref,
-                      def_path(cdata, item_id).unwrap().deterministic_hash(tcx)))
-}
-
-fn get_variant<'tcx>(cdata: Cmd,
-                     item: rbml::Doc,
-                     index: DefIndex)
-                     -> (ty::VariantDefData<'tcx, 'tcx>, Option<DefIndex>) {
-    let data = match entry_data(item, cdata) {
-        EntryData::Variant(data) => data,
-        _ => bug!()
-    };
-
-    let mut dcx = item.get(item_tag::children).decoder();
-    dcx.cdata = Some(cdata);
-
-    let fields = dcx.seq().map(|index| {
-        let f = cdata.lookup_item(index);
-        ty::FieldDefData::new(cdata.local_def_id(index),
-                              item_name(f),
-                              item_visibility(f))
-    }).collect();
-
-    (ty::VariantDefData {
-        did: cdata.local_def_id(data.struct_ctor.unwrap_or(index)),
-        name: item_name(item),
-        fields: fields,
-        disr_val: ConstInt::Infer(data.disr),
-        kind: data.kind,
-    }, data.struct_ctor)
-}
+impl<'a, 'tcx> CrateMetadata {
+    fn maybe_get(&'a self, item: rbml::Doc<'a>, tag: usize)
+                 -> Option<DecodeContext<'a, 'tcx>> {
+        item.maybe_child(tag).map(|child| {
+            DecodeContext::new(child, Some(self))
+        })
+    }
 
-pub fn get_adt_def<'a, 'tcx>(cdata: Cmd,
-                             item_id: DefIndex,
-                             tcx: TyCtxt<'a, 'tcx, 'tcx>)
-                             -> ty::AdtDefMaster<'tcx>
-{
-    let doc = cdata.lookup_item(item_id);
-    let did = cdata.local_def_id(item_id);
-    let mut ctor_index = None;
-    let family = item_family(doc);
-    let variants = if family == Family::Enum {
-        let mut dcx = doc.get(item_tag::children).decoder();
-        dcx.cdata = Some(cdata);
-
-        dcx.seq().map(|index| {
-            let (variant, struct_ctor) = get_variant(cdata, cdata.lookup_item(index), index);
-            assert_eq!(struct_ctor, None);
-            variant
-        }).collect()
-    } else{
-        let (variant, struct_ctor) = get_variant(cdata, doc, item_id);
-        ctor_index = struct_ctor;
-        vec![variant]
-    };
-    let kind = match family {
-        Family::Enum => ty::AdtKind::Enum,
-        Family::Struct => ty::AdtKind::Struct,
-        Family::Union => ty::AdtKind::Union,
-        _ => bug!("get_adt_def called on a non-ADT {:?} - {:?}",
-                  family, did)
-    };
-
-    let adt = tcx.intern_adt_def(did, kind, variants);
-    if let Some(ctor_index) = ctor_index {
-        // Make adt definition available through constructor id as well.
-        tcx.insert_adt_def(cdata.local_def_id(ctor_index), adt);
-    }
-
-    // this needs to be done *after* the variant is interned,
-    // to support recursive structures
-    for variant in &adt.variants {
-        for field in &variant.fields {
-            debug!("evaluating the type of {:?}::{:?}", variant.name, field.name);
-            let ty = get_type(cdata, field.did.index, tcx);
-            field.fulfill_ty(ty);
-            debug!("evaluating the type of {:?}::{:?}: {:?}",
-                   variant.name, field.name, ty);
+    fn get(&'a self, item: rbml::Doc<'a>, tag: usize) -> DecodeContext<'a, 'tcx> {
+        match self.maybe_get(item, tag) {
+            Some(dcx) => dcx,
+            None => bug!("failed to find child with tag {}", tag)
         }
     }
 
-    adt
-}
+    fn item_family(&self, item: rbml::Doc) -> Family {
+        self.get(item, item_tag::family).decode()
+    }
 
-pub fn get_predicates<'a, 'tcx>(cdata: Cmd,
-                                item_id: DefIndex,
-                                tcx: TyCtxt<'a, 'tcx, 'tcx>)
-                                -> ty::GenericPredicates<'tcx>
-{
-    let item_doc = cdata.lookup_item(item_id);
-    doc_predicates(item_doc, tcx, cdata, item_tag::predicates)
-}
+    fn item_visibility(&self, item: rbml::Doc) -> ty::Visibility {
+        self.get(item, item_tag::visibility).decode()
+    }
 
-pub fn get_super_predicates<'a, 'tcx>(cdata: Cmd,
-                                      item_id: DefIndex,
-                                      tcx: TyCtxt<'a, 'tcx, 'tcx>)
-                                      -> ty::GenericPredicates<'tcx>
-{
-    let item_doc = cdata.lookup_item(item_id);
-    doc_predicates(item_doc, tcx, cdata, item_tag::super_predicates)
-}
+    fn item_def_key(&self, item: rbml::Doc) -> hir_map::DefKey {
+        self.get(item, item_tag::def_key).decode()
+    }
 
-pub fn get_generics<'a, 'tcx>(cdata: Cmd,
-                              item_id: DefIndex,
-                              tcx: TyCtxt<'a, 'tcx, 'tcx>)
-                              -> &'tcx ty::Generics<'tcx>
-{
-    let item_doc = cdata.lookup_item(item_id);
-    doc_generics(item_doc, tcx, cdata)
-}
+    fn item_name(&self, item: rbml::Doc) -> ast::Name {
+        self.maybe_item_name(item).expect("no item in item_name")
+    }
 
-pub fn get_type<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>)
-                          -> Ty<'tcx>
-{
-    let item_doc = cdata.lookup_item(id);
-    doc_type(item_doc, tcx, cdata)
-}
+    fn maybe_item_name(&self, item: rbml::Doc) -> Option<ast::Name> {
+        let name = match self.item_def_key(item).disambiguated_data.data {
+            DefPathData::TypeNs(name) |
+            DefPathData::ValueNs(name) |
+            DefPathData::Module(name) |
+            DefPathData::MacroDef(name) |
+            DefPathData::TypeParam(name) |
+            DefPathData::LifetimeDef(name) |
+            DefPathData::EnumVariant(name) |
+            DefPathData::Field(name) |
+            DefPathData::Binding(name) => Some(name),
+
+            DefPathData::InlinedRoot(_) => bug!("unexpected DefPathData"),
+
+            DefPathData::CrateRoot |
+            DefPathData::Misc |
+            DefPathData::Impl |
+            DefPathData::ClosureExpr |
+            DefPathData::StructCtor |
+            DefPathData::Initializer |
+            DefPathData::ImplTrait => None
+        };
 
-pub fn get_stability(cdata: Cmd, id: DefIndex) -> Option<attr::Stability> {
-    let item = cdata.lookup_item(id);
-    reader::maybe_get_doc(item, item_tag::stability).map(|doc| {
-        doc.decoder().decode()
-    })
-}
+        name.map(|s| token::intern(&s))
+    }
 
-pub fn get_deprecation(cdata: Cmd, id: DefIndex) -> Option<attr::Deprecation> {
-    let item = cdata.lookup_item(id);
-    reader::maybe_get_doc(item, item_tag::deprecation).map(|doc| {
-        doc.decoder().decode()
-    })
-}
+    fn maybe_entry(&self, item_id: DefIndex) -> Option<rbml::Doc> {
+        self.index.lookup_item(self.data.as_slice(), item_id).map(|pos| {
+            rbml::Doc::at(self.data.as_slice(), pos as usize)
+        })
+    }
 
-pub fn get_visibility(cdata: Cmd, id: DefIndex) -> ty::Visibility {
-    item_visibility(cdata.lookup_item(id))
-}
+    fn entry(&self, item_id: DefIndex) -> rbml::Doc {
+        match self.maybe_entry(item_id) {
+            None => bug!("entry: id not found: {:?} in crate {:?} with number {}",
+                         item_id,
+                         self.name,
+                         self.cnum),
+            Some(d) => d
+        }
+    }
 
-fn get_impl_data(cdata: Cmd, id: DefIndex) -> ImplData {
-    match entry_data(cdata.lookup_item(id), cdata) {
-        EntryData::Impl(data) => data,
-        _ => bug!()
+    fn local_def_id(&self, index: DefIndex) -> DefId {
+        DefId {
+            krate: self.cnum,
+            index: index
+        }
     }
-}
 
-pub fn get_parent_impl(cdata: Cmd, id: DefIndex) -> Option<DefId> {
-    get_impl_data(cdata, id).parent_impl
-}
+    fn entry_data(&self, doc: rbml::Doc) -> EntryData {
+        self.get(doc, item_tag::data).decode()
+    }
 
-pub fn get_impl_polarity(cdata: Cmd, id: DefIndex) -> hir::ImplPolarity {
-    get_impl_data(cdata, id).polarity
-}
+    fn entry_typed_data(&self, doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>)
+                        -> EntryTypedData<'tcx> {
+        self.get(doc, item_tag::typed_data).typed(tcx).decode()
+    }
 
-pub fn get_custom_coerce_unsized_kind(
-    cdata: Cmd,
-    id: DefIndex)
-    -> Option<ty::adjustment::CustomCoerceUnsized>
-{
-    get_impl_data(cdata, id).coerce_unsized_kind
-}
+    fn item_parent_item(&self, d: rbml::Doc) -> Option<DefId> {
+        self.item_def_key(d).parent.map(|index| self.local_def_id(index))
+    }
 
-pub fn get_impl_trait<'a, 'tcx>(cdata: Cmd,
-                                id: DefIndex,
-                                tcx: TyCtxt<'a, 'tcx, 'tcx>)
-                                -> Option<ty::TraitRef<'tcx>>
-{
-    match entry_typed_data(cdata.lookup_item(id), tcx, cdata) {
-        EntryTypedData::Impl(data) => data.trait_ref,
-        _ => bug!()
+    fn doc_type(&self, doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
+        self.maybe_doc_type(doc, tcx).expect("missing item_tag::ty")
     }
-}
 
-/// Iterates over the language items in the given crate.
-pub fn get_lang_items(cdata: Cmd) -> Vec<(DefIndex, usize)> {
-    rbml::Doc::new(cdata.data()).get(root_tag::lang_items).decoder().decode()
-}
+    fn maybe_doc_type(&self, doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<Ty<'tcx>> {
+        self.maybe_get(doc, item_tag::ty).map(|dcx| dcx.typed(tcx).decode())
+    }
 
+    pub fn get_trait_def(&self,
+                         item_id: DefIndex,
+                         tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::TraitDef<'tcx> {
+        let item_doc = self.entry(item_id);
+        let generics = self.doc_generics(item_doc, tcx);
 
-/// Iterates over each child of the given item.
-pub fn each_child_of_item<F, G>(cdata: Cmd, id: DefIndex,
-                                mut get_crate_data: &mut G,
-                                mut callback: &mut F)
-    where F: FnMut(Def, ast::Name, ty::Visibility),
-          G: FnMut(CrateNum) -> Rc<CrateMetadata>,
-{
-    // Find the item.
-    let item_doc = match cdata.get_item(id) {
-        None => return,
-        Some(item_doc) => item_doc,
-    };
-
-    let mut dcx = match reader::maybe_get_doc(item_doc, item_tag::children) {
-        Some(doc) => doc.decoder(),
-        None => return
-    };
-    dcx.cdata = Some(cdata);
-
-    // Iterate over all children.
-    for child_index in dcx.seq::<DefIndex>() {
-        // Get the item.
-        if let Some(child) = cdata.get_item(child_index) {
-            // Hand off the item to the callback.
-            let family = item_family(child);
-            if let Family::ForeignMod = family {
-                each_child_of_item(cdata, child_index, get_crate_data, callback);
-            } else if let Some(def) = family.to_def(cdata.local_def_id(child_index)) {
-                callback(def, item_name(child), item_visibility(child));
-            }
-        }
+        let data = match self.entry_data(item_doc) {
+            EntryData::Trait(data) => data,
+            _ => bug!()
+        };
+        let typed_data = match self.entry_typed_data(item_doc, tcx) {
+            EntryTypedData::Trait(data) => data,
+            _ => bug!()
+        };
+
+        ty::TraitDef::new(data.unsafety, data.paren_sugar, generics, typed_data.trait_ref,
+                          self.def_path(item_id).unwrap().deterministic_hash(tcx)))
     }
 
-    let reexports = match entry_data(item_doc, cdata) {
-        EntryData::Mod(data) => data.reexports,
-        _ => return
-    };
-    for exp in reexports {
-        // This reexport may be in yet another crate.
-        let crate_data = if exp.def_id.krate == cdata.cnum {
-            None
-        } else {
-            Some(get_crate_data(exp.def_id.krate))
+    fn get_variant(&self, item: rbml::Doc, index: DefIndex)
+                  -> (ty::VariantDefData<'tcx, 'tcx>, Option<DefIndex>) {
+        let data = match self.entry_data(item) {
+            EntryData::Variant(data) => data,
+            _ => bug!()
         };
-        let crate_data = match crate_data {
-            Some(ref cdata) => &**cdata,
-            None => cdata
+
+        let fields = self.get(item, item_tag::children).seq().map(|index| {
+            let f = self.entry(index);
+            ty::FieldDefData::new(self.local_def_id(index),
+                                  self.item_name(f),
+                                  self.item_visibility(f))
+        }).collect();
+
+        (ty::VariantDefData {
+            did: self.local_def_id(data.struct_ctor.unwrap_or(index)),
+            name: self.item_name(item),
+            fields: fields,
+            disr_val: ConstInt::Infer(data.disr),
+            kind: data.kind,
+        }, data.struct_ctor)
+    }
+
+    pub fn get_adt_def(&self, item_id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>)
+                       -> ty::AdtDefMaster<'tcx> {
+        let doc = self.entry(item_id);
+        let did = self.local_def_id(item_id);
+        let mut ctor_index = None;
+        let family = self.item_family(doc);
+        let variants = if family == Family::Enum {
+            self.get(doc, item_tag::children).seq().map(|index| {
+                let (variant, struct_ctor) = self.get_variant(self.entry(index), index);
+                assert_eq!(struct_ctor, None);
+                variant
+            }).collect()
+        } else{
+            let (variant, struct_ctor) = self.get_variant(doc, item_id);
+            ctor_index = struct_ctor;
+            vec![variant]
+        };
+        let kind = match family {
+            Family::Enum => ty::AdtKind::Enum,
+            Family::Struct => ty::AdtKind::Struct,
+            Family::Union => ty::AdtKind::Union,
+            _ => bug!("get_adt_def called on a non-ADT {:?} - {:?}",
+                      family, did)
         };
 
-        // Get the item.
-        if let Some(child) = crate_data.get_item(exp.def_id.index) {
-            // Hand off the item to the callback.
-            if let Some(def) = item_family(child).to_def(exp.def_id) {
-                // These items have a public visibility because they're part of
-                // a public re-export.
-                callback(def, exp.name, ty::Visibility::Public);
+        let adt = tcx.intern_adt_def(did, kind, variants);
+        if let Some(ctor_index) = ctor_index {
+            // Make adt definition available through constructor id as well.
+            tcx.insert_adt_def(self.local_def_id(ctor_index), adt);
+        }
+
+        // this needs to be done *after* the variant is interned,
+        // to support recursive structures
+        for variant in &adt.variants {
+            for field in &variant.fields {
+                debug!("evaluating the type of {:?}::{:?}", variant.name, field.name);
+                let ty = self.get_type(field.did.index, tcx);
+                field.fulfill_ty(ty);
+                debug!("evaluating the type of {:?}::{:?}: {:?}",
+                       variant.name, field.name, ty);
             }
         }
+
+        adt
     }
-}
 
-pub fn maybe_get_item_name(cdata: Cmd, id: DefIndex) -> Option<ast::Name> {
-    maybe_item_name(cdata.lookup_item(id))
-}
+    pub fn get_predicates(&self, item_id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>)
+                          -> ty::GenericPredicates<'tcx> {
+        self.doc_predicates(self.entry(item_id), tcx, item_tag::predicates)
+    }
 
-pub fn maybe_get_item_ast<'a, 'tcx>(cdata: Cmd, tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefIndex)
-                                    -> Option<&'tcx InlinedItem> {
-    debug!("Looking up item: {:?}", id);
-    let item_doc = cdata.lookup_item(id);
-    let item_did = cdata.local_def_id(id);
-    let parent_def_id = cdata.local_def_id(def_key(cdata, id).parent.unwrap());
-    let mut parent_def_path = def_path(cdata, id).unwrap();
-    parent_def_path.data.pop();
-    reader::maybe_get_doc(item_doc, item_tag::ast).map(|ast_doc| {
-        decode_inlined_item(cdata, tcx, parent_def_path, parent_def_id, ast_doc, item_did)
-    })
-}
+    pub fn get_super_predicates(&self, item_id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>)
+                                -> ty::GenericPredicates<'tcx> {
+        self.doc_predicates(self.entry(item_id), tcx, item_tag::super_predicates)
+    }
 
-pub fn is_item_mir_available<'tcx>(cdata: Cmd, id: DefIndex) -> bool {
-    if let Some(item_doc) = cdata.get_item(id) {
-        return reader::maybe_get_doc(item_doc, item_tag::mir as usize).is_some();
+    pub fn get_generics(&self, item_id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>)
+                        -> &'tcx ty::Generics<'tcx> {
+        self.doc_generics(self.entry(item_id), tcx)
     }
 
-    false
-}
+    pub fn get_type(&self, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
+        self.doc_type(self.entry(id), tcx)
+    }
 
-pub fn maybe_get_item_mir<'a, 'tcx>(cdata: Cmd,
-                                    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                    id: DefIndex)
-                                    -> Option<Mir<'tcx>> {
-    let item_doc = cdata.lookup_item(id);
-
-    reader::maybe_get_doc(item_doc, item_tag::mir).map(|mir_doc| {
-        let mut dcx = mir_doc.decoder();
-        dcx.tcx = Some(tcx);
-        dcx.cdata = Some(cdata);
-        dcx.decode()
-    })
-}
+    pub fn get_stability(&self, id: DefIndex) -> Option<attr::Stability> {
+        self.maybe_get(self.entry(id), item_tag::stability).map(|mut dcx| {
+            dcx.decode()
+        })
+    }
 
-pub fn get_impl_or_trait_item<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>)
-                                        -> Option<ty::ImplOrTraitItem<'tcx>> {
-    let item_doc = cdata.lookup_item(id);
-    let family = item_family(item_doc);
+    pub fn get_deprecation(&self, id: DefIndex) -> Option<attr::Deprecation> {
+        self.maybe_get(self.entry(id), item_tag::deprecation).map(|mut dcx| {
+            dcx.decode()
+        })
+    }
 
-    match family {
-        Family::AssociatedConst |
-        Family::Method |
-        Family::AssociatedType => {}
+    pub fn get_visibility(&self, id: DefIndex) -> ty::Visibility {
+        self.item_visibility(self.entry(id))
+    }
 
-        _ => return None
+    fn get_impl_data(&self, id: DefIndex) -> ImplData {
+        match self.entry_data(self.entry(id)) {
+            EntryData::Impl(data) => data,
+            _ => bug!()
+        }
     }
 
-    let def_id = cdata.local_def_id(id);
+    pub fn get_parent_impl(&self, id: DefIndex) -> Option<DefId> {
+        self.get_impl_data(id).parent_impl
+    }
 
-    let container_id = item_parent_item(cdata, item_doc).unwrap();
-    let container = match item_family(cdata.lookup_item(container_id.index)) {
-        Family::Trait => TraitContainer(container_id),
-        _ => ImplContainer(container_id),
-    };
+    pub fn get_impl_polarity(&self, id: DefIndex) -> hir::ImplPolarity {
+        self.get_impl_data(id).polarity
+    }
 
-    let name = item_name(item_doc);
-    let vis = item_visibility(item_doc);
+    pub fn get_custom_coerce_unsized_kind(&self, id: DefIndex)
+                                          -> Option<ty::adjustment::CustomCoerceUnsized> {
+        self.get_impl_data(id).coerce_unsized_kind
+    }
 
-    let (defaultness, has_body) = match entry_data(item_doc, cdata) {
-        EntryData::TraitAssociated(data) => {
-            (hir::Defaultness::Default, data.has_default)
+    pub fn get_impl_trait(&self,
+                          id: DefIndex,
+                          tcx: TyCtxt<'a, 'tcx, 'tcx>)
+                          -> Option<ty::TraitRef<'tcx>> {
+        match self.entry_typed_data(self.entry(id), tcx) {
+            EntryTypedData::Impl(data) => data.trait_ref,
+            _ => bug!()
         }
-        EntryData::ImplAssociated(data) => {
-            (data.defaultness, true)
-        }
-        _ => bug!()
-    };
+    }
 
-    Some(match family {
-        Family::AssociatedConst => {
-            let ty = doc_type(item_doc, tcx, cdata);
-            ty::ConstTraitItem(Rc::new(ty::AssociatedConst {
-                name: name,
-                ty: ty,
-                vis: vis,
-                defaultness: defaultness,
-                def_id: def_id,
-                container: container,
-                has_value: has_body,
-            }))
+    /// Iterates over the language items in the given crate.
+    pub fn get_lang_items(&self) -> Vec<(DefIndex, usize)> {
+        self.get(self.data.root(), root_tag::lang_items).decode()
+    }
+
+    /// Iterates over each child of the given item.
+    pub fn each_child_of_item<F, G>(&self, id: DefIndex,
+                                    mut get_crate_data: &mut G,
+                                    mut callback: &mut F)
+        where F: FnMut(Def, ast::Name, ty::Visibility),
+              G: FnMut(CrateNum) -> Rc<CrateMetadata>,
+    {
+        // Find the item.
+        let item_doc = match self.maybe_entry(id) {
+            None => return,
+            Some(item_doc) => item_doc,
+        };
+
+        let dcx = match self.maybe_get(item_doc, item_tag::children) {
+            Some(dcx) => dcx,
+            None => return
+        };
+
+        // Iterate over all children.
+        for child_index in dcx.seq::<DefIndex>() {
+            // Get the item.
+            if let Some(child) = self.maybe_entry(child_index) {
+                // Hand off the item to the callback.
+                let family = self.item_family(child);
+                if let Family::ForeignMod = family {
+                    self.each_child_of_item(child_index, get_crate_data, callback);
+                } else if let Some(def) = family.to_def(self.local_def_id(child_index)) {
+                    callback(def, self.item_name(child), self.item_visibility(child));
+                }
+            }
         }
-        Family::Method => {
-            let generics = doc_generics(item_doc, tcx, cdata);
-            let predicates = doc_predicates(item_doc, tcx, cdata, item_tag::predicates);
-            let ity = tcx.lookup_item_type(def_id).ty;
-            let fty = match ity.sty {
-                ty::TyFnDef(.., fty) => fty,
-                _ => bug!(
-                    "the type {:?} of the method {:?} is not a function?",
-                    ity, name)
-            };
 
-            let explicit_self = match entry_typed_data(item_doc, tcx, cdata) {
-                EntryTypedData::Method(data) => data.explicit_self,
-                _ => bug!()
+        let reexports = match self.entry_data(item_doc) {
+            EntryData::Mod(data) => data.reexports,
+            _ => return
+        };
+        for exp in reexports {
+            // This reexport may be in yet another crate.
+            let crate_data = if exp.def_id.krate == self.cnum {
+                None
+            } else {
+                Some(get_crate_data(exp.def_id.krate))
             };
-            ty::MethodTraitItem(Rc::new(ty::Method {
-                name: name,
-                generics: generics,
-                predicates: predicates,
-                fty: fty,
-                explicit_self: explicit_self,
-                vis: vis,
-                defaultness: defaultness,
-                has_body: has_body,
-                def_id: def_id,
-                container: container,
-            }))
-        }
-        Family::AssociatedType => {
-            let ty = maybe_doc_type(item_doc, tcx, cdata);
-            ty::TypeTraitItem(Rc::new(ty::AssociatedType {
-                name: name,
-                ty: ty,
-                vis: vis,
-                defaultness: defaultness,
-                def_id: def_id,
-                container: container,
-            }))
+            let crate_data = match crate_data {
+                Some(ref cdata) => &**cdata,
+                None => self
+            };
+
+            // Get the item.
+            if let Some(child) = crate_data.maybe_entry(exp.def_id.index) {
+                // Hand off the item to the callback.
+                if let Some(def) = self.item_family(child).to_def(exp.def_id) {
+                    // These items have a public visibility because they're part of
+                    // a public re-export.
+                    callback(def, exp.name, ty::Visibility::Public);
+                }
+            }
         }
-        _ => bug!()
-    })
-}
+    }
 
-pub fn get_item_variances(cdata: Cmd, id: DefIndex) -> Vec<ty::Variance> {
-    let item_doc = cdata.lookup_item(id);
-    item_doc.get(item_tag::variances).decoder().decode()
-}
+    pub fn maybe_get_item_name(&self, id: DefIndex) -> Option<ast::Name> {
+        self.maybe_item_name(self.entry(id))
+    }
 
-pub fn get_struct_ctor_def_id(cdata: Cmd, node_id: DefIndex) -> Option<DefId>
-{
-    let data = match entry_data(cdata.lookup_item(node_id), cdata) {
-        EntryData::Variant(data) => data,
-        _ => bug!()
-    };
+    pub fn maybe_get_item_ast(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefIndex)
+                              -> Option<&'tcx InlinedItem> {
+        debug!("Looking up item: {:?}", id);
+        let item_doc = self.entry(id);
+        let item_did = self.local_def_id(id);
+        let parent_def_id = self.local_def_id(self.def_key(id).parent.unwrap());
+        let mut parent_def_path = self.def_path(id).unwrap();
+        parent_def_path.data.pop();
+        item_doc.maybe_child(item_tag::ast).map(|ast_doc| {
+            decode_inlined_item(self, tcx, parent_def_path, parent_def_id, ast_doc, item_did)
+        })
+    }
 
-    data.struct_ctor.map(|index| cdata.local_def_id(index))
-}
+    pub fn is_item_mir_available(&self, id: DefIndex) -> bool {
+        if let Some(item_doc) = self.maybe_entry(id) {
+            return item_doc.maybe_child(item_tag::mir).is_some();
+        }
 
-pub fn get_item_attrs(cdata: Cmd,
-                      node_id: DefIndex)
-                      -> Vec<ast::Attribute> {
-    // The attributes for a tuple struct are attached to the definition, not the ctor;
-    // we assume that someone passing in a tuple struct ctor is actually wanting to
-    // look at the definition
-    let mut item = cdata.lookup_item(node_id);
-    let def_key = item_def_key(item);
-    if def_key.disambiguated_data.data == DefPathData::StructCtor {
-        item = cdata.lookup_item(def_key.parent.unwrap());
-    }
-    get_attributes(item)
-}
+        false
+    }
 
-pub fn get_struct_field_names(cdata: Cmd, id: DefIndex) -> Vec<ast::Name> {
-    let mut dcx = cdata.lookup_item(id).get(item_tag::children).decoder();
-    dcx.cdata = Some(cdata);
+    pub fn maybe_get_item_mir(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefIndex)
+                              -> Option<Mir<'tcx>> {
+        self.maybe_get(self.entry(id), item_tag::mir).map(|dcx| {
+            dcx.typed(tcx).decode()
+        })
+    }
 
-    dcx.seq().map(|index| item_name(cdata.lookup_item(index))).collect()
-}
+    pub fn get_impl_or_trait_item(&self, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>)
+                                  -> Option<ty::ImplOrTraitItem<'tcx>> {
+        let item_doc = self.entry(id);
+        let family = self.item_family(item_doc);
 
-fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
-    reader::maybe_get_doc(md, item_tag::attributes).map_or(vec![], |attrs_doc| {
-        let mut attrs = attrs_doc.decoder().decode::<Vec<ast::Attribute>>();
+        match family {
+            Family::AssociatedConst |
+            Family::Method |
+            Family::AssociatedType => {}
 
-        // Need new unique IDs: old thread-local IDs won't map to new threads.
-        for attr in attrs.iter_mut() {
-            attr.node.id = attr::mk_attr_id();
+            _ => return None
         }
 
-        attrs
-    })
-}
+        let def_id = self.local_def_id(id);
 
-#[derive(Clone)]
-pub struct CrateDep {
-    pub cnum: CrateNum,
-    pub name: String,
-    pub hash: Svh,
-    pub explicitly_linked: bool,
-}
+        let container_id = self.item_parent_item(item_doc).unwrap();
+        let container = match self.item_family(self.entry(container_id.index)) {
+            Family::Trait => TraitContainer(container_id),
+            _ => ImplContainer(container_id),
+        };
 
-pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> {
-    let dcx = rbml::Doc::new(data).get(root_tag::crate_deps).decoder();
+        let name = self.item_name(item_doc);
+        let vis = self.item_visibility(item_doc);
 
-    dcx.seq().enumerate().map(|(crate_num, (name, hash, explicitly_linked))| {
-        CrateDep {
-            cnum: CrateNum::new(crate_num + 1),
-            name: name,
-            hash: hash,
-            explicitly_linked: explicitly_linked,
-        }
-    }).collect()
-}
+        let (defaultness, has_body) = match self.entry_data(item_doc) {
+            EntryData::TraitAssociated(data) => {
+                (hir::Defaultness::Default, data.has_default)
+            }
+            EntryData::ImplAssociated(data) => {
+                (data.defaultness, true)
+            }
+            _ => bug!()
+        };
 
-fn list_crate_deps(data: &[u8], out: &mut io::Write) -> io::Result<()> {
-    write!(out, "=External Dependencies=\n")?;
-    for dep in &get_crate_deps(data) {
-        write!(out, "{} {}-{}\n", dep.cnum, dep.name, dep.hash)?;
+        Some(match family {
+            Family::AssociatedConst => {
+                ty::ConstTraitItem(Rc::new(ty::AssociatedConst {
+                    name: name,
+                    ty: self.doc_type(item_doc, tcx),
+                    vis: vis,
+                    defaultness: defaultness,
+                    def_id: def_id,
+                    container: container,
+                    has_value: has_body,
+                }))
+            }
+            Family::Method => {
+                let generics = self.doc_generics(item_doc, tcx);
+                let predicates = self.doc_predicates(item_doc, tcx, item_tag::predicates);
+                let ity = tcx.lookup_item_type(def_id).ty;
+                let fty = match ity.sty {
+                    ty::TyFnDef(.., fty) => fty,
+                    _ => bug!(
+                        "the type {:?} of the method {:?} is not a function?",
+                        ity, name)
+                };
+
+                let explicit_self = match self.entry_typed_data(item_doc, tcx) {
+                    EntryTypedData::Method(data) => data.explicit_self,
+                    _ => bug!()
+                };
+                ty::MethodTraitItem(Rc::new(ty::Method {
+                    name: name,
+                    generics: generics,
+                    predicates: predicates,
+                    fty: fty,
+                    explicit_self: explicit_self,
+                    vis: vis,
+                    defaultness: defaultness,
+                    has_body: has_body,
+                    def_id: def_id,
+                    container: container,
+                }))
+            }
+            Family::AssociatedType => {
+                ty::TypeTraitItem(Rc::new(ty::AssociatedType {
+                    name: name,
+                    ty: self.maybe_doc_type(item_doc, tcx),
+                    vis: vis,
+                    defaultness: defaultness,
+                    def_id: def_id,
+                    container: container,
+                }))
+            }
+            _ => bug!()
+        })
     }
-    write!(out, "\n")?;
-    Ok(())
-}
 
-pub fn get_crate_info(data: &[u8]) -> CrateInfo {
-    rbml::Doc::new(data).get(root_tag::crate_info).decoder().decode()
-}
+    pub fn get_item_variances(&self, id: DefIndex) -> Vec<ty::Variance> {
+        let item_doc = self.entry(id);
+        self.get(item_doc, item_tag::variances).decode()
+    }
 
-pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Write) -> io::Result<()> {
-    list_crate_deps(bytes, out)
-}
+    pub fn get_struct_ctor_def_id(&self, node_id: DefIndex) -> Option<DefId> {
+        let data = match self.entry_data(self.entry(node_id)) {
+            EntryData::Variant(data) => data,
+            _ => bug!()
+        };
 
-// Translate a DefId from the current compilation environment to a DefId
-// for an external crate.
-fn reverse_translate_def_id(cdata: Cmd, did: DefId) -> Option<DefId> {
-    for (local, &global) in cdata.cnum_map.borrow().iter_enumerated() {
-        if global == did.krate {
-            return Some(DefId { krate: local, index: did.index });
+        data.struct_ctor.map(|index| self.local_def_id(index))
+    }
+
+    pub fn get_item_attrs(&self, node_id: DefIndex) -> Vec<ast::Attribute> {
+        // The attributes for a tuple struct are attached to the definition, not the ctor;
+        // we assume that someone passing in a tuple struct ctor is actually wanting to
+        // look at the definition
+        let mut item = self.entry(node_id);
+        let def_key = self.item_def_key(item);
+        if def_key.disambiguated_data.data == DefPathData::StructCtor {
+            item = self.entry(def_key.parent.unwrap());
         }
+        self.get_attributes(item)
     }
 
-    None
-}
+    pub fn get_struct_field_names(&self, id: DefIndex) -> Vec<ast::Name> {
+        self.get(self.entry(id), item_tag::children).seq().map(|index| {
+            self.item_name(self.entry(index))
+        }).collect()
+    }
+
+    fn get_attributes(&self, md: rbml::Doc) -> Vec<ast::Attribute> {
+        self.maybe_get(md, item_tag::attributes).map_or(vec![], |mut dcx| {
+            let mut attrs = dcx.decode::<Vec<ast::Attribute>>();
 
-pub fn each_inherent_implementation_for_type<F>(cdata: Cmd,
-                                                id: DefIndex,
-                                                mut callback: F)
-    where F: FnMut(DefId),
-{
-    let item_doc = cdata.lookup_item(id);
-    let mut dcx = item_doc.get(item_tag::inherent_impls).decoder();
-    dcx.cdata = Some(cdata);
+            // Need new unique IDs: old thread-local IDs won't map to new threads.
+            for attr in attrs.iter_mut() {
+                attr.node.id = attr::mk_attr_id();
+            }
 
-    for impl_def_id in dcx.seq() {
-        callback(impl_def_id);
+            attrs
+        })
     }
-}
 
-pub fn each_implementation_for_trait<F>(cdata: Cmd,
-                                        filter: Option<DefId>,
-                                        mut callback: F) where
-    F: FnMut(DefId),
-{
-    // Do a reverse lookup beforehand to avoid touching the crate_num
-    // hash map in the loop below.
-    let filter = match filter.map(|def_id| reverse_translate_def_id(cdata, def_id)) {
-        Some(Some(def_id)) => Some(def_id),
-        Some(None) => return,
-        None => None
-    };
-
-    // FIXME(eddyb) Make this O(1) instead of O(n).
-    for trait_doc in rbml::Doc::new(cdata.data()).get(root_tag::impls).children() {
-        let mut dcx = trait_doc.decoder();
-        dcx.cdata = Some(cdata);
-
-        let (krate, index) = dcx.decode();
-        if let Some(local_did) = filter {
-            if (local_did.krate.as_u32(), local_did.index) != (krate, index) {
-                continue;
+    // Translate a DefId from the current compilation environment to a DefId
+    // for an external crate.
+    fn reverse_translate_def_id(&self, did: DefId) -> Option<DefId> {
+        for (local, &global) in self.cnum_map.borrow().iter_enumerated() {
+            if global == did.krate {
+                return Some(DefId { krate: local, index: did.index });
             }
         }
 
-        for impl_def_id in dcx.seq() {
+        None
+    }
+
+    pub fn each_inherent_implementation_for_type<F>(&self, id: DefIndex, mut callback: F)
+        where F: FnMut(DefId),
+    {
+        for impl_def_id in self.get(self.entry(id), item_tag::inherent_impls).seq() {
             callback(impl_def_id);
         }
     }
-}
 
-pub fn get_trait_of_item(cdata: Cmd, id: DefIndex) -> Option<DefId> {
-    let item_doc = cdata.lookup_item(id);
-    let parent_item_id = match item_parent_item(cdata, item_doc) {
-        None => return None,
-        Some(item_id) => item_id,
-    };
-    match item_family(cdata.lookup_item(parent_item_id.index)) {
-        Family::Trait => Some(parent_item_id),
-        _ => None
-    }
-}
+    pub fn each_implementation_for_trait<F>(&self,
+                                            filter: Option<DefId>,
+                                            mut callback: F) where
+        F: FnMut(DefId),
+    {
+        // Do a reverse lookup beforehand to avoid touching the crate_num
+        // hash map in the loop below.
+        let filter = match filter.map(|def_id| self.reverse_translate_def_id(def_id)) {
+            Some(Some(def_id)) => Some(def_id),
+            Some(None) => return,
+            None => None
+        };
 
+        // FIXME(eddyb) Make this O(1) instead of O(n).
+        for trait_doc in self.data.root().children_of(root_tag::impls) {
+            let mut dcx = DecodeContext::new(trait_doc, Some(self));
 
-pub fn get_native_libraries(cdata: Cmd)
-                            -> Vec<(cstore::NativeLibraryKind, String)> {
-    rbml::Doc::new(cdata.data()).get(root_tag::native_libraries).decoder().decode()
-}
+            let (krate, index) = dcx.decode();
+            if let Some(local_did) = filter {
+                if (local_did.krate.as_u32(), local_did.index) != (krate, index) {
+                    continue;
+                }
+            }
 
-pub fn each_exported_macro<F>(data: &[u8], mut f: F) where
-    F: FnMut(ast::Name, Vec<ast::Attribute>, Span, String) -> bool,
-{
-    let dcx = rbml::Doc::new(data).get(root_tag::macro_defs).decoder();
-    for (name, attrs, span, body) in dcx.seq() {
-        if !f(name, attrs, span, body) {
-            break;
+            for impl_def_id in dcx.seq() {
+                callback(impl_def_id);
+            }
         }
     }
-}
 
-pub fn get_dylib_dependency_formats(cdata: Cmd)
-    -> Vec<(CrateNum, LinkagePreference)>
-{
-    let dcx = rbml::Doc::new(cdata.data()).get(root_tag::dylib_dependency_formats).decoder();
-
-    dcx.seq::<Option<_>>().enumerate().flat_map(|(i, link)| {
-        let cnum = CrateNum::new(i + 1);
-        link.map(|link| (cdata.cnum_map.borrow()[cnum], link))
-    }).collect()
-}
+    pub fn get_trait_of_item(&self, id: DefIndex) -> Option<DefId> {
+        let item_doc = self.entry(id);
+        let parent_item_id = match self.item_parent_item(item_doc) {
+            None => return None,
+            Some(item_id) => item_id,
+        };
+        match self.item_family(self.entry(parent_item_id.index)) {
+            Family::Trait => Some(parent_item_id),
+            _ => None
+        }
+    }
 
-pub fn get_missing_lang_items(cdata: Cmd) -> Vec<lang_items::LangItem> {
-    rbml::Doc::new(cdata.data()).get(root_tag::lang_items_missing).decoder().decode()
-}
 
-pub fn get_fn_arg_names(cdata: Cmd, id: DefIndex) -> Vec<String> {
-    let method_doc = cdata.lookup_item(id);
-    match reader::maybe_get_doc(method_doc, item_tag::fn_arg_names) {
-        Some(args_doc) => args_doc.decoder().decode(),
-        None => vec![],
+    pub fn get_native_libraries(&self) -> Vec<(NativeLibraryKind, String)> {
+        self.get(self.data.root(), root_tag::native_libraries).decode()
     }
-}
 
-pub fn get_reachable_ids(cdata: Cmd) -> Vec<DefId> {
-    let dcx = rbml::Doc::new(cdata.data()).get(root_tag::reachable_ids).decoder();
+    pub fn get_dylib_dependency_formats(&self) -> Vec<(CrateNum, LinkagePreference)> {
+        let dcx = self.get(self.data.root(), root_tag::dylib_dependency_formats);
 
-    dcx.seq().map(|index| cdata.local_def_id(index)).collect()
-}
+        dcx.seq::<Option<_>>().enumerate().flat_map(|(i, link)| {
+            let cnum = CrateNum::new(i + 1);
+            link.map(|link| (self.cnum_map.borrow()[cnum], link))
+        }).collect()
+    }
 
-pub fn is_const_fn(cdata: Cmd, id: DefIndex) -> bool {
-    let constness = match entry_data(cdata.lookup_item(id), cdata) {
-        EntryData::ImplAssociated(data) => data.constness,
-        EntryData::Fn(data) => data.constness,
-        _ => hir::Constness::NotConst
-    };
-    constness == hir::Constness::Const
-}
+    pub fn get_missing_lang_items(&self) -> Vec<lang_items::LangItem> {
+        self.get(self.data.root(), root_tag::lang_items_missing).decode()
+    }
 
-pub fn is_extern_item<'a, 'tcx>(cdata: Cmd,
-                                id: DefIndex,
-                                tcx: TyCtxt<'a, 'tcx, 'tcx>)
-                                -> bool {
-    let item_doc = match cdata.get_item(id) {
-        Some(doc) => doc,
-        None => return false,
-    };
-    let applicable = match item_family(item_doc) {
-        Family::ImmStatic |
-        Family::MutStatic |
-        Family::ForeignImmStatic |
-        Family::ForeignMutStatic => true,
-
-        Family::Fn | Family::ForeignFn => {
-            get_generics(cdata, id, tcx).types.is_empty()
-        }
+    pub fn get_fn_arg_names(&self, id: DefIndex) -> Vec<String> {
+        self.maybe_get(self.entry(id), item_tag::fn_arg_names)
+            .map_or(vec![], |mut dcx| dcx.decode())
+    }
 
-        _ => false,
-    };
+    pub fn get_reachable_ids(&self) -> Vec<DefId> {
+        let dcx = self.get(self.data.root(), root_tag::reachable_ids);
 
-    if applicable {
-        attr::contains_extern_indicator(tcx.sess.diagnostic(),
-                                        &get_attributes(item_doc))
-    } else {
-        false
+        dcx.seq().map(|index| self.local_def_id(index)).collect()
     }
-}
 
-pub fn is_foreign_item(cdata: Cmd, id: DefIndex) -> bool {
-    match item_family(cdata.lookup_item(id)) {
-        Family::ForeignImmStatic |
-        Family::ForeignMutStatic |
-        Family::ForeignFn => true,
-        _ => false
+    pub fn is_const_fn(&self, id: DefIndex) -> bool {
+        let constness = match self.entry_data(self.entry(id)) {
+            EntryData::ImplAssociated(data) => data.constness,
+            EntryData::Fn(data) => data.constness,
+            _ => hir::Constness::NotConst
+        };
+        constness == hir::Constness::Const
     }
-}
-
-fn doc_generics<'a, 'tcx>(base_doc: rbml::Doc,
-                          tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                          cdata: Cmd)
-                          -> &'tcx ty::Generics<'tcx>
-{
-    let mut dcx = base_doc.get(item_tag::generics).decoder();
-    dcx.tcx = Some(tcx);
-    dcx.cdata = Some(cdata);
-    tcx.alloc_generics(dcx.decode())
-}
 
-fn doc_predicates<'a, 'tcx>(base_doc: rbml::Doc,
-                            tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                            cdata: Cmd,
-                            tag: usize)
-                            -> ty::GenericPredicates<'tcx>
-{
-    let mut dcx = base_doc.get(tag).decoder();
-    dcx.cdata = Some(cdata);
-    dcx.tcx = Some(tcx);
-
-    ty::GenericPredicates {
-        parent: dcx.decode(),
-        predicates: (0..dcx.decode::<usize>()).map(|_| {
-            // Handle shorthands first, if we have an usize > 0x80.
-            if dcx.opaque.data[dcx.opaque.position()] & 0x80 != 0 {
-                let pos = dcx.decode::<usize>();
-                assert!(pos >= SHORTHAND_OFFSET);
-                let pos = pos - SHORTHAND_OFFSET;
-
-                let mut dcx = rbml::Doc {
-                    data: cdata.data(),
-                    start: pos,
-                    end: cdata.data().len(),
-                }.decoder();
-                dcx.tcx = Some(tcx);
-                dcx.cdata = Some(cdata);
-                dcx.decode()
-            } else {
-                dcx.decode()
+    pub fn is_extern_item(&self, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool {
+        let item_doc = match self.maybe_entry(id) {
+            Some(doc) => doc,
+            None => return false,
+        };
+        let applicable = match self.item_family(item_doc) {
+            Family::ImmStatic |
+            Family::MutStatic |
+            Family::ForeignImmStatic |
+            Family::ForeignMutStatic => true,
+
+            Family::Fn | Family::ForeignFn => {
+                self.get_generics(id, tcx).types.is_empty()
             }
-        }).collect()
+
+            _ => false,
+        };
+
+        if applicable {
+            attr::contains_extern_indicator(tcx.sess.diagnostic(),
+                                            &self.get_attributes(item_doc))
+        } else {
+            false
+        }
     }
-}
 
-pub fn is_defaulted_trait(cdata: Cmd, trait_id: DefIndex) -> bool {
-    match entry_data(cdata.lookup_item(trait_id), cdata) {
-        EntryData::Trait(data) => data.has_default_impl,
-        _ => bug!()
+    pub fn is_foreign_item(&self, id: DefIndex) -> bool {
+        match self.item_family(self.entry(id)) {
+            Family::ForeignImmStatic |
+            Family::ForeignMutStatic |
+            Family::ForeignFn => true,
+            _ => false
+        }
     }
-}
 
-pub fn is_default_impl(cdata: Cmd, impl_id: DefIndex) -> bool {
-    item_family(cdata.lookup_item(impl_id)) == Family::DefaultImpl
-}
+    fn doc_generics(&self, base_doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>)
+                    -> &'tcx ty::Generics<'tcx> {
+        let generics = self.get(base_doc, item_tag::generics).typed(tcx).decode();
+        tcx.alloc_generics(generics)
+    }
 
-pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<syntax_pos::FileMap> {
-    rbml::Doc::new(metadata).get(root_tag::codemap).decoder().decode()
-}
+    fn doc_predicates(&self, base_doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, tag: usize)
+                      -> ty::GenericPredicates<'tcx> {
+        let mut dcx = self.get(base_doc, tag).typed(tcx);
+
+        ty::GenericPredicates {
+            parent: dcx.decode(),
+            predicates: (0..dcx.decode::<usize>()).map(|_| {
+                // Handle shorthands first, if we have an usize > 0x80.
+                if dcx.opaque.data[dcx.opaque.position()] & 0x80 != 0 {
+                    let pos = dcx.decode::<usize>();
+                    assert!(pos >= SHORTHAND_OFFSET);
+                    let pos = pos - SHORTHAND_OFFSET;
+
+                    let data = self.data.as_slice();
+                    let doc = rbml::Doc {
+                        data: data,
+                        start: pos,
+                        end: data.len(),
+                    };
+                    DecodeContext::new(doc, Some(self)).typed(tcx).decode()
+                } else {
+                    dcx.decode()
+                }
+            }).collect()
+        }
+    }
 
-pub fn closure_kind(cdata: Cmd, closure_id: DefIndex) -> ty::ClosureKind {
-    match entry_data(cdata.lookup_item(closure_id), cdata) {
-        EntryData::Closure(data) => data.kind,
-        _ => bug!()
+    pub fn is_defaulted_trait(&self, trait_id: DefIndex) -> bool {
+        match self.entry_data(self.entry(trait_id)) {
+            EntryData::Trait(data) => data.has_default_impl,
+            _ => bug!()
+        }
     }
-}
 
-pub fn closure_ty<'a, 'tcx>(cdata: Cmd, closure_id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>)
-                            -> ty::ClosureTy<'tcx> {
-    match entry_typed_data(cdata.lookup_item(closure_id), tcx, cdata) {
-        EntryTypedData::Closure(data) => data.ty,
-        _ => bug!()
+    pub fn is_default_impl(&self, impl_id: DefIndex) -> bool {
+        self.item_family(self.entry(impl_id)) == Family::DefaultImpl
     }
-}
 
-pub fn def_key(cdata: Cmd, id: DefIndex) -> hir_map::DefKey {
-    debug!("def_key: id={:?}", id);
-    item_def_key(cdata.lookup_item(id))
-}
+    pub fn closure_kind(&self, closure_id: DefIndex) -> ty::ClosureKind {
+        match self.entry_data(self.entry(closure_id)) {
+            EntryData::Closure(data) => data.kind,
+            _ => bug!()
+        }
+    }
 
-fn item_def_key(item_doc: rbml::Doc) -> hir_map::DefKey {
-    item_doc.get(item_tag::def_key).decoder().decode()
-}
+    pub fn closure_ty(&self, closure_id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>)
+                      -> ty::ClosureTy<'tcx> {
+        match self.entry_typed_data(self.entry(closure_id), tcx) {
+            EntryTypedData::Closure(data) => data.ty,
+            _ => bug!()
+        }
+    }
 
-// Returns the path leading to the thing with this `id`. Note that
-// some def-ids don't wind up in the metadata, so `def_path` sometimes
-// returns `None`
-pub fn def_path(cdata: Cmd, id: DefIndex) -> Option<hir_map::DefPath> {
-    debug!("def_path(id={:?})", id);
-    if cdata.get_item(id).is_some() {
-        Some(hir_map::DefPath::make(cdata.cnum, id, |parent| def_key(cdata, parent)))
-    } else {
-        None
+    pub fn def_key(&self, id: DefIndex) -> hir_map::DefKey {
+        debug!("def_key: id={:?}", id);
+        self.item_def_key(self.entry(id))
+    }
+
+    // Returns the path leading to the thing with this `id`. Note that
+    // some def-ids don't wind up in the metadata, so `def_path` sometimes
+    // returns `None`
+    pub fn def_path(&self, id: DefIndex) -> Option<hir_map::DefPath> {
+        debug!("def_path(id={:?})", id);
+        if self.maybe_entry(id).is_some() {
+            Some(hir_map::DefPath::make(self.cnum, id, |parent| self.def_key(parent)))
+        } else {
+            None
+        }
     }
 }
index 637228725e0be18b3d90843eaae1dc6462890ac7..e345129b327e99e0258553046c8dc6d70413d584 100644 (file)
@@ -11,7 +11,6 @@
 // Metadata encoding
 
 #![allow(unused_must_use)] // everything is just a MemWriter, can't fail
-#![allow(non_camel_case_types)]
 
 use astencode::encode_inlined_item;
 use common::*;
@@ -226,9 +225,7 @@ fn encode_variant(&mut self, variant: ty::VariantDef,
             struct_ctor: struct_ctor
         })
     }
-}
 
-impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     /// Encode data for the given variant of the given ADT. The
     /// index of the variant is untracked: this is ok because we
     /// will have to lookup the adt-def by its id, and that gives us
@@ -249,8 +246,8 @@ fn encode_enum_variant_info(&mut self,
         self.encode_visibility(enum_vis);
 
         let attrs = tcx.get_attrs(vid);
-        encode_attributes(self, &attrs);
-        encode_stability(self, vid);
+        self.encode_attributes(&attrs);
+        self.encode_stability(vid);
 
         let data = self.encode_variant(variant, None);
 
@@ -264,9 +261,7 @@ fn encode_enum_variant_info(&mut self,
 
         self.encode_bounds_and_type_for_item(vid);
     }
-}
 
-impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     fn encode_info_for_mod(&mut self,
                            FromId(id, (md, attrs, vis)):
                            FromId<(&hir::Mod, &[ast::Attribute], &hir::Visibility)>) {
@@ -276,8 +271,8 @@ fn encode_info_for_mod(&mut self,
         self.encode_def_key(def_id);
         self.encode_family(Family::Mod);
         self.encode_visibility(vis);
-        encode_stability(self, def_id);
-        encode_attributes(self, attrs);
+        self.encode_stability(def_id);
+        self.encode_attributes(attrs);
         debug!("(encoding info for module) encoding info for module ID {}", id);
 
         // Encode info about all the module children.
@@ -371,8 +366,8 @@ fn encode_field(&mut self,
 
         let variant_id = tcx.map.as_local_node_id(variant.did).unwrap();
         let variant_data = tcx.map.expect_variant_data(variant_id);
-        encode_attributes(self, &variant_data.fields()[field_index].attrs);
-        encode_stability(self, field.did);
+        self.encode_attributes(&variant_data.fields()[field_index].attrs);
+        self.encode_stability(field.did);
     }
 
     fn encode_struct_ctor(&mut self, ctor_def_id: DefId) {
@@ -380,7 +375,7 @@ fn encode_struct_ctor(&mut self, ctor_def_id: DefId) {
         self.encode_family(Family::Struct);
         self.encode_bounds_and_type_for_item(ctor_def_id);
 
-        encode_stability(self, ctor_def_id);
+        self.encode_stability(ctor_def_id);
     }
 
     fn encode_generics(&mut self,
@@ -445,8 +440,8 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) {
         self.encode_family(family);
         self.encode_visibility(trait_item.vis());
 
-        encode_stability(self, def_id);
-        encode_attributes(self, &ast_item.attrs);
+        self.encode_stability(def_id);
+        self.encode_attributes(&ast_item.attrs);
         if let hir::MethodTraitItem(ref sig, _) = ast_item.node {
             self.encode_fn_arg_names(&sig.decl);
         };
@@ -499,8 +494,8 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) {
         self.encode_def_key(def_id);
         self.encode_family(family);
         self.encode_visibility(impl_item.vis());
-        encode_attributes(self, &ast_item.attrs);
-        encode_stability(self, def_id);
+        self.encode_attributes(&ast_item.attrs);
+        self.encode_stability(def_id);
 
         let constness = if let hir::ImplItemKind::Method(ref sig, _) = ast_item.node {
             if sig.constness == hir::Constness::Const {
@@ -555,33 +550,30 @@ fn encode_mir(&mut self, def_id: DefId) {
             self.end_tag();
         }
     }
-}
 
-// Encodes the inherent implementations of a structure, enumeration, or trait.
-fn encode_inherent_implementations(ecx: &mut EncodeContext,
-                                   def_id: DefId) {
-    ecx.start_tag(item_tag::inherent_impls);
-    match ecx.tcx.inherent_impls.borrow().get(&def_id) {
-        None => <[DefId]>::encode(&[], ecx).unwrap(),
-        Some(implementations) => implementations.encode(ecx).unwrap()
+    // Encodes the inherent implementations of a structure, enumeration, or trait.
+    fn encode_inherent_implementations(&mut self, def_id: DefId) {
+        self.start_tag(item_tag::inherent_impls);
+        match self.tcx.inherent_impls.borrow().get(&def_id) {
+            None => <[DefId]>::encode(&[], self).unwrap(),
+            Some(implementations) => implementations.encode(self).unwrap()
+        }
+        self.end_tag();
     }
-    ecx.end_tag();
-}
 
-fn encode_stability(ecx: &mut EncodeContext, def_id: DefId) {
-    ecx.tcx.lookup_stability(def_id).map(|stab| {
-        ecx.start_tag(item_tag::stability);
-        stab.encode(ecx).unwrap();
-        ecx.end_tag();
-    });
-    ecx.tcx.lookup_deprecation(def_id).map(|depr| {
-        ecx.start_tag(item_tag::deprecation);
-        depr.encode(ecx).unwrap();
-        ecx.end_tag();
-    });
-}
+    fn encode_stability(&mut self, def_id: DefId) {
+        self.tcx.lookup_stability(def_id).map(|stab| {
+            self.start_tag(item_tag::stability);
+            stab.encode(self).unwrap();
+            self.end_tag();
+        });
+        self.tcx.lookup_deprecation(def_id).map(|depr| {
+            self.start_tag(item_tag::deprecation);
+            depr.encode(self).unwrap();
+            self.end_tag();
+        });
+    }
 
-impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     fn encode_info_for_item(&mut self,
                             (def_id, item): (DefId, &hir::Item)) {
         let tcx = self.tcx;
@@ -652,7 +644,7 @@ fn encode_info_for_item(&mut self,
                 self.end_tag();
 
                 // Encode inherent implementations for self enumeration.
-                encode_inherent_implementations(self, def_id);
+                self.encode_inherent_implementations(def_id);
 
                 (Family::Enum, EntryData::Other, EntryTypedData::Other)
             }
@@ -675,7 +667,7 @@ fn encode_info_for_item(&mut self,
                 let data = self.encode_variant(variant, struct_ctor);
 
                 // Encode inherent implementations for self structure.
-                encode_inherent_implementations(self, def_id);
+                self.encode_inherent_implementations(def_id);
 
                 (Family::Struct, data, EntryTypedData::Other)
             }
@@ -691,7 +683,7 @@ fn encode_info_for_item(&mut self,
                 let data = self.encode_variant(def.struct_variant(), None);
 
                 // Encode inherent implementations for self union.
-                encode_inherent_implementations(self, def_id);
+                self.encode_inherent_implementations(def_id);
 
                 (Family::Union, data, EntryTypedData::Other)
             }
@@ -752,7 +744,7 @@ fn encode_info_for_item(&mut self,
                 self.end_tag();
 
                 // Encode inherent implementations for self trait.
-                encode_inherent_implementations(self, def_id);
+                self.encode_inherent_implementations(def_id);
 
                 (Family::Trait,
                  EntryData::Trait(TraitData {
@@ -772,8 +764,8 @@ fn encode_info_for_item(&mut self,
         self.encode_family(family);
         self.encode_def_key(def_id);
         self.encode_visibility(&item.vis);
-        encode_attributes(self, &item.attrs);
-        encode_stability(self, def_id);
+        self.encode_attributes(&item.attrs);
+        self.encode_stability(def_id);
 
         self.start_tag(item_tag::data);
         data.encode(self).unwrap();
@@ -883,8 +875,8 @@ fn encode_info_for_foreign_item(&mut self,
         EntryTypedData::Other.encode(self).unwrap();
         self.end_tag();
 
-        encode_attributes(self, &nitem.attrs);
-        encode_stability(self, def_id);
+        self.encode_attributes(&nitem.attrs);
+        self.encode_stability(def_id);
     }
 }
 
@@ -970,152 +962,153 @@ fn encode_info_for_closure(&mut self, def_id: DefId) {
         assert!(self.mir_map.map.contains_key(&def_id));
         self.encode_mir(def_id);
     }
-}
 
-fn encode_info_for_items(ecx: &mut EncodeContext) -> IndexData {
-    let krate = ecx.tcx.map.krate();
-
-    // FIXME(eddyb) Avoid wrapping the items in a doc.
-    ecx.start_tag(0).unwrap();
-
-    let items = {
-        let mut index = IndexBuilder::new(ecx);
-        index.record(DefId::local(CRATE_DEF_INDEX),
-                     EncodeContext::encode_info_for_mod,
-                     FromId(CRATE_NODE_ID, (&krate.module, &krate.attrs, &hir::Public)));
-        let mut visitor = EncodeVisitor {
-            index: index,
+    fn encode_info_for_items(&mut self) -> IndexData {
+        let krate = self.tcx.map.krate();
+
+        // FIXME(eddyb) Avoid wrapping the items in a doc.
+        self.start_tag(0).unwrap();
+
+        let items = {
+            let mut index = IndexBuilder::new(self);
+            index.record(DefId::local(CRATE_DEF_INDEX),
+                        EncodeContext::encode_info_for_mod,
+                        FromId(CRATE_NODE_ID, (&krate.module, &krate.attrs, &hir::Public)));
+            let mut visitor = EncodeVisitor {
+                index: index,
+            };
+            krate.visit_all_items(&mut visitor);
+            visitor.index.into_items()
         };
-        krate.visit_all_items(&mut visitor);
-        visitor.index.into_items()
-    };
 
-    ecx.end_tag();
+        self.end_tag();
 
-    items
-}
+        items
+    }
 
-fn encode_item_index(ecx: &mut EncodeContext, index: IndexData) {
-    ecx.start_tag(root_tag::index);
-    index.write_index(&mut ecx.opaque.cursor);
-    ecx.end_tag();
-}
+    fn encode_item_index(&mut self, index: IndexData) {
+        self.start_tag(root_tag::index);
+        index.write_index(&mut self.opaque.cursor);
+        self.end_tag();
+    }
 
-fn encode_attributes(ecx: &mut EncodeContext, attrs: &[ast::Attribute]) {
-    ecx.start_tag(item_tag::attributes);
-    attrs.encode(ecx).unwrap();
-    ecx.end_tag();
-}
+    fn encode_attributes(&mut self, attrs: &[ast::Attribute]) {
+        self.start_tag(item_tag::attributes);
+        attrs.encode(self).unwrap();
+        self.end_tag();
+    }
 
-fn encode_crate_deps(ecx: &mut EncodeContext, cstore: &cstore::CStore) {
-    fn get_ordered_deps(cstore: &cstore::CStore)
-                        -> Vec<(CrateNum, Rc<cstore::CrateMetadata>)> {
-        // Pull the cnums and name,vers,hash out of cstore
-        let mut deps = Vec::new();
-        cstore.iter_crate_data(|cnum, val| {
-            deps.push((cnum, val.clone()));
-        });
+    fn encode_crate_deps(&mut self) {
+        fn get_ordered_deps(cstore: &cstore::CStore)
+                            -> Vec<(CrateNum, Rc<cstore::CrateMetadata>)> {
+            // Pull the cnums and name,vers,hash out of cstore
+            let mut deps = Vec::new();
+            cstore.iter_crate_data(|cnum, val| {
+                deps.push((cnum, val.clone()));
+            });
 
-        // Sort by cnum
-        deps.sort_by(|kv1, kv2| kv1.0.cmp(&kv2.0));
+            // Sort by cnum
+            deps.sort_by(|kv1, kv2| kv1.0.cmp(&kv2.0));
 
-        // Sanity-check the crate numbers
-        let mut expected_cnum = 1;
-        for &(n, _) in &deps {
-            assert_eq!(n, CrateNum::new(expected_cnum));
-            expected_cnum += 1;
+            // Sanity-check the crate numbers
+            let mut expected_cnum = 1;
+            for &(n, _) in &deps {
+                assert_eq!(n, CrateNum::new(expected_cnum));
+                expected_cnum += 1;
+            }
+
+            deps
         }
 
-        deps
+        // We're just going to write a list of crate 'name-hash-version's, with
+        // the assumption that they are numbered 1 to n.
+        // FIXME (#2166): This is not nearly enough to support correct versioning
+        // but is enough to get transitive crate dependencies working.
+        self.start_tag(root_tag::crate_deps);
+        let deps = get_ordered_deps(self.cstore);
+        self.seq(&deps, |_, &(_, ref dep)| {
+            (dep.name(), dep.hash(), dep.explicitly_linked.get())
+        });
+        self.end_tag();
     }
 
-    // We're just going to write a list of crate 'name-hash-version's, with
-    // the assumption that they are numbered 1 to n.
-    // FIXME (#2166): This is not nearly enough to support correct versioning
-    // but is enough to get transitive crate dependencies working.
-    ecx.start_tag(root_tag::crate_deps);
-    ecx.seq(&get_ordered_deps(cstore), |_, &(_, ref dep)| {
-        (dep.name(), dep.hash(), dep.explicitly_linked.get())
-    });
-    ecx.end_tag();
-}
-
-fn encode_lang_items(ecx: &mut EncodeContext) {
-    let tcx = ecx.tcx;
-    let lang_items = || {
-        tcx.lang_items.items().iter().enumerate().filter_map(|(i, &opt_def_id)| {
-            if let Some(def_id) = opt_def_id {
-                if def_id.is_local() {
-                    return Some((def_id.index, i));
+    fn encode_lang_items(&mut self) {
+        let tcx = self.tcx;
+        let lang_items = || {
+            tcx.lang_items.items().iter().enumerate().filter_map(|(i, &opt_def_id)| {
+                if let Some(def_id) = opt_def_id {
+                    if def_id.is_local() {
+                        return Some((def_id.index, i));
+                    }
                 }
-            }
-            None
-        })
-    };
+                None
+            })
+        };
 
-    let count = lang_items().count();
-    let mut lang_items = lang_items();
+        let count = lang_items().count();
+        let mut lang_items = lang_items();
 
-    ecx.start_tag(root_tag::lang_items);
-    ecx.seq(0..count, |_, _| lang_items.next().unwrap());
-    ecx.end_tag();
+        self.start_tag(root_tag::lang_items);
+        self.seq(0..count, |_, _| lang_items.next().unwrap());
+        self.end_tag();
 
-    ecx.start_tag(root_tag::lang_items_missing);
-    tcx.lang_items.missing.encode(ecx).unwrap();
-    ecx.end_tag();
-}
+        self.start_tag(root_tag::lang_items_missing);
+        tcx.lang_items.missing.encode(self).unwrap();
+        self.end_tag();
+    }
 
-fn encode_native_libraries(ecx: &mut EncodeContext) {
-    let used_libraries = ecx.tcx.sess.cstore.used_libraries();
-    let libs = || {
-        used_libraries.iter().filter_map(|&(ref lib, kind)| {
-            match kind {
-                cstore::NativeStatic => None, // these libraries are not propagated
-                cstore::NativeFramework | cstore::NativeUnknown => {
-                    Some((kind, lib))
+    fn encode_native_libraries(&mut self) {
+        let used_libraries = self.tcx.sess.cstore.used_libraries();
+        let libs = || {
+            used_libraries.iter().filter_map(|&(ref lib, kind)| {
+                match kind {
+                    cstore::NativeStatic => None, // these libraries are not propagated
+                    cstore::NativeFramework | cstore::NativeUnknown => {
+                        Some((kind, lib))
+                    }
                 }
-            }
-        })
-    };
+            })
+        };
 
-    let count = libs().count();
-    let mut libs = libs();
+        let count = libs().count();
+        let mut libs = libs();
 
-    ecx.start_tag(root_tag::native_libraries);
-    ecx.seq(0..count, |_, _| libs.next().unwrap());
-    ecx.end_tag();
-}
+        self.start_tag(root_tag::native_libraries);
+        self.seq(0..count, |_, _| libs.next().unwrap());
+        self.end_tag();
+    }
 
-fn encode_codemap(ecx: &mut EncodeContext) {
-    let codemap = ecx.tcx.sess.codemap();
-    let all_filemaps = codemap.files.borrow();
-    let filemaps = || {
-        // No need to export empty filemaps, as they can't contain spans
-        // that need translation.
-        // Also no need to re-export imported filemaps, as any downstream
-        // crate will import them from their original source.
-        all_filemaps.iter().filter(|filemap| {
-            !filemap.lines.borrow().is_empty() && !filemap.is_imported()
-        })
-    };
+    fn encode_codemap(&mut self) {
+        let codemap = self.tcx.sess.codemap();
+        let all_filemaps = codemap.files.borrow();
+        let filemaps = || {
+            // No need to export empty filemaps, as they can't contain spans
+            // that need translation.
+            // Also no need to re-export imported filemaps, as any downstream
+            // crate will import them from their original source.
+            all_filemaps.iter().filter(|filemap| {
+                !filemap.lines.borrow().is_empty() && !filemap.is_imported()
+            })
+        };
 
-    let count = filemaps().count();
-    let mut filemaps = filemaps();
+        let count = filemaps().count();
+        let mut filemaps = filemaps();
 
-    ecx.start_tag(root_tag::codemap);
-    ecx.seq(0..count, |_, _| filemaps.next().unwrap());
-    ecx.end_tag();
-}
+        self.start_tag(root_tag::codemap);
+        self.seq(0..count, |_, _| filemaps.next().unwrap());
+        self.end_tag();
+    }
 
-/// Serialize the text of the exported macros
-fn encode_macro_defs(ecx: &mut EncodeContext) {
-    let tcx = ecx.tcx;
-    ecx.start_tag(root_tag::macro_defs);
-    ecx.seq(&tcx.map.krate().exported_macros, |_, def| {
-        let body = ::syntax::print::pprust::tts_to_string(&def.body);
-        (def.name, &def.attrs, def.span, body)
-    });
-    ecx.end_tag();
+    /// Serialize the text of the exported macros
+    fn encode_macro_defs(&mut self) {
+        let tcx = self.tcx;
+        self.start_tag(root_tag::macro_defs);
+        self.seq(&tcx.map.krate().exported_macros, |_, def| {
+            let body = ::syntax::print::pprust::tts_to_string(&def.body);
+            (def.name, &def.attrs, def.span, body)
+        });
+        self.end_tag();
+    }
 }
 
 struct ImplVisitor<'a, 'tcx:'a> {
@@ -1136,59 +1129,61 @@ fn visit_item(&mut self, item: &hir::Item) {
     }
 }
 
-/// Encodes an index, mapping each trait to its (local) implementations.
-fn encode_impls(ecx: &mut EncodeContext) {
-    let mut visitor = ImplVisitor {
-        tcx: ecx.tcx,
-        impls: FnvHashMap()
-    };
-    ecx.tcx.map.krate().visit_all_items(&mut visitor);
-
-    ecx.start_tag(root_tag::impls);
-    for (trait_def_id, trait_impls) in visitor.impls {
-        // FIXME(eddyb) Avoid wrapping the entries in docs.
-        ecx.start_tag(0);
-        (trait_def_id.krate.as_u32(), trait_def_id.index).encode(ecx).unwrap();
-        trait_impls.encode(ecx).unwrap();
-        ecx.end_tag();
+impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
+    /// Encodes an index, mapping each trait to its (local) implementations.
+    fn encode_impls(&mut self) {
+        let mut visitor = ImplVisitor {
+            tcx: self.tcx,
+            impls: FnvHashMap()
+        };
+        self.tcx.map.krate().visit_all_items(&mut visitor);
+
+        self.start_tag(root_tag::impls);
+        for (trait_def_id, trait_impls) in visitor.impls {
+            // FIXME(eddyb) Avoid wrapping the entries in docs.
+            self.start_tag(0);
+            (trait_def_id.krate.as_u32(), trait_def_id.index).encode(self).unwrap();
+            trait_impls.encode(self).unwrap();
+            self.end_tag();
+        }
+        self.end_tag();
     }
-    ecx.end_tag();
-}
 
-// Encodes all reachable symbols in this crate into the metadata.
-//
-// This pass is seeded off the reachability list calculated in the
-// middle::reachable module but filters out items that either don't have a
-// symbol associated with them (they weren't translated) or if they're an FFI
-// definition (as that's not defined in this crate).
-fn encode_reachable(ecx: &mut EncodeContext) {
-    ecx.start_tag(root_tag::reachable_ids);
+    // Encodes all reachable symbols in this crate into the metadata.
+    //
+    // This pass is seeded off the reachability list calculated in the
+    // middle::reachable module but filters out items that either don't have a
+    // symbol associated with them (they weren't translated) or if they're an FFI
+    // definition (as that's not defined in this crate).
+    fn encode_reachable(&mut self) {
+        self.start_tag(root_tag::reachable_ids);
 
-    let reachable = ecx.reachable;
-    ecx.seq(reachable, |ecx, &id| ecx.tcx.map.local_def_id(id).index);
+        let reachable = self.reachable;
+        self.seq(reachable, |ecx, &id| ecx.tcx.map.local_def_id(id).index);
 
-    ecx.end_tag();
-}
+        self.end_tag();
+    }
 
-fn encode_dylib_dependency_formats(ecx: &mut EncodeContext) {
-    ecx.start_tag(root_tag::dylib_dependency_formats);
-    match ecx.tcx.sess.dependency_formats.borrow().get(&config::CrateTypeDylib) {
-        Some(arr) => {
-            ecx.seq(arr, |_, slot| {
-                match *slot {
-                    Linkage::NotLinked |
-                    Linkage::IncludedFromDylib => None,
-
-                    Linkage::Dynamic => Some(LinkagePreference::RequireDynamic),
-                    Linkage::Static => Some(LinkagePreference::RequireStatic),
-                }
-            });
-        }
-        None => {
-            <[Option<LinkagePreference>]>::encode(&[], ecx).unwrap();
+    fn encode_dylib_dependency_formats(&mut self) {
+        self.start_tag(root_tag::dylib_dependency_formats);
+        match self.tcx.sess.dependency_formats.borrow().get(&config::CrateTypeDylib) {
+            Some(arr) => {
+                self.seq(arr, |_, slot| {
+                    match *slot {
+                        Linkage::NotLinked |
+                        Linkage::IncludedFromDylib => None,
+
+                        Linkage::Dynamic => Some(LinkagePreference::RequireDynamic),
+                        Linkage::Static => Some(LinkagePreference::RequireStatic),
+                    }
+                });
+            }
+            None => {
+                <[Option<LinkagePreference>]>::encode(&[], self).unwrap();
+            }
         }
+        self.end_tag();
     }
-    ecx.end_tag();
 }
 
 pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -1281,47 +1276,47 @@ fn encode_metadata_inner(ecx: &mut EncodeContext) {
     ecx.end_tag();
 
     let mut i = ecx.position();
-    encode_crate_deps(ecx, ecx.cstore);
-    encode_dylib_dependency_formats(ecx);
+    ecx.encode_crate_deps();
+    ecx.encode_dylib_dependency_formats();
     let dep_bytes = ecx.position() - i;
 
     // Encode the language items.
     i = ecx.position();
-    encode_lang_items(ecx);
+    ecx.encode_lang_items();
     let lang_item_bytes = ecx.position() - i;
 
     // Encode the native libraries used
     i = ecx.position();
-    encode_native_libraries(ecx);
+    ecx.encode_native_libraries();
     let native_lib_bytes = ecx.position() - i;
 
     // Encode codemap
     i = ecx.position();
-    encode_codemap(ecx);
+    ecx.encode_codemap();
     let codemap_bytes = ecx.position() - i;
 
     // Encode macro definitions
     i = ecx.position();
-    encode_macro_defs(ecx);
+    ecx.encode_macro_defs();
     let macro_defs_bytes = ecx.position() - i;
 
     // Encode the def IDs of impls, for coherence checking.
     i = ecx.position();
-    encode_impls(ecx);
+    ecx.encode_impls();
     let impl_bytes = ecx.position() - i;
 
     // Encode reachability info.
     i = ecx.position();
-    encode_reachable(ecx);
+    ecx.encode_reachable();
     let reachable_bytes = ecx.position() - i;
 
     // Encode and index the items.
     i = ecx.position();
-    let items = encode_info_for_items(ecx);
+    let items = ecx.encode_info_for_items();
     let item_bytes = ecx.position() - i;
 
     i = ecx.position();
-    encode_item_index(ecx, items);
+    ecx.encode_item_index(items);
     let index_bytes = ecx.position() - i;
 
     let total_bytes = ecx.position();
index 47bf65bead9af328f45bccdc9ee426dd4e273b0b..883004b8486f1fde30464759386e24653d2c3017 100644 (file)
 
 use cstore::{MetadataBlob, MetadataVec, MetadataArchive};
 use common::{metadata_encoding_version, rustc_version};
-use decoder;
 
 use rustc::hir::svh::Svh;
 use rustc::session::Session;
@@ -511,7 +510,7 @@ fn find_library_crate(&mut self) -> Option<Library> {
                     if let Some((ref p, _)) = lib.rlib {
                         err.note(&format!("path: {}", p.display()));
                     }
-                    let crate_info = decoder::get_crate_info(lib.metadata.as_slice());
+                    let crate_info = lib.metadata.get_crate_info();
                     note_crate_name(&mut err, &crate_info.name);
                 }
                 err.emit();
@@ -550,7 +549,7 @@ fn extract_one(&mut self, m: FnvHashMap<PathBuf, PathKind>, flavor: CrateFlavor,
             info!("{} reading metadata from: {}", flavor, lib.display());
             let (hash, metadata) = match get_metadata_section(self.target, flavor, &lib) {
                 Ok(blob) => {
-                    if let Some(h) = self.crate_matches(blob.as_slice(), &lib) {
+                    if let Some(h) = self.crate_matches(&blob, &lib) {
                         (h, blob)
                     } else {
                         info!("metadata mismatch");
@@ -597,8 +596,8 @@ fn extract_one(&mut self, m: FnvHashMap<PathBuf, PathKind>, flavor: CrateFlavor,
         }
     }
 
-    fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> Option<Svh> {
-        let crate_rustc_version = decoder::crate_rustc_version(crate_data);
+    fn crate_matches(&mut self, metadata: &MetadataBlob, libpath: &Path) -> Option<Svh> {
+        let crate_rustc_version = metadata.crate_rustc_version();
         if crate_rustc_version != Some(rustc_version()) {
             let message = crate_rustc_version.unwrap_or(format!("an unknown compiler"));
             info!("Rejecting via version: expected {} got {}", rustc_version(), message);
@@ -609,7 +608,7 @@ fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> Option<Svh> {
             return None;
         }
 
-        let crate_info = decoder::get_crate_info(crate_data);
+        let crate_info = metadata.get_crate_info();
         if self.should_match_name {
             if self.crate_name != crate_info.name {
                 info!("Rejecting via crate name"); return None;
@@ -895,7 +894,7 @@ pub fn list_file_metadata(target: &Target, path: &Path,
     let filename = path.file_name().unwrap().to_str().unwrap();
     let flavor = if filename.ends_with(".rlib") { CrateFlavor::Rlib } else { CrateFlavor::Dylib };
     match get_metadata_section(target, flavor, path) {
-        Ok(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out),
+        Ok(metadata) => metadata.list_crate_metadata(out),
         Err(msg) => {
             write!(out, "{}\n", msg)
         }
index 24a0329602beb0becc3440aa120a05f0fa711cca..c4cfc32d63306140ca3d918e7eef2f4f511fa101 100644 (file)
 use std::fmt;
 use std::str;
 
+macro_rules! try_or {
+    ($e:expr, $r:expr) => (
+        match $e {
+            Ok(x) => x,
+            Err(_) => return $r
+        }
+    )
+}
+
 #[derive(Clone, Copy)]
 pub struct Doc<'a> {
     pub data: &'a [u8],
@@ -79,17 +88,34 @@ pub fn at(data: &'doc [u8], start: usize) -> Doc<'doc> {
         }
     }
 
-    pub fn get(&self, tag: usize) -> Doc<'doc> {
-        match maybe_get_doc(*self, tag) {
+    pub fn maybe_child(&self, tag: usize) -> Option<Doc<'doc>> {
+        let mut pos = self.start;
+        while pos < self.end {
+            let elt_tag = try_or!(tag_at(self.data, pos), None);
+            let elt_size = try_or!(tag_len_at(self.data, elt_tag.next), None);
+            pos = elt_size.next + elt_size.val;
+            if elt_tag.val == tag {
+                return Some(Doc {
+                    data: self.data,
+                    start: elt_size.next,
+                    end: pos,
+                });
+            }
+        }
+        None
+    }
+
+    pub fn child(&self, tag: usize) -> Doc<'doc> {
+        match self.maybe_child(tag) {
             Some(d) => d,
             None => {
-                bug!("failed to find block with tag {:?}", tag);
+                bug!("failed to find child with tag {:?}", tag);
             }
         }
     }
 
-    pub fn children(self) -> DocsIterator<'doc> {
-        DocsIterator { d: self }
+    pub fn children_of(&self, tag: usize) -> DocsIterator<'doc> {
+        DocsIterator { d: self.child(tag) }
     }
 }
 
@@ -106,24 +132,10 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-// rbml reading
-
-macro_rules! try_or {
-    ($e:expr, $r:expr) => (
-        match $e {
-            Ok(e) => e,
-            Err(e) => {
-                debug!("ignored error: {:?}", e);
-                return $r
-            }
-        }
-    )
-}
-
 #[derive(Copy, Clone)]
-pub struct Res {
-    pub val: usize,
-    pub next: usize,
+struct Res {
+    val: usize,
+    next: usize,
 }
 
 fn tag_at(data: &[u8], start: usize) -> Result<Res, Error> {
@@ -235,23 +247,6 @@ fn tag_len_at(data: &[u8], next: usize) -> Result<Res, Error> {
     vuint_at(data, next)
 }
 
-pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: usize) -> Option<Doc<'a>> {
-    let mut pos = d.start;
-    while pos < d.end {
-        let elt_tag = try_or!(tag_at(d.data, pos), None);
-        let elt_size = try_or!(tag_len_at(d.data, elt_tag.next), None);
-        pos = elt_size.next + elt_size.val;
-        if elt_tag.val == tg {
-            return Some(Doc {
-                data: d.data,
-                start: elt_size.next,
-                end: pos,
-            });
-        }
-    }
-    None
-}
-
 pub struct DocsIterator<'a> {
     d: Doc<'a>,
 }
index 43a9b4e49e39377e330ccc67d175b3c2c751be6b..0acf211a27c53897aa2e1c0985fec8e5210ee386 100644 (file)
@@ -237,8 +237,8 @@ pub struct ExternalCrate {
 impl Clean<ExternalCrate> for CrateNum {
     fn clean(&self, cx: &DocContext) -> ExternalCrate {
         let mut primitives = Vec::new();
+        let root = DefId { krate: self.0, index: CRATE_DEF_INDEX };
         cx.tcx_opt().map(|tcx| {
-            let root = DefId { krate: self.0, index: CRATE_DEF_INDEX };
             for item in tcx.sess.cstore.item_children(root) {
                 let did = match item.def {
                     Def::Mod(did) => did,
@@ -250,7 +250,7 @@ fn clean(&self, cx: &DocContext) -> ExternalCrate {
         });
         ExternalCrate {
             name: (&cx.sess().cstore.crate_name(self.0)[..]).to_owned(),
-            attrs: cx.sess().cstore.crate_attrs(self.0).clean(cx),
+            attrs: cx.sess().cstore.item_attrs(root).clean(cx),
             primitives: primitives,
         }
     }