rustc_metadata: move all encoding/decoding helpers to methods.

This commit is contained in:
Eduard Burtescu 2016-09-15 11:04:00 +03:00
parent 6890354f3b
commit adddfccf2b
10 changed files with 1103 additions and 1231 deletions

View File

@ -188,7 +188,6 @@ pub trait CrateStore<'tcx> {
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 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
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")

View 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);

View 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::util::nodemap::{FnvHashMap, FnvHashSet};
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 @@ impl<'a> CrateReader<'a> {
-> (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 @@ impl<'a> CrateReader<'a> {
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 @@ impl<'a> CrateReader<'a> {
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 @@ impl<'a> CrateReader<'a> {
// 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 @@ impl<'a> CrateReader<'a> {
// 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 @@ impl<'a> CrateReader<'a> {
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 @@ impl<'a> CrateReader<'a> {
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 @@ impl<'a> CrateReader<'a> {
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

View File

@ -10,7 +10,6 @@
use cstore;
use common;
use decoder;
use encoder;
use loader;
@ -40,101 +39,87 @@ use rustc::hir;
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 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
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 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
{
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 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
}
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 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
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 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
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 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
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 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
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 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
// 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 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
// 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 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
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 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
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>

View 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 @@ pub use self::MetadataBlob::*;
use common;
use creader;
use decoder;
use index;
use loader;
@ -297,7 +294,6 @@ impl CStore {
}
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 @@ impl CrateMetadata {
}
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()
}

File diff suppressed because it is too large Load Diff

View 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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
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();
fn encode_info_for_items(&mut self) -> IndexData {
let krate = self.tcx.map.krate();
// FIXME(eddyb) Avoid wrapping the items in a doc.
ecx.start_tag(0).unwrap();
// FIXME(eddyb) Avoid wrapping the items in a doc.
self.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,
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
}
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_attributes(ecx: &mut EncodeContext, attrs: &[ast::Attribute]) {
ecx.start_tag(item_tag::attributes);
attrs.encode(ecx).unwrap();
ecx.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()));
});
// 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;
}
deps
items
}
// 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_item_index(&mut self, index: IndexData) {
self.start_tag(root_tag::index);
index.write_index(&mut self.opaque.cursor);
self.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_attributes(&mut self, attrs: &[ast::Attribute]) {
self.start_tag(item_tag::attributes);
attrs.encode(self).unwrap();
self.end_tag();
}
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));
// Sanity-check the crate numbers
let mut expected_cnum = 1;
for &(n, _) in &deps {
assert_eq!(n, CrateNum::new(expected_cnum));
expected_cnum += 1;
}
None
})
};
let count = lang_items().count();
let mut lang_items = lang_items();
deps
}
ecx.start_tag(root_tag::lang_items);
ecx.seq(0..count, |_, _| lang_items.next().unwrap());
ecx.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.
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();
}
ecx.start_tag(root_tag::lang_items_missing);
tcx.lang_items.missing.encode(ecx).unwrap();
ecx.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_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
})
};
let count = libs().count();
let mut libs = libs();
let count = lang_items().count();
let mut lang_items = lang_items();
ecx.start_tag(root_tag::native_libraries);
ecx.seq(0..count, |_, _| libs.next().unwrap());
ecx.end_tag();
}
self.start_tag(root_tag::lang_items);
self.seq(0..count, |_, _| lang_items.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()
})
};
self.start_tag(root_tag::lang_items_missing);
tcx.lang_items.missing.encode(self).unwrap();
self.end_tag();
}
let count = filemaps().count();
let mut filemaps = filemaps();
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))
}
}
})
};
ecx.start_tag(root_tag::codemap);
ecx.seq(0..count, |_, _| filemaps.next().unwrap());
ecx.end_tag();
}
let count = libs().count();
let mut libs = libs();
/// 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();
self.start_tag(root_tag::native_libraries);
self.seq(0..count, |_, _| libs.next().unwrap());
self.end_tag();
}
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();
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(&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 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'tcx> {
}
}
/// 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);
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);
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();
}
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);
let reachable = ecx.reachable;
ecx.seq(reachable, |ecx, &id| ecx.tcx.map.local_def_id(id).index);
ecx.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();
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();
}
// 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 = self.reachable;
self.seq(reachable, |ecx, &id| ecx.tcx.map.local_def_id(id).index);
self.end_tag();
}
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();

View File

@ -214,7 +214,6 @@
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 @@ impl<'a> Context<'a> {
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 @@ impl<'a> Context<'a> {
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 @@ impl<'a> Context<'a> {
}
}
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 @@ impl<'a> Context<'a> {
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)
}

View File

@ -52,6 +52,15 @@ use test::Bencher;
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 @@ impl<'doc> 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 @@ impl fmt::Display for Error {
}
}
// 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>,
}

View 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 @@ impl Clean<ExternalCrate> for CrateNum {
});
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,
}
}