diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2015-09-17 14:29:59 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2015-10-01 10:43:07 -0400 |
| commit | 01f32ace0302373fb69ef9e2d0e21cc841981eba (patch) | |
| tree | aceffa99e137cb0fa21d75f1a973ab0528a21415 /src/librustc/metadata | |
| parent | a6fee0674171fefc25e1a61e01870a654d6862a8 (diff) | |
Convert DefId to use DefIndex, which is an index into a list of
paths, and construct paths for all definitions. Also, stop rewriting DefIds for closures, and instead just load the closure data from the original def-id, which may be in another crate.
Diffstat (limited to 'src/librustc/metadata')
| -rw-r--r-- | src/librustc/metadata/common.rs | 19 | ||||
| -rw-r--r-- | src/librustc/metadata/creader.rs | 7 | ||||
| -rw-r--r-- | src/librustc/metadata/csearch.rs | 103 | ||||
| -rw-r--r-- | src/librustc/metadata/cstore.rs | 18 | ||||
| -rw-r--r-- | src/librustc/metadata/decoder.rs | 222 | ||||
| -rw-r--r-- | src/librustc/metadata/encoder.rs | 248 | ||||
| -rw-r--r-- | src/librustc/metadata/index.rs | 224 | ||||
| -rw-r--r-- | src/librustc/metadata/tydecode.rs | 64 |
8 files changed, 449 insertions, 456 deletions
diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index a6cbb4ec504..7b8ad78da74 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -43,9 +43,15 @@ pub const tag_items_data_parent_item: usize = 0x28; pub const tag_items_data_item_is_tuple_struct_ctor: usize = 0x29; -pub const tag_index: usize = 0x2a; +pub const tag_items_closure_kind: usize = 0x2a; -// GAP 0x2b, 0x2c, 0x2d, 0x2e +pub const tag_items_closure_ty: usize = 0x2b; + +pub const tag_index: usize = 0x2c; + +pub const tag_def_key: usize = 0x2d; + +// GAP 0x2e pub const tag_meta_item_name_value: usize = 0x2f; @@ -137,8 +143,7 @@ enum_from_u32! { tag_table_adjustments = 0x61, tag_table_moves_map = 0x62, tag_table_capture_map = 0x63, - tag_table_closure_tys = 0x64, - tag_table_closure_kinds = 0x65, + // GAP 0x64, 0x65 tag_table_upvar_capture_map = 0x66, tag_table_capture_modes = 0x67, // GAP 0x68 @@ -162,12 +167,12 @@ pub const tag_dylib_dependency_formats: usize = 0x106; // top-level only // tag_lang_items // - tag_lang_items_item // - tag_lang_items_item_id: u32 -// - tag_lang_items_item_node_id: u32 +// - tag_lang_items_item_index: u32 pub const tag_lang_items: usize = 0x107; // top-level only pub const tag_lang_items_item: usize = 0x73; pub const tag_lang_items_item_id: usize = 0x74; -pub const tag_lang_items_item_node_id: usize = 0x75; +pub const tag_lang_items_item_index: usize = 0x75; pub const tag_lang_items_missing: usize = 0x76; pub const tag_item_unnamed_field: usize = 0x77; @@ -215,7 +220,7 @@ pub struct LinkMeta { pub const tag_struct_fields: usize = 0x10d; // top-level only pub const tag_struct_field: usize = 0x8a; -pub const tag_struct_field_id: usize = 0x8b; +// GAP 0x8b pub const tag_attribute_is_sugared_doc: usize = 0x8c; diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 04f164c296d..fe4a909a085 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -325,6 +325,7 @@ impl<'a> CrateReader<'a> { let cmeta = Rc::new(cstore::crate_metadata { name: name.to_string(), local_path: RefCell::new(SmallVector::zero()), + local_def_path: RefCell::new(vec![]), index: decoder::load_index(metadata.as_slice()), data: metadata, cnum_map: RefCell::new(cnum_map), @@ -548,7 +549,8 @@ impl<'a> CrateReader<'a> { self.sess.abort_if_errors(); } - let registrar = decoder::get_plugin_registrar_fn(ekrate.metadata.as_slice()) + let registrar = + decoder::get_plugin_registrar_fn(ekrate.metadata.as_slice()) .map(|id| decoder::get_symbol_from_buf(ekrate.metadata.as_slice(), id)); match (ekrate.dylib.as_ref(), registrar) { @@ -751,6 +753,9 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> { i.span, PathKind::Crate, true); + let def_id = self.ast_map.local_def_id(i.id); + let def_path = self.ast_map.def_path(def_id); + cmeta.update_local_def_path(def_path); self.ast_map.with_path(i.id, |path| { cmeta.update_local_path(path) }); diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 70a969e4d82..402aa52612e 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -14,7 +14,7 @@ use front::map as ast_map; use metadata::cstore; use metadata::decoder; use metadata::inline::InlinedItem; -use middle::def_id::DefId; +use middle::def_id::{DefId, DefIndex}; use middle::lang_items; use middle::ty; use util::nodemap::FnvHashMap; @@ -33,7 +33,7 @@ pub struct MethodInfo { pub fn get_symbol(cstore: &cstore::CStore, def: DefId) -> String { let cdata = cstore.get_crate_data(def.krate); - decoder::get_symbol(&cdata, def.xxx_node) + decoder::get_symbol(&cdata, def.index) } /// Iterates over all the language items in the given crate. @@ -41,7 +41,7 @@ pub fn each_lang_item<F>(cstore: &cstore::CStore, cnum: ast::CrateNum, f: F) -> bool where - F: FnMut(ast::NodeId, usize) -> bool, + F: FnMut(DefIndex, usize) -> bool, { let crate_data = cstore.get_crate_data(cnum); decoder::each_lang_item(&*crate_data, f) @@ -59,7 +59,7 @@ pub fn each_child_of_item<F>(cstore: &cstore::CStore, }; decoder::each_child_of_item(cstore.intr.clone(), &*crate_data, - def_id.xxx_node, + def_id.index, get_crate_data, callback) } @@ -83,7 +83,7 @@ pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore, pub fn get_item_path(tcx: &ty::ctxt, def: DefId) -> Vec<ast_map::PathElem> { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - let path = decoder::get_item_path(&*cdata, def.xxx_node); + let path = decoder::get_item_path(&*cdata, def.index); cdata.with_local_path(|cpath| { let mut r = Vec::with_capacity(cpath.len() + path.len()); @@ -96,7 +96,7 @@ pub fn get_item_path(tcx: &ty::ctxt, def: DefId) -> Vec<ast_map::PathElem> { pub fn get_item_name(tcx: &ty::ctxt, def: DefId) -> ast::Name { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_item_name(&cstore.intr, &cdata, def.xxx_node) + decoder::get_item_name(&cstore.intr, &cdata, def.index) } pub enum FoundAst<'ast> { @@ -113,14 +113,14 @@ pub fn maybe_get_item_ast<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId, -> FoundAst<'tcx> { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::maybe_get_item_ast(&*cdata, tcx, def.xxx_node, decode_inlined_item) + decoder::maybe_get_item_ast(&*cdata, tcx, def.index, decode_inlined_item) } /// Returns information about the given implementation. pub fn get_impl_items(cstore: &cstore::CStore, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId> { let cdata = cstore.get_crate_data(impl_def_id.krate); - decoder::get_impl_items(&*cdata, impl_def_id.xxx_node) + decoder::get_impl_items(&*cdata, impl_def_id.index) } pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) @@ -128,7 +128,7 @@ pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) let cdata = tcx.sess.cstore.get_crate_data(def.krate); decoder::get_impl_or_trait_item(tcx.sess.cstore.intr.clone(), &*cdata, - def.xxx_node, + def.index, tcx) } @@ -136,24 +136,24 @@ pub fn get_trait_name(cstore: &cstore::CStore, def: DefId) -> ast::Name { let cdata = cstore.get_crate_data(def.krate); decoder::get_trait_name(cstore.intr.clone(), &*cdata, - def.xxx_node) + def.index) } pub fn is_static_method(cstore: &cstore::CStore, def: DefId) -> bool { let cdata = cstore.get_crate_data(def.krate); - decoder::is_static_method(&*cdata, def.xxx_node) + decoder::is_static_method(&*cdata, def.index) } pub fn get_trait_item_def_ids(cstore: &cstore::CStore, def: DefId) -> Vec<ty::ImplOrTraitItemId> { let cdata = cstore.get_crate_data(def.krate); - decoder::get_trait_item_def_ids(&*cdata, def.xxx_node) + decoder::get_trait_item_def_ids(&*cdata, def.index) } pub fn get_item_variances(cstore: &cstore::CStore, def: DefId) -> ty::ItemVariances { let cdata = cstore.get_crate_data(def.krate); - decoder::get_item_variances(&*cdata, def.xxx_node) + decoder::get_item_variances(&*cdata, def.index) } pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>, @@ -161,43 +161,43 @@ pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>, -> Vec<Rc<ty::Method<'tcx>>> { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.xxx_node, tcx) + decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.index, tcx) } pub fn get_associated_consts<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) -> Vec<Rc<ty::AssociatedConst<'tcx>>> { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_associated_consts(cstore.intr.clone(), &*cdata, def.xxx_node, tcx) + decoder::get_associated_consts(cstore.intr.clone(), &*cdata, def.index, tcx) } pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: DefId) -> Option<ast::Name> { let cdata = cstore.get_crate_data(def.krate); - decoder::get_type_name_if_impl(&*cdata, def.xxx_node) + decoder::get_type_name_if_impl(&*cdata, def.index) } pub fn get_methods_if_impl(cstore: &cstore::CStore, def: DefId) -> Option<Vec<MethodInfo> > { let cdata = cstore.get_crate_data(def.krate); - decoder::get_methods_if_impl(cstore.intr.clone(), &*cdata, def.xxx_node) + decoder::get_methods_if_impl(cstore.intr.clone(), &*cdata, def.index) } pub fn get_item_attrs(cstore: &cstore::CStore, def_id: DefId) -> Vec<ast::Attribute> { let cdata = cstore.get_crate_data(def_id.krate); - decoder::get_item_attrs(&*cdata, def_id.xxx_node) + decoder::get_item_attrs(&*cdata, def_id.index) } pub fn get_struct_field_names(cstore: &cstore::CStore, def: DefId) -> Vec<ast::Name> { let cdata = cstore.get_crate_data(def.krate); - decoder::get_struct_field_names(&cstore.intr, &*cdata, def.xxx_node) + decoder::get_struct_field_names(&cstore.intr, &*cdata, def.index) } -pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: DefId) -> FnvHashMap<ast::NodeId, - Vec<ast::Attribute>> { +pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: DefId) + -> FnvHashMap<DefId, Vec<ast::Attribute>> { let cdata = cstore.get_crate_data(def.krate); decoder::get_struct_field_attrs(&*cdata) } @@ -207,19 +207,19 @@ pub fn get_type<'tcx>(tcx: &ty::ctxt<'tcx>, -> ty::TypeScheme<'tcx> { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_type(&*cdata, def.xxx_node, tcx) + decoder::get_type(&*cdata, def.index, tcx) } pub fn get_trait_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::TraitDef<'tcx> { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_trait_def(&*cdata, def.xxx_node, tcx) + decoder::get_trait_def(&*cdata, def.index, tcx) } pub fn get_adt_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx> { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_adt_def(&cstore.intr, &*cdata, def.xxx_node, tcx) + decoder::get_adt_def(&cstore.intr, &*cdata, def.index, tcx) } pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) @@ -227,7 +227,7 @@ pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_predicates(&*cdata, def.xxx_node, tcx) + decoder::get_predicates(&*cdata, def.index, tcx) } pub fn get_super_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) @@ -235,7 +235,7 @@ pub fn get_super_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_super_predicates(&*cdata, def.xxx_node, tcx) + decoder::get_super_predicates(&*cdata, def.index, tcx) } pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>, @@ -244,7 +244,7 @@ pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>, { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_impl_polarity(&*cdata, def.xxx_node) + decoder::get_impl_polarity(&*cdata, def.index) } pub fn get_custom_coerce_unsized_kind<'tcx>( @@ -254,7 +254,7 @@ pub fn get_custom_coerce_unsized_kind<'tcx>( { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_custom_coerce_unsized_kind(&*cdata, def.xxx_node) + decoder::get_custom_coerce_unsized_kind(&*cdata, def.index) } // Given a def_id for an impl, return the trait it implements, @@ -264,7 +264,7 @@ pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>, -> Option<ty::TraitRef<'tcx>> { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_impl_trait(&*cdata, def.xxx_node, tcx) + decoder::get_impl_trait(&*cdata, def.index, tcx) } pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum) @@ -279,7 +279,7 @@ pub fn each_inherent_implementation_for_type<F>(cstore: &cstore::CStore, F: FnMut(DefId), { let cdata = cstore.get_crate_data(def_id.krate); - decoder::each_inherent_implementation_for_type(&*cdata, def_id.xxx_node, callback) + decoder::each_inherent_implementation_for_type(&*cdata, def_id.index, callback) } pub fn each_implementation_for_trait<F>(cstore: &cstore::CStore, @@ -300,7 +300,7 @@ pub fn get_trait_of_item(cstore: &cstore::CStore, tcx: &ty::ctxt) -> Option<DefId> { let cdata = cstore.get_crate_data(def_id.krate); - decoder::get_trait_of_item(&*cdata, def_id.xxx_node, tcx) + decoder::get_trait_of_item(&*cdata, def_id.index, tcx) } pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore, @@ -308,7 +308,7 @@ pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore, -> Option<DefId> { let cdata = cstore.get_crate_data(def_id.krate); - decoder::get_tuple_struct_definition_if_ctor(&*cdata, def_id.xxx_node) + decoder::get_tuple_struct_definition_if_ctor(&*cdata, def_id.index) } pub fn get_dylib_dependency_formats(cstore: &cstore::CStore, @@ -330,7 +330,7 @@ pub fn get_method_arg_names(cstore: &cstore::CStore, did: DefId) -> Vec<String> { let cdata = cstore.get_crate_data(did.krate); - decoder::get_method_arg_names(&*cdata, did.xxx_node) + decoder::get_method_arg_names(&*cdata, did.index) } pub fn get_reachable_ids(cstore: &cstore::CStore, cnum: ast::CrateNum) @@ -342,24 +342,24 @@ pub fn get_reachable_ids(cstore: &cstore::CStore, cnum: ast::CrateNum) pub fn is_typedef(cstore: &cstore::CStore, did: DefId) -> bool { let cdata = cstore.get_crate_data(did.krate); - decoder::is_typedef(&*cdata, did.xxx_node) + decoder::is_typedef(&*cdata, did.index) } pub fn is_const_fn(cstore: &cstore::CStore, did: DefId) -> bool { let cdata = cstore.get_crate_data(did.krate); - decoder::is_const_fn(&*cdata, did.xxx_node) + decoder::is_const_fn(&*cdata, did.index) } pub fn is_impl(cstore: &cstore::CStore, did: DefId) -> bool { let cdata = cstore.get_crate_data(did.krate); - decoder::is_impl(&*cdata, did.xxx_node) + decoder::is_impl(&*cdata, did.index) } pub fn get_stability(cstore: &cstore::CStore, def: DefId) -> Option<attr::Stability> { let cdata = cstore.get_crate_data(def.krate); - decoder::get_stability(&*cdata, def.xxx_node) + decoder::get_stability(&*cdata, def.index) } pub fn is_staged_api(cstore: &cstore::CStore, krate: ast::CrateNum) -> bool { @@ -369,21 +369,42 @@ pub fn is_staged_api(cstore: &cstore::CStore, krate: ast::CrateNum) -> bool { pub fn get_repr_attrs(cstore: &cstore::CStore, def: DefId) -> Vec<attr::ReprAttr> { let cdata = cstore.get_crate_data(def.krate); - decoder::get_repr_attrs(&*cdata, def.xxx_node) + decoder::get_repr_attrs(&*cdata, def.index) } pub fn is_defaulted_trait(cstore: &cstore::CStore, trait_def_id: DefId) -> bool { let cdata = cstore.get_crate_data(trait_def_id.krate); - decoder::is_defaulted_trait(&*cdata, trait_def_id.xxx_node) + decoder::is_defaulted_trait(&*cdata, trait_def_id.index) } pub fn is_default_impl(cstore: &cstore::CStore, impl_did: DefId) -> bool { let cdata = cstore.get_crate_data(impl_did.krate); - decoder::is_default_impl(&*cdata, impl_did.xxx_node) + decoder::is_default_impl(&*cdata, impl_did.index) } pub fn is_extern_fn(cstore: &cstore::CStore, did: DefId, tcx: &ty::ctxt) -> bool { let cdata = cstore.get_crate_data(did.krate); - decoder::is_extern_fn(&*cdata, did.xxx_node, tcx) + decoder::is_extern_fn(&*cdata, did.index, tcx) } + +pub fn closure_kind<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId) -> ty::ClosureKind { + assert!(!def_id.is_local()); + let cdata = tcx.sess.cstore.get_crate_data(def_id.krate); + decoder::closure_kind(&*cdata, def_id.index) +} + +pub fn closure_ty<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId) -> ty::ClosureTy<'tcx> { + assert!(!def_id.is_local()); + let cdata = tcx.sess.cstore.get_crate_data(def_id.krate); + decoder::closure_ty(&*cdata, def_id.index, tcx) +} + +pub fn def_path(tcx: &ty::ctxt, def: DefId) -> ast_map::DefPath { + let cstore = &tcx.sess.cstore; + let cdata = cstore.get_crate_data(def.krate); + let path = decoder::def_path(&*cdata, def.index); + let local_path = cdata.local_def_path(); + local_path.into_iter().chain(path).collect() +} + diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 915027041bc..48676a2a1b4 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -59,6 +59,7 @@ pub struct ImportedFileMap { pub struct crate_metadata { pub name: String, pub local_path: RefCell<SmallVector<ast_map::PathElem>>, + pub local_def_path: RefCell<ast_map::DefPath>, pub data: MetadataBlob, pub cnum_map: RefCell<cnum_map>, pub cnum: ast::CrateNum, @@ -312,6 +313,23 @@ impl crate_metadata { } } + pub fn local_def_path(&self) -> ast_map::DefPath { + let local_def_path = self.local_def_path.borrow(); + if local_def_path.is_empty() { + let name = ast_map::DefPathData::DetachedCrate(token::intern(&self.name)); + vec![ast_map::DisambiguatedDefPathData { data: name, disambiguator: 0 }] + } else { + local_def_path.clone() + } + } + + pub fn update_local_def_path(&self, candidate: ast_map::DefPath) { + let mut local_def_path = self.local_def_path.borrow_mut(); + if local_def_path.is_empty() || candidate.len() < local_def_path.len() { + *local_def_path = candidate; + } + } + pub fn is_allocator(&self) -> bool { let attrs = decoder::get_crate_attributes(self.data()); attr::contains_name(&attrs, "allocator") diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 8ce31e533de..58e87f1910a 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -30,7 +30,7 @@ use metadata::index; use metadata::inline::InlinedItem; use metadata::tydecode::TyDecoder; use middle::def; -use middle::def_id::DefId; +use middle::def_id::{DefId, DefIndex}; use middle::lang_items; use middle::subst; use middle::ty::{ImplContainer, TraitContainer}; @@ -59,15 +59,15 @@ use syntax::ptr::P; pub type Cmd<'a> = &'a crate_metadata; impl crate_metadata { - fn get_item(&self, item_id: ast::NodeId) -> Option<rbml::Doc> { + fn get_item(&self, item_id: DefIndex) -> Option<rbml::Doc> { self.index.lookup_item(self.data(), item_id).map(|pos| { reader::doc_at(self.data(), pos as usize).unwrap().doc }) } - fn lookup_item(&self, item_id: ast::NodeId) -> rbml::Doc { + fn lookup_item(&self, item_id: DefIndex) -> rbml::Doc { match self.get_item(item_id) { - None => panic!("lookup_item: id not found: {}", item_id), + None => panic!("lookup_item: id not found: {:?}", item_id), Some(d) => d } } @@ -75,7 +75,7 @@ impl crate_metadata { pub fn load_index(data: &[u8]) -> index::Index { let index = reader::get_doc(rbml::Doc::new(data), tag_index); - index::Index::from_buf(index.data, index.start, index.end) + index::Index::from_rbml(index) } pub fn crate_rustc_version(data: &[u8]) -> Option<String> { @@ -170,7 +170,8 @@ fn item_symbol(item: rbml::Doc) -> String { fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> DefId { let id = reader::doc_as_u64(d); - let def_id = DefId { krate: (id >> 32) as u32, xxx_node: id as u32 }; + let index = DefIndex::new((id & 0xFFFF_FFFF) as usize); + let def_id = DefId { krate: (id >> 32) as u32, index: index }; translate_def_id(cdata, def_id) } @@ -203,14 +204,14 @@ fn variant_disr_val(d: rbml::Doc) -> Option<ty::Disr> { fn doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Ty<'tcx> { let tp = reader::get_doc(doc, tag_items_data_item_type); TyDecoder::with_doc(tcx, cdata.cnum, tp, - &mut |_, did| translate_def_id(cdata, did)) + &mut |did| translate_def_id(cdata, did)) .parse_ty() } fn maybe_doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Option<Ty<'tcx>> { reader::maybe_get_doc(doc, tag_items_data_item_type).map(|tp| { TyDecoder::with_doc(tcx, cdata.cnum, tp, - &mut |_, did| translate_def_id(cdata, did)) + &mut |did| translate_def_id(cdata, did)) .parse_ty() }) } @@ -219,7 +220,7 @@ fn doc_method_fty<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> ty::BareFnTy<'tcx> { let tp = reader::get_doc(doc, tag_item_method_fty); TyDecoder::with_doc(tcx, cdata.cnum, tp, - &mut |_, did| translate_def_id(cdata, did)) + &mut |did| translate_def_id(cdata, did)) .parse_bare_fn_ty() } @@ -231,7 +232,7 @@ pub fn item_type<'tcx>(_item_id: DefId, item: rbml::Doc, fn doc_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> ty::TraitRef<'tcx> { TyDecoder::with_doc(tcx, cdata.cnum, doc, - &mut |_, did| translate_def_id(cdata, did)) + &mut |did| translate_def_id(cdata, did)) .parse_trait_ref() } @@ -345,7 +346,7 @@ fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec<ast::Name> { } pub fn get_trait_def<'tcx>(cdata: Cmd, - item_id: ast::NodeId, + item_id: DefIndex, tcx: &ty::ctxt<'tcx>) -> ty::TraitDef<'tcx> { let item_doc = cdata.lookup_item(item_id); @@ -368,7 +369,7 @@ pub fn get_trait_def<'tcx>(cdata: Cmd, pub fn get_adt_def<'tcx>(intr: &IdentInterner, cdata: Cmd, - item_id: ast::NodeId, + item_id: DefIndex, tcx: &ty::ctxt<'tcx>) -> ty::AdtDefMaster<'tcx> { fn get_enum_variants<'tcx>(intr: &IdentInterner, @@ -378,7 +379,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner, let mut disr_val = 0; reader::tagged_docs(doc, tag_items_data_item_variant).map(|p| { let did = translated_def_id(cdata, p); - let item = cdata.lookup_item(did.xxx_node); + let item = cdata.lookup_item(did.index); if let Some(disr) = variant_disr_val(item) { disr_val = disr; @@ -428,7 +429,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner, } let doc = cdata.lookup_item(item_id); - let did = DefId { krate: cdata.cnum, xxx_node: item_id }; + let did = DefId { krate: cdata.cnum, index: item_id }; let (kind, variants) = match item_family(doc) { Enum => (ty::AdtKind::Enum, get_enum_variants(intr, cdata, doc, tcx)), @@ -448,7 +449,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner, // from the ctor. debug!("evaluating the ctor-type of {:?}", variant.name); - let ctor_ty = get_type(cdata, variant.did.xxx_node, tcx).ty; + let ctor_ty = get_type(cdata, variant.did.index, tcx).ty; debug!("evaluating the ctor-type of {:?}.. {:?}", variant.name, ctor_ty); @@ -468,7 +469,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner, } else { for field in &variant.fields { debug!("evaluating the type of {:?}::{:?}", variant.name, field.name); - let ty = get_type(cdata, field.did.xxx_node, tcx).ty; + let ty = get_type(cdata, field.did.index, tcx).ty; field.fulfill_ty(ty); debug!("evaluating the type of {:?}::{:?}: {:?}", variant.name, field.name, ty); @@ -480,7 +481,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner, } pub fn get_predicates<'tcx>(cdata: Cmd, - item_id: ast::NodeId, + item_id: DefIndex, tcx: &ty::ctxt<'tcx>) -> ty::GenericPredicates<'tcx> { @@ -489,7 +490,7 @@ pub fn get_predicates<'tcx>(cdata: Cmd, } pub fn get_super_predicates<'tcx>(cdata: Cmd, - item_id: ast::NodeId, + item_id: DefIndex, tcx: &ty::ctxt<'tcx>) -> ty::GenericPredicates<'tcx> { @@ -497,11 +498,11 @@ pub fn get_super_predicates<'tcx>(cdata: Cmd, doc_predicates(item_doc, tcx, cdata, tag_item_super_predicates) } -pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>) +pub fn get_type<'tcx>(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt<'tcx>) -> ty::TypeScheme<'tcx> { let item_doc = cdata.lookup_item(id); - let t = item_type(DefId { krate: cdata.cnum, xxx_node: id }, item_doc, tcx, + let t = item_type(DefId { krate: cdata.cnum, index: id }, item_doc, tcx, cdata); let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics); ty::TypeScheme { @@ -510,7 +511,7 @@ pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>) } } -pub fn get_stability(cdata: Cmd, id: ast::NodeId) -> Option<attr::Stability> { +pub fn get_stability(cdata: Cmd, id: DefIndex) -> Option<attr::Stability> { let item = cdata.lookup_item(id); reader::maybe_get_doc(item, tag_items_data_item_stability).map(|doc| { let mut decoder = reader::Decoder::new(doc); @@ -518,7 +519,7 @@ pub fn get_stability(cdata: Cmd, id: ast::NodeId) -> Option<attr::Stability> { }) } -pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec<attr::ReprAttr> { +pub fn get_repr_attrs(cdata: Cmd, id: DefIndex) -> Vec<attr::ReprAttr> { let item = cdata.lookup_item(id); match reader::maybe_get_doc(item, tag_items_data_item_repr).map(|doc| { let mut decoder = reader::Decoder::new(doc); @@ -530,7 +531,7 @@ pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec<attr::ReprAttr> { } pub fn get_impl_polarity<'tcx>(cdata: Cmd, - id: ast::NodeId) + id: DefIndex) -> Option<hir::ImplPolarity> { let item_doc = cdata.lookup_item(id); @@ -545,7 +546,7 @@ pub fn get_impl_polarity<'tcx>(cdata: Cmd, pub fn get_custom_coerce_unsized_kind<'tcx>( cdata: Cmd, - id: ast::NodeId) + id: DefIndex) -> Option<ty::adjustment::CustomCoerceUnsized> { let item_doc = cdata.lookup_item(id); @@ -556,7 +557,7 @@ pub fn get_custom_coerce_unsized_kind<'tcx>( } pub fn get_impl_trait<'tcx>(cdata: Cmd, - id: ast::NodeId, + id: DefIndex, tcx: &ty::ctxt<'tcx>) -> Option<ty::TraitRef<'tcx>> { @@ -572,12 +573,12 @@ pub fn get_impl_trait<'tcx>(cdata: Cmd, } } -pub fn get_symbol(cdata: Cmd, id: ast::NodeId) -> String { +pub fn get_symbol(cdata: Cmd, id: DefIndex) -> String { return item_symbol(cdata.lookup_item(id)); } /// If you have a crate_metadata, call get_symbol instead -pub fn get_symbol_from_buf(data: &[u8], id: ast::NodeId) -> String { +pub fn get_symbol_from_buf(data: &[u8], id: DefIndex) -> String { let index = load_index(data); let pos = index.lookup_item(data, id).unwrap(); let doc = reader::doc_at(data, pos as usize).unwrap().doc; @@ -594,18 +595,17 @@ pub enum DefLike { /// Iterates over the language items in the given crate. pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where - F: FnMut(ast::NodeId, usize) -> bool, + F: FnMut(DefIndex, usize) -> bool, { let root = rbml::Doc::new(cdata.data()); let lang_items = reader::get_doc(root, tag_lang_items); reader::tagged_docs(lang_items, tag_lang_items_item).all(|item_doc| { let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id); let id = reader::doc_as_u32(id_doc) as usize; - let node_id_doc = reader::get_doc(item_doc, - tag_lang_items_item_node_id); - let node_id = reader::doc_as_u32(node_id_doc) as ast::NodeId; + let index_doc = reader::get_doc(item_doc, tag_lang_items_item_index); + let index = DefIndex::from_u32(reader::doc_as_u32(index_doc)); - f(node_id, id) + f(index, id) }) } @@ -634,7 +634,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>, }; // Get the item. - match crate_data.get_item(child_def_id.xxx_node) { + match crate_data.get_item(child_def_id.index) { None => {} Some(child_item_doc) => { // Hand off the item to the callback. @@ -652,12 +652,12 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>, for inherent_impl_def_id_doc in reader::tagged_docs(item_doc, tag_items_data_item_inherent_impl) { let inherent_impl_def_id = item_def_id(inherent_impl_def_id_doc, cdata); - if let Some(inherent_impl_doc) = cdata.get_item(inherent_impl_def_id.xxx_node) { + if let Some(inherent_impl_doc) = cdata.get_item(inherent_impl_def_id.index) { for impl_item_def_id_doc in reader::tagged_docs(inherent_impl_doc, tag_item_impl_item) { let impl_item_def_id = item_def_id(impl_item_def_id_doc, cdata); - if let Some(impl_method_doc) = cdata.get_item(impl_item_def_id.xxx_node) { + if let Some(impl_method_doc) = cdata.get_item(impl_item_def_id.index) { if let StaticMethod = item_family(impl_method_doc) { // Hand off the static method to the callback. let static_method_name = item_name(&*intr, impl_method_doc); @@ -693,7 +693,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>, }; // Get the item. - if let Some(child_item_doc) = crate_data.get_item(child_def_id.xxx_node) { + if let Some(child_item_doc) = crate_data.get_item(child_def_id.index) { // Hand off the item to the callback. let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id); // These items have a public visibility because they're part of @@ -706,7 +706,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>, /// Iterates over each child of the given item. pub fn each_child_of_item<F, G>(intr: Rc<IdentInterner>, cdata: Cmd, - id: ast::NodeId, + id: DefIndex, get_crate_data: G, callback: F) where F: FnMut(DefLike, ast::Name, hir::Visibility), @@ -745,11 +745,11 @@ pub fn each_top_level_item_of_crate<F, G>(intr: Rc<IdentInterner>, callback) } -pub fn get_item_path(cdata: Cmd, id: ast::NodeId) -> Vec<hir_map::PathElem> { +pub fn get_item_path(cdata: Cmd, id: DefIndex) -> Vec<hir_map::PathElem> { item_path(cdata.lookup_item(id)) } -pub fn get_item_name(intr: &IdentInterner, cdata: Cmd, id: ast::NodeId) -> ast::Name { +pub fn get_item_name(intr: &IdentInterner, cdata: Cmd, id: DefIndex) -> ast::Name { item_name(intr, cdata.lookup_item(id)) } @@ -757,22 +757,25 @@ pub type DecodeInlinedItem<'a> = Box<for<'tcx> FnMut(Cmd, &ty::ctxt<'tcx>, Vec<hir_map::PathElem>, + hir_map::DefPath, rbml::Doc) - -> Result<&'tcx InlinedItem, Vec<hir_map::PathElem>> + 'a>; + -> Result<&'tcx InlinedItem, (Vec<hir_map::PathElem>, + hir_map::DefPath)> + 'a>; -pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeId, +pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: DefIndex, mut decode_inlined_item: DecodeInlinedItem) -> csearch::FoundAst<'tcx> { - debug!("Looking up item: {}", id); + debug!("Looking up item: {:?}", id); let item_doc = cdata.lookup_item(id); let path = item_path(item_doc).split_last().unwrap().1.to_vec(); - match decode_inlined_item(cdata, tcx, path, item_doc) { + let def_path = def_path(cdata, id); + match decode_inlined_item(cdata, tcx, path, def_path, item_doc) { Ok(ii) => csearch::FoundAst::Found(ii), - Err(path) => { + Err((path, def_path)) => { match item_parent_item(cdata, item_doc) { Some(did) => { - let parent_item = cdata.lookup_item(did.xxx_node); - match decode_inlined_item(cdata, tcx, path, parent_item) { + let parent_item = cdata.lookup_item(did.index); + match decode_inlined_item(cdata, tcx, path, def_path, parent_item) { Ok(ii) => csearch::FoundAst::FoundParent(did, ii), Err(_) => csearch::FoundAst::NotFound } @@ -811,7 +814,7 @@ fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory { } /// Returns the def IDs of all the items in the given implementation. -pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId) +pub fn get_impl_items(cdata: Cmd, impl_id: DefIndex) -> Vec<ty::ImplOrTraitItemId> { reader::tagged_docs(cdata.lookup_item(impl_id), tag_item_impl_item).map(|doc| { let def_id = item_def_id(doc, cdata); @@ -826,13 +829,13 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId) pub fn get_trait_name(intr: Rc<IdentInterner>, cdata: Cmd, - id: ast::NodeId) + id: DefIndex) -> ast::Name { let doc = cdata.lookup_item(id); item_name(&*intr, doc) } -pub fn is_static_method(cdata: Cmd, id: ast::NodeId) -> bool { +pub fn is_static_method(cdata: Cmd, id: DefIndex) -> bool { let doc = cdata.lookup_item(id); match item_sort(doc) { Some('r') | Some('p') => { @@ -844,7 +847,7 @@ pub fn is_static_method(cdata: Cmd, id: ast::NodeId) -> bool { pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>, cdata: Cmd, - id: ast::NodeId, + id: DefIndex, tcx: &ty::ctxt<'tcx>) -> ty::ImplOrTraitItem<'tcx> { let item_doc = cdata.lookup_item(id); @@ -852,7 +855,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>, let def_id = item_def_id(item_doc, cdata); let container_id = item_require_parent_item(cdata, item_doc); - let container_doc = cdata.lookup_item(container_id.xxx_node); + let container_doc = cdata.lookup_item(container_id.index); let container = match item_family(container_doc) { Trait => TraitContainer(container_id), _ => ImplContainer(container_id), @@ -902,7 +905,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>, } } -pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId) +pub fn get_trait_item_def_ids(cdata: Cmd, id: DefIndex) -> Vec<ty::ImplOrTraitItemId> { let item = cdata.lookup_item(id); reader::tagged_docs(item, tag_item_trait_item).map(|mth| { @@ -916,7 +919,7 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId) }).collect() } -pub fn get_item_variances(cdata: Cmd, id: ast::NodeId) -> ty::ItemVariances { +pub fn get_item_variances(cdata: Cmd, id: DefIndex) -> ty::ItemVariances { let item_doc = cdata.lookup_item(id); let variance_doc = reader::get_doc(item_doc, tag_item_variances); let mut decoder = reader::Decoder::new(variance_doc); @@ -925,19 +928,19 @@ pub fn get_item_variances(cdata: Cmd, id: ast::NodeId) -> ty::ItemVariances { pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>, cdata: Cmd, - id: ast::NodeId, + id: DefIndex, tcx: &ty::ctxt<'tcx>) -> Vec<Rc<ty::Method<'tcx>>> { let item = cdata.lookup_item(id); reader::tagged_docs(item, tag_item_trait_item).filter_map(|mth_id| { let did = item_def_id(mth_id, cdata); - let mth = cdata.lookup_item(did.xxx_node); + let mth = cdata.lookup_item(did.index); if item_sort(mth) == Some('p') { let trait_item = get_impl_or_trait_item(intr.clone(), cdata, - did.xxx_node, + did.index, tcx); if let ty::MethodTraitItem(ref method) = trait_item { Some((*method).clone()) @@ -952,7 +955,7 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>, pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>, cdata: Cmd, - id: ast::NodeId, + id: DefIndex, tcx: &ty::ctxt<'tcx>) -> Vec<Rc<ty::AssociatedConst<'tcx>>> { let item = cdata.lookup_item(id); @@ -960,13 +963,13 @@ pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>, [tag_item_trait_item, tag_item_impl_item].iter().flat_map(|&tag| { reader::tagged_docs(item, tag).filter_map(|ac_id| { let did = item_def_id(ac_id, cdata); - let ac_doc = cdata.lookup_item(did.xxx_node); + let ac_doc = cdata.lookup_item(did.index); match item_sort(ac_doc) { Some('C') | Some('c') => { let trait_item = get_impl_or_trait_item(intr.clone(), cdata, - did.xxx_node, + did.index, tcx); if let ty::ConstTraitItem(ref ac) = trait_item { Some((*ac).clone()) @@ -981,7 +984,7 @@ pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>, } pub fn get_type_name_if_impl(cdata: Cmd, - node_id: ast::NodeId) -> Option<ast::Name> { + node_id: DefIndex) -> Option<ast::Name> { let item = cdata.lookup_item(node_id); if item_family(item) != Impl { return None; @@ -994,7 +997,7 @@ pub fn get_type_name_if_impl(cdata: Cmd, pub fn get_methods_if_impl(intr: Rc<IdentInterner>, cdata: Cmd, - node_id: ast::NodeId) + node_id: DefIndex) -> Option<Vec<MethodInfo> > { let item = cdata.lookup_item(node_id); if item_family(item) != Impl { @@ -1011,7 +1014,7 @@ pub fn get_methods_if_impl(intr: Rc<IdentInterner>, let mut impl_methods = Vec::new(); for impl_method_id in impl_method_ids { - let impl_method_doc = cdata.lookup_item(impl_method_id.xxx_node); + let impl_method_doc = cdata.lookup_item(impl_method_id.index); let family = item_family(impl_method_doc); match family { StaticMethod | Method => { @@ -1031,7 +1034,7 @@ pub fn get_methods_if_impl(intr: Rc<IdentInterner>, /// If node_id is the constructor of a tuple struct, retrieve the NodeId of /// the actual type definition, otherwise, return None pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd, - node_id: ast::NodeId) + node_id: DefIndex) -> Option<DefId> { let item = cdata.lookup_item(node_id); @@ -1041,24 +1044,24 @@ pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd, } pub fn get_item_attrs(cdata: Cmd, - orig_node_id: ast::NodeId) + orig_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 node_id = get_tuple_struct_definition_if_ctor(cdata, orig_node_id); - let node_id = node_id.map(|x| x.xxx_node).unwrap_or(orig_node_id); + let node_id = node_id.map(|x| x.index).unwrap_or(orig_node_id); let item = cdata.lookup_item(node_id); get_attributes(item) } -pub fn get_struct_field_attrs(cdata: Cmd) -> FnvHashMap<ast::NodeId, Vec<ast::Attribute>> { +pub fn get_struct_field_attrs(cdata: Cmd) -> FnvHashMap<DefId, Vec<ast::Attribute>> { let data = rbml::Doc::new(cdata.data()); let fields = reader::get_doc(data, tag_struct_fields); reader::tagged_docs(fields, tag_struct_field).map(|field| { - let id = reader::doc_as_u32(reader::get_doc(field, tag_struct_field_id)); + let def_id = translated_def_id(cdata, reader::get_doc(field, tag_def_id)); let attrs = get_attributes(field); - (id, attrs) + (def_id, attrs) }).collect() } @@ -1070,7 +1073,7 @@ fn struct_field_family_to_visibility(family: Family) -> hir::Visibility { } } -pub fn get_struct_field_names(intr: &IdentInterner, cdata: Cmd, id: ast::NodeId) +pub fn get_struct_field_names(intr: &IdentInterner, cdata: Cmd, id: DefIndex) -> Vec<ast::Name> { let item = cdata.lookup_item(id); reader::tagged_docs(item, tag_item_field).map(|an_item| { @@ -1228,14 +1231,14 @@ pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Write) -> io::Result<()> // crate to the correct local crate number. pub fn translate_def_id(cdata: Cmd, did: DefId) -> DefId { if did.is_local() { - return DefId { krate: cdata.cnum, xxx_node: did.xxx_node }; + return DefId { krate: cdata.cnum, index: did.index }; } match cdata.cnum_map.borrow().get(&did.krate) { Some(&n) => { DefId { krate: n, - xxx_node: did.xxx_node, + index: did.index, } } None => panic!("didn't find a crate in the cnum_map") @@ -1246,12 +1249,12 @@ pub fn translate_def_id(cdata: Cmd, did: DefId) -> DefId { // for an external crate. fn reverse_translate_def_id(cdata: Cmd, did: DefId) -> Option<DefId> { if did.krate == cdata.cnum { - return Some(DefId { krate: LOCAL_CRATE, xxx_node: did.xxx_node }); + return Some(DefId { krate: LOCAL_CRATE, index: did.index }); } for (&local, &global) in cdata.cnum_map.borrow().iter() { if global == did.krate { - return Some(DefId { krate: local, xxx_node: did.xxx_node }); + return Some(DefId { krate: local, index: did.index }); } } @@ -1259,7 +1262,7 @@ fn reverse_translate_def_id(cdata: Cmd, did: DefId) -> Option<DefId> { } pub fn each_inherent_implementation_for_type<F>(cdata: Cmd, - id: ast::NodeId, + id: DefIndex, mut callback: F) where F: FnMut(DefId), { @@ -1277,7 +1280,7 @@ pub fn each_implementation_for_trait<F>(cdata: Cmd, F: FnMut(DefId), { if cdata.cnum == def_id.krate { - let item_doc = cdata.lookup_item(def_id.xxx_node); + let item_doc = cdata.lookup_item(def_id.index); for impl_doc in reader::tagged_docs(item_doc, tag_items_data_item_extension_impl) { callback(item_def_id(impl_doc, cdata)); } @@ -1299,14 +1302,14 @@ pub fn each_implementation_for_trait<F>(cdata: Cmd, } } -pub fn get_trait_of_item(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) +pub fn get_trait_of_item(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt) -> 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, }; - let parent_item_doc = cdata.lookup_item(parent_item_id.xxx_node); + let parent_item_doc = cdata.lookup_item(parent_item_id.index); match item_family(parent_item_doc) { Trait => Some(item_def_id(parent_item_doc, cdata)), Impl | DefaultImpl => { @@ -1332,9 +1335,9 @@ pub fn get_native_libraries(cdata: Cmd) }).collect() } -pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<ast::NodeId> { +pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<DefIndex> { reader::maybe_get_doc(rbml::Doc::new(data), tag_plugin_registrar_fn) - .map(|doc| reader::doc_as_u32(doc)) + .map(|doc| DefIndex::from_u32(reader::doc_as_u32(doc))) } pub fn each_exported_macro<F>(data: &[u8], intr: &IdentInterner, mut f: F) where @@ -1386,7 +1389,7 @@ pub fn get_missing_lang_items(cdata: Cmd) }).collect() } -pub fn get_method_arg_names(cdata: Cmd, id: ast::NodeId) -> Vec<String> { +pub fn get_method_arg_names(cdata: Cmd, id: DefIndex) -> Vec<String> { let method_doc = cdata.lookup_item(id); match reader::maybe_get_doc(method_doc, tag_method_argument_names) { Some(args_doc) => { @@ -1404,12 +1407,12 @@ pub fn get_reachable_ids(cdata: Cmd) -> Vec<DefId> { reader::tagged_docs(items, tag_reachable_id).map(|doc| { DefId { krate: cdata.cnum, - xxx_node: reader::doc_as_u32(doc), + index: DefIndex::from_u32(reader::doc_as_u32(doc)), } }).collect() } -pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool { +pub fn is_typedef(cdata: Cmd, id: DefIndex) -> bool { let item_doc = cdata.lookup_item(id); match item_family(item_doc) { Type => true, @@ -1417,7 +1420,7 @@ pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool { } } -pub fn is_const_fn(cdata: Cmd, id: ast::NodeId) -> bool { +pub fn is_const_fn(cdata: Cmd, id: DefIndex) -> bool { let item_doc = cdata.lookup_item(id); match fn_constness(item_doc) { hir::Constness::Const => true, @@ -1425,7 +1428,7 @@ pub fn is_const_fn(cdata: Cmd, id: ast::NodeId) -> bool { } } -pub fn is_impl(cdata: Cmd, id: ast::NodeId) -> bool { +pub fn is_impl(cdata: Cmd, id: DefIndex) -> bool { let item_doc = cdata.lookup_item(id); match item_family(item_doc) { Impl => true, @@ -1445,7 +1448,7 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc, for p in reader::tagged_docs(doc, tag_type_param_def) { let bd = TyDecoder::with_doc(tcx, cdata.cnum, p, - &mut |_, did| translate_def_id(cdata, did)) + &mut |did| translate_def_id(cdata, did)) .parse_type_param_def(); types.push(bd.space, bd); } @@ -1467,7 +1470,7 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc, let bounds = reader::tagged_docs(rp_doc, tag_items_data_region).map(|p| { TyDecoder::with_doc(tcx, cdata.cnum, p, - &mut |_, did| translate_def_id(cdata, did)) + &mut |did| translate_def_id(cdata, did)) .parse_region() }).collect(); @@ -1497,7 +1500,7 @@ fn doc_predicates<'tcx>(base_doc: rbml::Doc, let data_doc = reader::get_doc(predicate_doc, tag_predicate_data); let data = TyDecoder::with_doc(tcx, cdata.cnum, data_doc, - &mut |_, did| translate_def_id(cdata, did)) + &mut |did| translate_def_id(cdata, did)) .parse_predicate(); predicates.push(space, data); @@ -1506,14 +1509,14 @@ fn doc_predicates<'tcx>(base_doc: rbml::Doc, ty::GenericPredicates { predicates: predicates } } -pub fn is_defaulted_trait(cdata: Cmd, trait_id: ast::NodeId) -> bool { +pub fn is_defaulted_trait(cdata: Cmd, trait_id: DefIndex) -> bool { let trait_doc = cdata.lookup_item(trait_id); assert!(item_family(trait_doc) == Family::Trait); let defaulted_doc = reader::get_doc(trait_doc, tag_defaulted_trait); reader::doc_as_u8(defaulted_doc) != 0 } -pub fn is_default_impl(cdata: Cmd, impl_id: ast::NodeId) -> bool { +pub fn is_default_impl(cdata: Cmd, impl_id: DefIndex) -> bool { let impl_doc = cdata.lookup_item(impl_id); item_family(impl_doc) == Family::DefaultImpl } @@ -1528,7 +1531,7 @@ pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> { }).collect() } -pub fn is_extern_fn(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) -> bool { +pub fn is_extern_fn(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt) -> bool { let item_doc = match cdata.get_item(id) { Some(doc) => doc, None => return false, @@ -1543,3 +1546,42 @@ pub fn is_extern_fn(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) -> bool { false } } + +pub fn closure_kind(cdata: Cmd, closure_id: DefIndex) -> ty::ClosureKind { + let closure_doc = cdata.lookup_item(closure_id); + let closure_kind_doc = reader::get_doc(closure_doc, tag_items_closure_kind); + let mut decoder = reader::Decoder::new(closure_kind_doc); + ty::ClosureKind::decode(&mut decoder).unwrap() +} + +pub fn closure_ty<'tcx>(cdata: Cmd, closure_id: DefIndex, tcx: &ty::ctxt<'tcx>) + -> ty::ClosureTy<'tcx> { + let closure_doc = cdata.lookup_item(closure_id); + let closure_ty_doc = reader::get_doc(closure_doc, tag_items_closure_ty); + TyDecoder::with_doc(tcx, cdata.cnum, closure_ty_doc, &mut |did| translate_def_id(cdata, did)) + .parse_closure_ty() +} + +fn def_key(item_doc: rbml::Doc) -> hir_map::DefKey { + match reader::maybe_get_doc(item_doc, tag_def_key) { + Some(def_key_doc) => { + let mut decoder = reader::Decoder::new(def_key_doc); + hir_map::DefKey::decode(&mut decoder).unwrap() + } + None => { + panic!("failed to find block with tag {:?} for item with family {:?}", + tag_def_key, + item_family(item_doc)) + } + } +} + +pub fn def_path(cdata: Cmd, id: DefIndex) -> hir_map::DefPath { + debug!("def_path(id={:?})", id); + hir_map::definitions::make_def_path(id, |parent| { + debug!("def_path: parent={:?}", parent); + let parent_doc = cdata.lookup_item(parent); + def_key(parent_doc) + }) +} + diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 14e5e8b41ff..f637545e2e9 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -20,10 +20,10 @@ use metadata::cstore; use metadata::cstore::LOCAL_CRATE; use metadata::decoder; use metadata::tyencode; -use metadata::index::{self, IndexEntry}; +use metadata::index::IndexData; use metadata::inline::InlinedItemRef; use middle::def; -use middle::def_id::DefId; +use middle::def_id::{CRATE_DEF_INDEX, DefId}; use middle::dependency_format::Linkage; use middle::stability; use middle::ty::{self, Ty}; @@ -34,6 +34,7 @@ use std::cell::RefCell; use std::io::prelude::*; use std::io::{Cursor, SeekFrom}; use std::rc::Rc; +use std::u32; use syntax::abi; use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID, CrateNum}; use syntax::attr; @@ -93,6 +94,26 @@ fn encode_def_id(rbml_w: &mut Encoder, id: DefId) { rbml_w.wr_tagged_u64(tag_def_id, def_to_u64(id)); } +/// For every DefId that we create a metadata item for, we include a +/// serialized copy of its DefKey, which allows us to recreate a path. +fn encode_def_id_and_key(ecx: &EncodeContext, + rbml_w: &mut Encoder, + def_id: DefId) +{ + encode_def_id(rbml_w, def_id); + encode_def_key(ecx, rbml_w, def_id); +} + +fn encode_def_key(ecx: &EncodeContext, + rbml_w: &mut Encoder, + def_id: DefId) +{ + rbml_w.start_tag(tag_def_key); + let def_key = ecx.tcx.map.def_key(def_id); + def_key.encode(rbml_w); + rbml_w.end_tag(); +} + fn encode_trait_ref<'a, 'tcx>(rbml_w: &mut Encoder, ecx: &EncodeContext<'a, 'tcx>, trait_ref: ty::TraitRef<'tcx>, @@ -115,11 +136,12 @@ fn encode_family(rbml_w: &mut Encoder, c: char) { } pub fn def_to_u64(did: DefId) -> u64 { - (did.krate as u64) << 32 | (did.xxx_node as u64) + assert!(did.index.as_u32() < u32::MAX); + (did.krate as u64) << 32 | (did.index.as_usize() as u64) } pub fn def_to_string(did: DefId) -> String { - format!("{}:{}", did.krate, did.xxx_node) + format!("{}:{}", did.krate, did.index.as_usize()) } fn encode_item_variances(rbml_w: &mut Encoder, @@ -280,7 +302,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext, rbml_w: &mut Encoder, id: NodeId, vis: hir::Visibility, - index: &mut Vec<IndexEntry>) { + index: &mut IndexData) { debug!("encode_enum_variant_info(id={})", id); let mut disr_val = 0; @@ -297,12 +319,9 @@ fn encode_enum_variant_info(ecx: &EncodeContext, } } - index.push(IndexEntry { - node: vid.xxx_node, - pos: rbml_w.mark_stable_position(), - }); + index.record(vid, rbml_w); rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, vid); + encode_def_id_and_key(ecx, rbml_w, vid); encode_family(rbml_w, match variant.kind() { ty::VariantKind::Unit | ty::VariantKind::Tuple => 'v', ty::VariantKind::Dict => 'V' @@ -522,7 +541,7 @@ fn encode_info_for_mod(ecx: &EncodeContext, name: Name, vis: hir::Visibility) { rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, ecx.tcx.map.local_def_id(id)); + encode_def_id_and_key(ecx, rbml_w, ecx.tcx.map.local_def_id(id)); encode_family(rbml_w, 'm'); encode_name(rbml_w, name); debug!("(encoding info for module) encoding info for module ID {}", id); @@ -631,21 +650,17 @@ fn encode_parent_sort(rbml_w: &mut Encoder, sort: char) { fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, field: ty::FieldDef<'tcx>, - global_index: &mut Vec<IndexEntry>) { + global_index: &mut IndexData) { let nm = field.name; let id = ecx.local_id(field.did); - let pos = rbml_w.mark_stable_position(); - global_index.push(IndexEntry { - node: id, - pos: pos, - }); + global_index.record(field.did, rbml_w); rbml_w.start_tag(tag_items_data_item); debug!("encode_field: encoding {} {}", nm, id); encode_struct_field_family(rbml_w, field.vis); encode_name(rbml_w, nm); encode_bounds_and_type_for_item(rbml_w, ecx, id); - encode_def_id(rbml_w, ecx.tcx.map.local_def_id(id)); + encode_def_id_and_key(ecx, rbml_w, field.did); let stab = stability::lookup(ecx.tcx, field.did); encode_stability(rbml_w, stab); @@ -657,15 +672,14 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext, rbml_w: &mut Encoder, name: Name, ctor_id: NodeId, - index: &mut Vec<IndexEntry>, + index: &mut IndexData, struct_id: NodeId) { - index.push(IndexEntry { - node: ctor_id, - pos: rbml_w.mark_stable_position(), - }); + let ctor_def_id = ecx.tcx.map.local_def_id(ctor_id); + + index.record(ctor_def_id, rbml_w); rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, ecx.tcx.map.local_def_id(ctor_id)); + encode_def_id_and_key(ecx, rbml_w, ctor_def_id); encode_family(rbml_w, 'o'); encode_bounds_and_type_for_item(rbml_w, ecx, ctor_id); encode_name(rbml_w, name); @@ -775,7 +789,7 @@ fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder, fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, method_ty: &ty::Method<'tcx>) { - encode_def_id(rbml_w, method_ty.def_id); + encode_def_id_and_key(ecx, rbml_w, method_ty.def_id); encode_name(rbml_w, method_ty.name); encode_generics(rbml_w, ecx, &method_ty.generics, &method_ty.predicates, tag_method_ty_generics); @@ -802,7 +816,7 @@ fn encode_info_for_associated_const(ecx: &EncodeContext, rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, associated_const.def_id); + encode_def_id_and_key(ecx, rbml_w, associated_const.def_id); encode_name(rbml_w, associated_const.name); encode_visibility(rbml_w, associated_const.vis); encode_family(rbml_w, 'C'); @@ -891,7 +905,7 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, associated_type.def_id); + encode_def_id_and_key(ecx, rbml_w, associated_type.def_id); encode_name(rbml_w, associated_type.name); encode_visibility(rbml_w, associated_type.vis); encode_family(rbml_w, 'y'); @@ -1000,19 +1014,11 @@ fn encode_stability(rbml_w: &mut Encoder, stab_opt: Option<&attr::Stability>) { fn encode_info_for_item(ecx: &EncodeContext, rbml_w: &mut Encoder, item: &hir::Item, - index: &mut Vec<IndexEntry>, + index: &mut IndexData, path: PathElems, vis: hir::Visibility) { let tcx = ecx.tcx; - fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder, - index: &mut Vec<IndexEntry>) { - index.push(IndexEntry { - node: item.id, - pos: rbml_w.mark_stable_position(), - }); - } - debug!("encoding info for item at {}", tcx.sess.codemap().span_to_string(item.span)); @@ -1021,9 +1027,9 @@ fn encode_info_for_item(ecx: &EncodeContext, match item.node { hir::ItemStatic(_, m, _) => { - add_to_index(item, rbml_w, index); + index.record(def_id, rbml_w); rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, def_id); + encode_def_id_and_key(ecx, rbml_w, def_id); if m == hir::MutMutable { encode_family(rbml_w, 'b'); } else { @@ -1039,9 +1045,9 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.end_tag(); } hir::ItemConst(_, _) => { - add_to_index(item, rbml_w, index); + index.record(def_id, rbml_w); rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, def_id); + encode_def_id_and_key(ecx, rbml_w, def_id); encode_family(rbml_w, 'C'); encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_name(rbml_w, item.name); @@ -1053,9 +1059,9 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.end_tag(); } hir::ItemFn(ref decl, _, constness, _, ref generics, _) => { - add_to_index(item, rbml_w, index); + index.record(def_id, rbml_w); rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, def_id); + encode_def_id_and_key(ecx, rbml_w, def_id); encode_family(rbml_w, FN_FAMILY); let tps_len = generics.ty_params.len(); encode_bounds_and_type_for_item(rbml_w, ecx, item.id); @@ -1076,7 +1082,7 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.end_tag(); } hir::ItemMod(ref m) => { - add_to_index(item, rbml_w, index); + index.record(def_id, rbml_w); encode_info_for_mod(ecx, rbml_w, m, @@ -1087,9 +1093,9 @@ fn encode_info_for_item(ecx: &EncodeContext, item.vis); } hir::ItemForeignMod(ref fm) => { - add_to_index(item, rbml_w, index); + index.record(def_id, rbml_w); rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, def_id); + encode_def_id_and_key(ecx, rbml_w, def_id); encode_family(rbml_w, 'n'); encode_name(rbml_w, item.name); encode_path(rbml_w, path); @@ -1104,9 +1110,9 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.end_tag(); } hir::ItemTy(..) => { - add_to_index(item, rbml_w, index); + index.record(def_id, rbml_w); rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, def_id); + encode_def_id_and_key(ecx, rbml_w, def_id); encode_family(rbml_w, 'y'); encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_name(rbml_w, item.name); @@ -1116,10 +1122,10 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.end_tag(); } hir::ItemEnum(ref enum_definition, _) => { - add_to_index(item, rbml_w, index); + index.record(def_id, rbml_w); rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, def_id); + encode_def_id_and_key(ecx, rbml_w, def_id); encode_family(rbml_w, 't'); encode_item_variances(rbml_w, ecx, item.id); encode_bounds_and_type_for_item(rbml_w, ecx, item.id); @@ -1154,11 +1160,11 @@ fn encode_info_for_item(ecx: &EncodeContext, } /* Index the class*/ - add_to_index(item, rbml_w, index); + index.record(def_id, rbml_w); /* Now, make an item for the class itself */ rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, def_id); + encode_def_id_and_key(ecx, rbml_w, def_id); encode_family(rbml_w, 'S'); encode_bounds_and_type_for_item(rbml_w, ecx, item.id); @@ -1192,9 +1198,9 @@ fn encode_info_for_item(ecx: &EncodeContext, } } hir::ItemDefaultImpl(unsafety, _) => { - add_to_index(item, rbml_w, index); + index.record(def_id, rbml_w); rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, def_id); + encode_def_id_and_key(ecx, rbml_w, def_id); encode_family(rbml_w, 'd'); encode_name(rbml_w, item.name); encode_unsafety(rbml_w, unsafety); @@ -1209,9 +1215,9 @@ fn encode_info_for_item(ecx: &EncodeContext, let impl_items = tcx.impl_items.borrow(); let items = impl_items.get(&def_id).unwrap(); - add_to_index(item, rbml_w, index); + index.record(def_id, rbml_w); rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, def_id); + encode_def_id_and_key(ecx, rbml_w, def_id); encode_family(rbml_w, 'i'); encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_name(rbml_w, item.name); @@ -1272,10 +1278,7 @@ fn encode_info_for_item(ecx: &EncodeContext, None }; - index.push(IndexEntry { - node: trait_item_def_id.def_id().xxx_node, - pos: rbml_w.mark_stable_position(), - }); + index.record(trait_item_def_id.def_id(), rbml_w); match tcx.impl_or_trait_item(trait_item_def_id.def_id()) { ty::ConstTraitItem(ref associated_const) => { @@ -1307,9 +1310,9 @@ fn encode_info_for_item(ecx: &EncodeContext, } } hir::ItemTrait(_, _, _, ref ms) => { - add_to_index(item, rbml_w, index); + index.record(def_id, rbml_w); rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, def_id); + encode_def_id_and_key(ecx, rbml_w, def_id); encode_family(rbml_w, 'I'); encode_item_variances(rbml_w, ecx, item.id); let trait_def = tcx.lookup_trait_def(def_id); @@ -1363,10 +1366,7 @@ fn encode_info_for_item(ecx: &EncodeContext, for (i, &item_def_id) in r.iter().enumerate() { assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE); - index.push(IndexEntry { - node: item_def_id.def_id().xxx_node, - pos: rbml_w.mark_stable_position(), - }); + index.record(item_def_id.def_id(), rbml_w); rbml_w.start_tag(tag_items_data_item); @@ -1381,7 +1381,7 @@ fn encode_info_for_item(ecx: &EncodeContext, match trait_item_type { ty::ConstTraitItem(associated_const) => { encode_name(rbml_w, associated_const.name); - encode_def_id(rbml_w, associated_const.def_id); + encode_def_id_and_key(ecx, rbml_w, associated_const.def_id); encode_visibility(rbml_w, associated_const.vis); let elem = ast_map::PathName(associated_const.name); @@ -1422,7 +1422,7 @@ fn encode_info_for_item(ecx: &EncodeContext, } ty::TypeTraitItem(associated_type) => { encode_name(rbml_w, associated_type.name); - encode_def_id(rbml_w, associated_type.def_id); + encode_def_id_and_key(ecx, rbml_w, associated_type.def_id); let elem = ast_map::PathName(associated_type.name); encode_path(rbml_w, @@ -1491,16 +1491,15 @@ fn encode_info_for_item(ecx: &EncodeContext, fn encode_info_for_foreign_item(ecx: &EncodeContext, rbml_w: &mut Encoder, nitem: &hir::ForeignItem, - index: &mut Vec<IndexEntry>, + index: &mut IndexData, path: PathElems, abi: abi::Abi) { - index.push(IndexEntry { - node: nitem.id, - pos: rbml_w.mark_stable_position(), - }); + let def_id = ecx.tcx.map.local_def_id(nitem.id); + + index.record(def_id, rbml_w); rbml_w.start_tag(tag_items_data_item); - encode_def_id(rbml_w, ecx.tcx.map.local_def_id(nitem.id)); + encode_def_id_and_key(ecx, rbml_w, def_id); encode_visibility(rbml_w, nitem.vis); match nitem.node { hir::ForeignItemFn(ref fndecl, _) => { @@ -1534,12 +1533,39 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, rbml_w.end_tag(); } -fn my_visit_expr(_e: &hir::Expr) { } +fn my_visit_expr(expr: &hir::Expr, + rbml_w: &mut Encoder, + ecx: &EncodeContext, + index: &mut IndexData) { + match expr.node { + hir::ExprClosure(..) => { + let def_id = ecx.tcx.map.local_def_id(expr.id); + + index.record(def_id, rbml_w); + + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, def_id); + + rbml_w.start_tag(tag_items_closure_ty); + write_closure_type(ecx, rbml_w, &ecx.tcx.tables.borrow().closure_tys[&def_id]); + rbml_w.end_tag(); + + rbml_w.start_tag(tag_items_closure_kind); + ecx.tcx.closure_kind(def_id).encode(rbml_w).unwrap(); + rbml_w.end_tag(); + + ecx.tcx.map.with_path(expr.id, |path| encode_path(rbml_w, path)); + + rbml_w.end_tag(); + } + _ => { } + } +} fn my_visit_item(i: &hir::Item, rbml_w: &mut Encoder, ecx: &EncodeContext, - index: &mut Vec<IndexEntry>) { + index: &mut IndexData) { ecx.tcx.map.with_path(i.id, |path| { encode_info_for_item(ecx, rbml_w, i, index, path, i.vis); }); @@ -1548,7 +1574,7 @@ fn my_visit_item(i: &hir::Item, fn my_visit_foreign_item(ni: &hir::ForeignItem, rbml_w: &mut Encoder, ecx: &EncodeContext, - index: &mut Vec<IndexEntry>) { + index: &mut IndexData) { debug!("writing foreign item {}::{}", ecx.tcx.map.path_to_string(ni.id), ni.name); @@ -1564,40 +1590,32 @@ fn my_visit_foreign_item(ni: &hir::ForeignItem, struct EncodeVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> { rbml_w_for_visit_item: &'a mut Encoder<'b>, ecx: &'a EncodeContext<'c,'tcx>, - index: &'a mut Vec<IndexEntry>, + index: &'a mut IndexData, } impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for EncodeVisitor<'a, 'b, 'c, 'tcx> { fn visit_expr(&mut self, ex: &hir::Expr) { visit::walk_expr(self, ex); - my_visit_expr(ex); + my_visit_expr(ex, self.rbml_w_for_visit_item, self.ecx, self.index); } fn visit_item(&mut self, i: &hir::Item) { visit::walk_item(self, i); - my_visit_item(i, - self.rbml_w_for_visit_item, - self.ecx, - self.index); + my_visit_item(i, self.rbml_w_for_visit_item, self.ecx, self.index); } fn visit_foreign_item(&mut self, ni: &hir::ForeignItem) { visit::walk_foreign_item(self, ni); - my_visit_foreign_item(ni, - self.rbml_w_for_visit_item, - self.ecx, - self.index); + my_visit_foreign_item(ni, self.rbml_w_for_visit_item, self.ecx, self.index); } } fn encode_info_for_items(ecx: &EncodeContext, rbml_w: &mut Encoder, krate: &hir::Crate) - -> Vec<IndexEntry> { - let mut index = Vec::new(); + -> IndexData { + let mut index = IndexData::new(ecx.tcx.map.num_local_def_ids()); + rbml_w.start_tag(tag_items_data); - index.push(IndexEntry { - node: CRATE_NODE_ID, - pos: rbml_w.mark_stable_position(), - }); + index.record_index(CRATE_DEF_INDEX, rbml_w); encode_info_for_mod(ecx, rbml_w, &krate.module, @@ -1617,13 +1635,9 @@ fn encode_info_for_items(ecx: &EncodeContext, index } - - - -fn encode_index(rbml_w: &mut Encoder, index: Vec<IndexEntry>) -{ +fn encode_index(rbml_w: &mut Encoder, index: IndexData) { rbml_w.start_tag(tag_index); - index::write_index(index, rbml_w.writer); + index.write_index(rbml_w.writer); rbml_w.end_tag(); } @@ -1737,12 +1751,12 @@ fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) { fn encode_lang_items(ecx: &EncodeContext, rbml_w: &mut Encoder) { rbml_w.start_tag(tag_lang_items); - for (i, &def_id) in ecx.tcx.lang_items.items() { - if let Some(id) = def_id { - if let Some(id) = ecx.tcx.map.as_local_node_id(id) { + for (i, &opt_def_id) in ecx.tcx.lang_items.items() { + if let Some(def_id) = opt_def_id { + if def_id.is_local() { rbml_w.start_tag(tag_lang_items_item); rbml_w.wr_tagged_u32(tag_lang_items_item_id, i as u32); - rbml_w.wr_tagged_u32(tag_lang_items_item_node_id, id as u32); + rbml_w.wr_tagged_u32(tag_lang_items_item_index, def_id.index.as_u32()); rbml_w.end_tag(); } } @@ -1776,7 +1790,10 @@ fn encode_native_libraries(ecx: &EncodeContext, rbml_w: &mut Encoder) { fn encode_plugin_registrar_fn(ecx: &EncodeContext, rbml_w: &mut Encoder) { match ecx.tcx.sess.plugin_registrar_fn.get() { - Some(id) => { rbml_w.wr_tagged_u32(tag_plugin_registrar_fn, id); } + Some(id) => { + let def_id = ecx.tcx.map.local_def_id(id); + rbml_w.wr_tagged_u32(tag_plugin_registrar_fn, def_id.index.as_u32()); + } None => {} } } @@ -1821,24 +1838,26 @@ fn encode_macro_defs(rbml_w: &mut Encoder, rbml_w.end_tag(); } -fn encode_struct_field_attrs(rbml_w: &mut Encoder, krate: &hir::Crate) { - struct StructFieldVisitor<'a, 'b:'a> { - rbml_w: &'a mut Encoder<'b>, +fn encode_struct_field_attrs(ecx: &EncodeContext, + rbml_w: &mut Encoder, + krate: &hir::Crate) { + struct StructFieldVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> { + ecx: &'a EncodeContext<'b, 'tcx>, + rbml_w: &'a mut Encoder<'c>, } - impl<'a, 'b, 'v> Visitor<'v> for StructFieldVisitor<'a, 'b> { + impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for StructFieldVisitor<'a, 'b, 'c, 'tcx> { fn visit_struct_field(&mut self, field: &hir::StructField) { self.rbml_w.start_tag(tag_struct_field); - self.rbml_w.wr_tagged_u32(tag_struct_field_id, field.node.id); + let def_id = self.ecx.tcx.map.local_def_id(field.node.id); + encode_def_id(self.rbml_w, def_id); encode_attributes(self.rbml_w, &field.node.attrs); self.rbml_w.end_tag(); } } rbml_w.start_tag(tag_struct_fields); - visit::walk_crate(&mut StructFieldVisitor { - rbml_w: rbml_w - }, krate); + visit::walk_crate(&mut StructFieldVisitor { ecx: ecx, rbml_w: rbml_w }, krate); rbml_w.end_tag(); } @@ -1925,8 +1944,9 @@ fn encode_misc_info(ecx: &EncodeContext, // definition (as that's not defined in this crate). fn encode_reachable(ecx: &EncodeContext, rbml_w: &mut Encoder) { rbml_w.start_tag(tag_reachable_ids); - for id in ecx.reachable { - rbml_w.wr_tagged_u32(tag_reachable_id, *id); + for &id in ecx.reachable { + let def_id = ecx.tcx.map.local_def_id(id); + rbml_w.wr_tagged_u32(tag_reachable_id, def_id.index.as_u32()); } rbml_w.end_tag(); } @@ -2139,7 +2159,7 @@ fn encode_metadata_inner(wr: &mut Cursor<Vec<u8>>, encode_index(&mut rbml_w, items_index); stats.index_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i; - encode_struct_field_attrs(&mut rbml_w, krate); + encode_struct_field_attrs(&ecx, &mut rbml_w, krate); stats.total_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap(); diff --git a/src/librustc/metadata/index.rs b/src/librustc/metadata/index.rs index b02a9022a7a..c60b789a2f1 100644 --- a/src/librustc/metadata/index.rs +++ b/src/librustc/metadata/index.rs @@ -8,143 +8,95 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use middle::def_id::{DefId, DefIndex}; +use rbml; +use rbml::writer::Encoder; use std::io::{Cursor, Write}; use std::slice; use std::u32; -use syntax::ast::NodeId; -#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)] -pub struct IndexEntry { - pub node: NodeId, - pub pos: u64 -} - -#[derive(Debug)] -pub struct IndexArrayEntry { - bits: u32, - first_pos: u32 +/// As part of the metadata, we generate an index that stores, for +/// each DefIndex, the position of the corresponding RBML document (if +/// any). This is just a big `[u32]` slice, where an entry of +/// `u32::MAX` indicates that there is no RBML document. This little +/// struct just stores the offsets within the metadata of the start +/// and end of this slice. These are actually part of an RBML +/// document, but for looking things up in the metadata, we just +/// discard the RBML positioning and jump directly to the data. +pub struct Index { + data_start: usize, + data_end: usize, } -impl IndexArrayEntry { - fn encode_to<W: Write>(&self, b: &mut W) { - write_be_u32(b, self.bits); - write_be_u32(b, self.first_pos); +impl Index { + /// Given the RBML doc representing the index, save the offests + /// for later. + pub fn from_rbml(index: rbml::Doc) -> Index { + Index { data_start: index.start, data_end: index.end } } - fn decode_from(b: &[u32]) -> Self { - IndexArrayEntry { - bits: b[0].to_be(), - first_pos: b[1].to_be() + /// Given the metadata, extract out the offset of a particular + /// DefIndex (if any). + #[inline(never)] + pub fn lookup_item(&self, bytes: &[u8], def_index: DefIndex) -> Option<u32> { + let words = bytes_to_words(&bytes[self.data_start..self.data_end]); + let index = def_index.as_usize(); + + debug!("lookup_item: index={:?} words.len={:?}", + index, words.len()); + + let position = u32::from_be(words[index]); + if position == u32::MAX { + debug!("lookup_item: position=u32::MAX"); + None + } else { + debug!("lookup_item: position={:?}", position); + Some(position) } } } -/// The Item Index -/// -/// This index maps the NodeId of each item to its location in the -/// metadata. -/// -/// The index is a sparse bit-vector consisting of a index-array -/// and a position-array. Each entry in the index-array handles 32 nodes. -/// The first word is a bit-array consisting of the nodes that hold items, -/// the second is the index of the first of the items in the position-array. -/// If there is a large set of non-item trailing nodes, they can be omitted -/// from the index-array. -/// -/// The index is serialized as an array of big-endian 32-bit words. -/// The first word is the number of items in the position-array. -/// Then, for each item, its position in the metadata follows. -/// After that the index-array is stored. -/// -/// struct index { -/// u32 item_count; -/// u32 items[self.item_count]; -/// struct { u32 bits; u32 offset; } positions[..]; -/// } -pub struct Index { - position_start: usize, - index_start: usize, - index_end: usize, +/// While we are generating the metadata, we also track the position +/// of each DefIndex. It is not required that all definitions appear +/// in the metadata, nor that they are serialized in order, and +/// therefore we first allocate the vector here and fill it with +/// `u32::MAX`. Whenever an index is visited, we fill in the +/// appropriate spot by calling `record_position`. We should never +/// visit the same index twice. +pub struct IndexData { + positions: Vec<u32>, } -pub fn write_index(mut entries: Vec<IndexEntry>, buf: &mut Cursor<Vec<u8>>) { - assert!(entries.len() < u32::MAX as usize); - entries.sort(); - - let mut last_entry = IndexArrayEntry { bits: 0, first_pos: 0 }; - - write_be_u32(buf, entries.len() as u32); - for &IndexEntry { pos, .. } in &entries { - assert!(pos < u32::MAX as u64); - write_be_u32(buf, pos as u32); +impl IndexData { + pub fn new(max_index: usize) -> IndexData { + IndexData { + positions: vec![u32::MAX; max_index] + } } - let mut pos_in_index_array = 0; - for (i, &IndexEntry { node, .. }) in entries.iter().enumerate() { - let (x, s) = (node / 32 as u32, node % 32 as u32); - while x > pos_in_index_array { - pos_in_index_array += 1; - last_entry.encode_to(buf); - last_entry = IndexArrayEntry { bits: 0, first_pos: i as u32 }; - } - last_entry.bits |= 1<<s; + pub fn record(&mut self, def_id: DefId, encoder: &mut Encoder) { + assert!(def_id.is_local()); + self.record_index(def_id.index, encoder) } - last_entry.encode_to(buf); - info!("write_index: {} items, {} array entries", - entries.len(), pos_in_index_array); -} + pub fn record_index(&mut self, item: DefIndex, encoder: &mut Encoder) { + let item = item.as_usize(); -impl Index { - fn lookup_index(&self, index: &[u32], i: u32) -> Option<IndexArrayEntry> { - let ix = (i as usize)*2; - if ix >= index.len() { - None - } else { - Some(IndexArrayEntry::decode_from(&index[ix..ix+2])) - } - } + let position = encoder.mark_stable_position(); - fn item_from_pos(&self, positions: &[u32], pos: u32) -> u32 { - positions[pos as usize].to_be() - } + assert!(position < (u32::MAX as u64)); + let position = position as u32; - #[inline(never)] - pub fn lookup_item(&self, buf: &[u8], node: NodeId) -> Option<u32> { - let index = bytes_to_words(&buf[self.index_start..self.index_end]); - let positions = bytes_to_words(&buf[self.position_start..self.index_start]); - let (x, s) = (node / 32 as u32, node % 32 as u32); - let result = match self.lookup_index(index, x) { - Some(IndexArrayEntry { bits, first_pos }) => { - let bit = 1<<s; - if bits & bit == 0 { - None - } else { - let prev_nodes_for_entry = (bits&(bit-1)).count_ones(); - Some(self.item_from_pos( - positions, - first_pos+prev_nodes_for_entry)) - } - } - None => None // trailing zero - }; - debug!("lookup_item({:?}) = {:?}", node, result); - result + assert!(self.positions[item] == u32::MAX, + "recorded position for item {:?} twice, first at {:?} and now at {:?}", + item, self.positions[item], position); + + self.positions[item] = position; } - pub fn from_buf(buf: &[u8], start: usize, end: usize) -> Self { - let buf = bytes_to_words(&buf[start..end]); - let position_count = buf[0].to_be() as usize; - let position_len = position_count*4; - info!("loaded index - position: {}-{}-{}", start, start+position_len, end); - debug!("index contents are {:?}", - buf.iter().map(|b| format!("{:08x}", b)).collect::<Vec<_>>().concat()); - assert!(end-4-start >= position_len); - assert_eq!((end-4-start-position_len)%8, 0); - Index { - position_start: start+4, - index_start: start+position_len+4, - index_end: end + pub fn write_index(&self, buf: &mut Cursor<Vec<u8>>) { + for &position in &self.positions { + write_be_u32(buf, position); } } } @@ -162,47 +114,3 @@ fn bytes_to_words(b: &[u8]) -> &[u32] { assert!(b.len() % 4 == 0); unsafe { slice::from_raw_parts(b.as_ptr() as *const u32, b.len()/4) } } - -#[test] -fn test_index() { - let entries = vec![ - IndexEntry { node: 0, pos: 17 }, - IndexEntry { node: 31, pos: 29 }, - IndexEntry { node: 32, pos: 1175 }, - IndexEntry { node: 191, pos: 21 }, - IndexEntry { node: 128, pos: 34 }, - IndexEntry { node: 145, pos: 70 }, - IndexEntry { node: 305, pos: 93214 }, - IndexEntry { node: 138, pos: 64 }, - IndexEntry { node: 129, pos: 53 }, - IndexEntry { node: 192, pos: 33334 }, - IndexEntry { node: 200, pos: 80123 }, - ]; - let mut c = Cursor::new(vec![]); - write_index(entries.clone(), &mut c); - let mut buf = c.into_inner(); - let expected: &[u8] = &[ - 0, 0, 0, 11, // # entries - // values: - 0,0,0,17, 0,0,0,29, 0,0,4,151, 0,0,0,34, - 0,0,0,53, 0,0,0,64, 0,0,0,70, 0,0,0,21, - 0,0,130,54, 0,1,56,251, 0,1,108,30, - // index: - 128,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,2, - 0,0,0,0,0,0,0,3, 0,0,0,0,0,0,0,3, - 0,2,4,3,0,0,0,3, 128,0,0,0,0,0,0,7, - 0,0,1,1,0,0,0,8, 0,0,0,0,0,0,0,10, - 0,0,0,0,0,0,0,10, 0,2,0,0,0,0,0,10 - ]; - assert_eq!(buf, expected); - - // insert some junk padding - for i in 0..17 { buf.insert(0, i); buf.push(i) } - let index = Index::from_buf(&buf, 17, buf.len()-17); - - // test round-trip - for i in 0..4096 { - assert_eq!(index.lookup_item(&buf, i), - entries.iter().find(|e| e.node == i).map(|n| n.pos as u32)); - } -} diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index f023049d78f..4657323c172 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -16,11 +16,9 @@ #![allow(non_camel_case_types)] -pub use self::DefIdSource::*; - use rustc_front::hir; -use middle::def_id::DefId; +use middle::def_id::{DefId, DefIndex}; use middle::region; use middle::subst; use middle::subst::VecPerParamSpace; @@ -36,32 +34,7 @@ use syntax::parse::token; // parse_from_str. Extra parameters are for converting to/from def_ids in the // data buffer. Whatever format you choose should not contain pipe characters. -// Def id conversion: when we encounter def-ids, they have to be translated. -// For example, the crate number must be converted from the crate number used -// in the library we are reading from into the local crate numbers in use -// here. To perform this translation, the type decoder is supplied with a -// conversion function of type `conv_did`. -// -// Sometimes, particularly when inlining, the correct translation of the -// def-id will depend on where it originated from. Therefore, the conversion -// function is given an indicator of the source of the def-id. See -// astencode.rs for more information. -#[derive(Copy, Clone, Debug)] -pub enum DefIdSource { - // Identifies a struct, trait, enum, etc. - NominalType, - - // Identifies a type alias (`type X = ...`). - TypeWithId, - - // Identifies a region parameter (`fn foo<'X>() { ... }`). - RegionParameter, - - // Identifies a closure - ClosureSource -} - -pub type DefIdConvert<'a> = &'a mut FnMut(DefIdSource, DefId) -> DefId; +pub type DefIdConvert<'a> = &'a mut FnMut(DefId) -> DefId; pub struct TyDecoder<'a, 'tcx: 'a> { data: &'a [u8], @@ -183,7 +156,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { ty::BrAnon(id) } '[' => { - let def = self.parse_def(RegionParameter); + let def = self.parse_def(); let name = token::intern(&self.parse_str(']')); ty::BrNamed(def, name) } @@ -209,7 +182,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { } 'B' => { assert_eq!(self.next(), '['); - let def_id = self.parse_def(NominalType); + let def_id = self.parse_def(); let space = self.parse_param_space(); assert_eq!(self.next(), '|'); let index = self.parse_u32(); @@ -309,7 +282,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { } pub fn parse_trait_ref(&mut self) -> ty::TraitRef<'tcx> { - let def = self.parse_def(NominalType); + let def = self.parse_def(); let substs = self.tcx.mk_substs(self.parse_substs()); ty::TraitRef {def_id: def, substs: substs} } @@ -338,7 +311,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { 'c' => return tcx.types.char, 't' => { assert_eq!(self.next(), '['); - let did = self.parse_def(NominalType); + let did = self.parse_def(); let substs = self.parse_substs(); assert_eq!(self.next(), ']'); let def = self.tcx.lookup_adt_def(did); @@ -385,7 +358,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { return tcx.mk_tup(params); } 'F' => { - let def_id = self.parse_def(NominalType); + let def_id = self.parse_def(); return tcx.mk_fn(Some(def_id), tcx.mk_bare_fn(self.parse_bare_fn_ty())); } 'G' => { @@ -427,13 +400,13 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { return tt; } '\"' => { - let _ = self.parse_def(TypeWithId); + let _ = self.parse_def(); let inner = self.parse_ty(); inner } 'a' => { assert_eq!(self.next(), '['); - let did = self.parse_def(NominalType); + let did = self.parse_def(); let substs = self.parse_substs(); assert_eq!(self.next(), ']'); let def = self.tcx.lookup_adt_def(did); @@ -441,7 +414,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { } 'k' => { assert_eq!(self.next(), '['); - let did = self.parse_def(ClosureSource); + let did = self.parse_def(); let substs = self.parse_substs(); let mut tys = vec![]; while self.peek() != '.' { @@ -476,9 +449,9 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { ty::TypeAndMut { ty: self.parse_ty(), mutbl: m } } - fn parse_def(&mut self, source: DefIdSource) -> DefId { + fn parse_def(&mut self) -> DefId { let def_id = parse_defid(self.scan(|c| c == '|')); - return (self.conv_def_id)(source, def_id); + return (self.conv_def_id)(def_id); } fn parse_uint(&mut self) -> usize { @@ -581,7 +554,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { 'p' => ty::Binder(self.parse_projection_predicate()).to_predicate(), 'w' => ty::Predicate::WellFormed(self.parse_ty()), 'O' => { - let def_id = self.parse_def(NominalType); + let def_id = self.parse_def(); assert_eq!(self.next(), '|'); ty::Predicate::ObjectSafe(def_id) } @@ -601,12 +574,12 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { pub fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> { let name = self.parse_name(':'); - let def_id = self.parse_def(NominalType); + let def_id = self.parse_def(); let space = self.parse_param_space(); assert_eq!(self.next(), '|'); let index = self.parse_u32(); assert_eq!(self.next(), '|'); - let default_def_id = self.parse_def(NominalType); + let default_def_id = self.parse_def(); let default = self.parse_opt(|this| this.parse_ty()); let object_lifetime_default = self.parse_object_lifetime_default(); @@ -623,7 +596,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { pub fn parse_region_param_def(&mut self) -> ty::RegionParameterDef { let name = self.parse_name(':'); - let def_id = self.parse_def(NominalType); + let def_id = self.parse_def(); let space = self.parse_param_space(); assert_eq!(self.next(), '|'); let index = self.parse_u32(); @@ -731,11 +704,12 @@ fn parse_defid(buf: &[u8]) -> DefId { let def_num = match str::from_utf8(def_part).ok().and_then(|s| { s.parse::<usize>().ok() }) { - Some(dn) => dn as ast::NodeId, + Some(dn) => dn, None => panic!("internal error: parse_defid: id expected, found {:?}", def_part) }; - DefId { krate: crate_num, xxx_node: def_num } + let index = DefIndex::new(def_num); + DefId { krate: crate_num, index: index } } fn parse_unsafety(c: char) -> hir::Unsafety { |
