diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index af36d45ab573d..4f7bbe9e02725 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -467,37 +467,44 @@ pub mod reader { f(&d.data[d.start..d.end]) } - pub fn doc_as_u8(d: Doc) -> u8 { assert_eq!(d.end, d.start + 1); d.data[d.start] } - pub fn doc_as_u16(d: Doc) -> u16 { - assert_eq!(d.end, d.start + 2); - let mut b = [0; 2]; - bytes::copy_memory(&d.data[d.start..d.end], &mut b); - unsafe { (*(b.as_ptr() as *const u16)).to_be() } - } - - pub fn doc_as_u32(d: Doc) -> u32 { - assert_eq!(d.end, d.start + 4); - let mut b = [0; 4]; - bytes::copy_memory(&d.data[d.start..d.end], &mut b); - unsafe { (*(b.as_ptr() as *const u32)).to_be() } - } - pub fn doc_as_u64(d: Doc) -> u64 { - assert_eq!(d.end, d.start + 8); - let mut b = [0; 8]; - bytes::copy_memory(&d.data[d.start..d.end], &mut b); - unsafe { (*(b.as_ptr() as *const u64)).to_be() } + if d.end >= 8 { + // For performance, we read 8 big-endian bytes, + // and mask off the junk if there is any. This + // obviously won't work on the first 8 bytes + // of a file - we will fall of the start + // of the page and segfault. + + let mut b = [0; 8]; + bytes::copy_memory(&d.data[d.end-8..d.end], &mut b); + let data = unsafe { (*(b.as_ptr() as *const u64)).to_be() }; + let len = d.end - d.start; + if len < 8 { + data & ((1<<(len*8))-1) + } else { + data + } + } else { + let mut result = 0; + for b in &d.data[d.start..d.end] { + result = (result<<8) + (*b as u64); + } + result + } } - pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 } - pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 } - pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 } - pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 } + #[inline] pub fn doc_as_u16(d: Doc) -> u16 { doc_as_u64(d) as u16 } + #[inline] pub fn doc_as_u32(d: Doc) -> u32 { doc_as_u64(d) as u32 } + + #[inline] pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 } + #[inline] pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 } + #[inline] pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 } + #[inline] pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 } pub struct Decoder<'a> { parent: Doc<'a>, @@ -907,7 +914,7 @@ pub mod writer { } } - fn write_vuint(w: &mut W, n: usize) -> EncodeResult { + pub fn write_vuint(w: &mut W, n: usize) -> EncodeResult { if n < 0x7f { return write_sized_vuint(w, n, 1); } if n < 0x4000 { return write_sized_vuint(w, n, 2); } if n < 0x200000 { return write_sized_vuint(w, n, 3); } @@ -996,35 +1003,43 @@ pub mod writer { pub fn wr_tagged_u64(&mut self, tag_id: usize, v: u64) -> EncodeResult { let bytes: [u8; 8] = unsafe { mem::transmute(v.to_be()) }; - self.wr_tagged_bytes(tag_id, &bytes) + // tagged integers are emitted in big-endian, with no + // leading zeros. + let leading_zero_bytes = v.leading_zeros()/8; + self.wr_tagged_bytes(tag_id, &bytes[leading_zero_bytes as usize..]) } - pub fn wr_tagged_u32(&mut self, tag_id: usize, v: u32) -> EncodeResult{ - let bytes: [u8; 4] = unsafe { mem::transmute(v.to_be()) }; - self.wr_tagged_bytes(tag_id, &bytes) + #[inline] + pub fn wr_tagged_u32(&mut self, tag_id: usize, v: u32) -> EncodeResult { + self.wr_tagged_u64(tag_id, v as u64) } + #[inline] pub fn wr_tagged_u16(&mut self, tag_id: usize, v: u16) -> EncodeResult { - let bytes: [u8; 2] = unsafe { mem::transmute(v.to_be()) }; - self.wr_tagged_bytes(tag_id, &bytes) + self.wr_tagged_u64(tag_id, v as u64) } + #[inline] pub fn wr_tagged_u8(&mut self, tag_id: usize, v: u8) -> EncodeResult { self.wr_tagged_bytes(tag_id, &[v]) } + #[inline] pub fn wr_tagged_i64(&mut self, tag_id: usize, v: i64) -> EncodeResult { self.wr_tagged_u64(tag_id, v as u64) } + #[inline] pub fn wr_tagged_i32(&mut self, tag_id: usize, v: i32) -> EncodeResult { self.wr_tagged_u32(tag_id, v as u32) } + #[inline] pub fn wr_tagged_i16(&mut self, tag_id: usize, v: i16) -> EncodeResult { self.wr_tagged_u16(tag_id, v as u16) } + #[inline] pub fn wr_tagged_i8(&mut self, tag_id: usize, v: i8) -> EncodeResult { self.wr_tagged_bytes(tag_id, &[v as u8]) } diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index 7b8ad78da74dc..a4fee5b7aa805 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -44,14 +44,14 @@ pub const tag_items_data_parent_item: usize = 0x28; pub const tag_items_data_item_is_tuple_struct_ctor: usize = 0x29; pub const tag_items_closure_kind: usize = 0x2a; - pub const tag_items_closure_ty: usize = 0x2b; +pub const tag_def_key: usize = 0x2c; -pub const tag_index: usize = 0x2c; - -pub const tag_def_key: usize = 0x2d; +// GAP 0x2d 0x2e -// GAP 0x2e +pub const tag_index: usize = 0x110; // top-level only +pub const tag_xref_index: usize = 0x111; // top-level only +pub const tag_xref_data: usize = 0x112; // top-level only pub const tag_meta_item_name_value: usize = 0x2f; @@ -80,8 +80,6 @@ pub const tag_crate_dep_crate_name: usize = 0x36; pub const tag_crate_dep_hash: usize = 0x37; pub const tag_crate_dep_explicitly_linked: usize = 0x38; // top-level only -pub const tag_mod_impl: usize = 0x39; - pub const tag_item_trait_item: usize = 0x3a; pub const tag_item_trait_ref: usize = 0x3b; @@ -95,7 +93,6 @@ pub const tag_path_len: usize = 0x3e; pub const tag_path_elem_mod: usize = 0x3f; pub const tag_path_elem_name: usize = 0x40; pub const tag_item_field: usize = 0x41; -pub const tag_item_field_origin: usize = 0x42; pub const tag_item_variances: usize = 0x43; /* @@ -125,28 +122,20 @@ enum_from_u32! { tag_tree = 0x51, - tag_id_range = 0x52, - + // GAP 0x52 tag_table = 0x53, // GAP 0x54, 0x55 tag_table_def = 0x56, tag_table_node_type = 0x57, tag_table_item_subst = 0x58, tag_table_freevars = 0x59, - tag_table_tcache = 0x5a, - tag_table_param_defs = 0x5b, - tag_table_mutbl = 0x5c, - tag_table_last_use = 0x5d, - tag_table_spill = 0x5e, + // GAP 0x5a, 0x5b, 0x5c, 0x5d, 0x5e tag_table_method_map = 0x5f, - tag_table_vtable_map = 0x60, + // GAP 0x60 tag_table_adjustments = 0x61, - tag_table_moves_map = 0x62, - tag_table_capture_map = 0x63, - // GAP 0x64, 0x65 + // GAP 0x62, 0x63, 0x64, 0x65 tag_table_upvar_capture_map = 0x66, - tag_table_capture_modes = 0x67, - // GAP 0x68 + // GAP 0x67, 0x68 tag_table_const_qualif = 0x69, tag_table_cast_kinds = 0x6a, } @@ -154,10 +143,6 @@ enum_from_u32! { pub const tag_item_trait_item_sort: usize = 0x70; -pub const tag_item_trait_parent_sort: usize = 0x71; - -pub const tag_item_impl_type_basename: usize = 0x72; - pub const tag_crate_triple: usize = 0x105; // top-level only pub const tag_dylib_dependency_formats: usize = 0x106; // top-level only @@ -177,23 +162,17 @@ pub const tag_lang_items_missing: usize = 0x76; pub const tag_item_unnamed_field: usize = 0x77; pub const tag_items_data_item_visibility: usize = 0x78; - -pub const tag_item_method_tps: usize = 0x79; -pub const tag_item_method_fty: usize = 0x7a; - +pub const tag_items_data_item_inherent_impl: usize = 0x79; +// GAP 0x7a pub const tag_mod_child: usize = 0x7b; pub const tag_misc_info: usize = 0x108; // top-level only pub const tag_misc_info_crate_items: usize = 0x7c; -// GAP 0x7d -pub const tag_item_impl_vtables: usize = 0x7e; - pub const tag_impls: usize = 0x109; // top-level only -pub const tag_impls_impl: usize = 0x7f; -pub const tag_impls_impl_trait_def_id: usize = 0x8d; +pub const tag_impls_trait: usize = 0x7d; +pub const tag_impls_trait_impl: usize = 0x7e; -pub const tag_items_data_item_inherent_impl: usize = 0x80; -pub const tag_items_data_item_extension_impl: usize = 0x81; +// GAP 0x7f, 0x80, 0x81 pub const tag_native_libraries: usize = 0x10a; // top-level only pub const tag_native_libraries_lib: usize = 0x82; @@ -220,10 +199,10 @@ pub struct LinkMeta { pub const tag_struct_fields: usize = 0x10d; // top-level only pub const tag_struct_field: usize = 0x8a; -// GAP 0x8b +pub const tag_items_data_item_struct_ctor: usize = 0x8b; pub const tag_attribute_is_sugared_doc: usize = 0x8c; - +// GAP 0x8d pub const tag_items_data_region: usize = 0x8e; pub const tag_region_param_def: usize = 0x8f; @@ -237,9 +216,9 @@ pub const tag_type_param_def: usize = 0x94; pub const tag_item_generics: usize = 0x95; pub const tag_method_ty_generics: usize = 0x96; -pub const tag_predicate: usize = 0x97; -pub const tag_predicate_space: usize = 0x98; -pub const tag_predicate_data: usize = 0x99; +pub const tag_type_predicate: usize = 0x97; +pub const tag_self_predicate: usize = 0x98; +pub const tag_fn_predicate: usize = 0x99; pub const tag_unsafety: usize = 0x9a; diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index fe4a909a08516..6c81562f7b291 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -327,6 +327,7 @@ impl<'a> CrateReader<'a> { local_path: RefCell::new(SmallVector::zero()), local_def_path: RefCell::new(vec![]), index: decoder::load_index(metadata.as_slice()), + xref_index: decoder::load_xrefs(metadata.as_slice()), data: metadata, cnum_map: RefCell::new(cnum_map), cnum: cnum, diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 402aa52612e87..e04df51dc6862 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -171,12 +171,6 @@ pub fn get_associated_consts<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) decoder::get_associated_consts(cstore.intr.clone(), &*cdata, def.index, tcx) } -pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: DefId) - -> Option { - let cdata = cstore.get_crate_data(def.krate); - decoder::get_type_name_if_impl(&*cdata, def.index) -} - pub fn get_methods_if_impl(cstore: &cstore::CStore, def: DefId) -> Option > { diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 48676a2a1b48a..c0e7667666c09 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -66,7 +66,9 @@ pub struct crate_metadata { pub codemap_import_info: RefCell>, pub span: codemap::Span, pub staged_api: bool, + pub index: index::Index, + pub xref_index: index::DenseIndex, /// Flag if this crate is required by an rlib version of this crate, or in /// other words whether it was explicitly linked to. An example of a crate diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index dd1238aacee04..f51fb068219c9 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -83,6 +83,11 @@ pub fn crate_rustc_version(data: &[u8]) -> Option { reader::maybe_get_doc(doc, tag_rustc_version).map(|s| s.as_str()) } +pub fn load_xrefs(data: &[u8]) -> index::DenseIndex { + let index = reader::get_doc(rbml::Doc::new(data), tag_xref_index); + index::DenseIndex::from_buf(index.data, index.start, index.end) +} + #[derive(Debug, PartialEq)] enum Family { ImmStatic, // c @@ -216,14 +221,6 @@ fn maybe_doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Opt }) } -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)) - .parse_bare_fn_ty() -} - pub fn item_type<'tcx>(_item_id: DefId, item: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Ty<'tcx> { doc_type(item, tcx, cdata) @@ -391,6 +388,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner, did: did, name: item_name(intr, item), fields: get_variant_fields(intr, cdata, item, tcx), + ctor_id: did, disr_val: disr } }).collect() @@ -419,11 +417,13 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner, cdata: Cmd, doc: rbml::Doc, did: DefId, + ctor_id: DefId, tcx: &ty::ctxt<'tcx>) -> ty::VariantDefData<'tcx, 'tcx> { ty::VariantDefData { did: did, name: item_name(intr, doc), fields: get_variant_fields(intr, cdata, doc, tcx), + ctor_id: ctor_id, disr_val: 0 } } @@ -431,11 +431,20 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner, let doc = cdata.lookup_item(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)), - Struct => (ty::AdtKind::Struct, - vec![get_struct_variant(intr, cdata, doc, did, tcx)]), - _ => tcx.sess.bug("get_adt_def called on a non-ADT") + Enum => { + (ty::AdtKind::Enum, + get_enum_variants(intr, cdata, doc, tcx)) + } + Struct => { + let ctor_did = + reader::maybe_get_doc(doc, tag_items_data_item_struct_ctor). + map_or(did, |ctor_doc| translated_def_id(cdata, ctor_doc)); + (ty::AdtKind::Struct, + vec![get_struct_variant(intr, cdata, doc, did, ctor_did, tcx)]) + } + _ => tcx.sess.bug( + &format!("get_adt_def called on a non-ADT {:?} - {:?}", + item_family(doc), did)) }; let adt = tcx.intern_adt_def(did, kind, variants); @@ -758,7 +767,8 @@ pub type DecodeInlinedItem<'a> = &ty::ctxt<'tcx>, Vec, hir_map::DefPath, - rbml::Doc) + rbml::Doc, + DefId) -> Result<&'tcx InlinedItem, (Vec, hir_map::DefPath)> + 'a>; @@ -767,15 +777,16 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: DefIndex, -> csearch::FoundAst<'tcx> { debug!("Looking up item: {:?}", id); let item_doc = cdata.lookup_item(id); + let item_did = item_def_id(item_doc, cdata); let path = item_path(item_doc).split_last().unwrap().1.to_vec(); let def_path = def_path(cdata, id); - match decode_inlined_item(cdata, tcx, path, def_path, item_doc) { + match decode_inlined_item(cdata, tcx, path, def_path, item_doc, item_did) { Ok(ii) => csearch::FoundAst::Found(ii), Err((path, def_path)) => { match item_parent_item(cdata, item_doc) { Some(did) => { let parent_item = cdata.lookup_item(did.index); - match decode_inlined_item(cdata, tcx, path, def_path, parent_item) { + match decode_inlined_item(cdata, tcx, path, def_path, parent_item, did) { Ok(ii) => csearch::FoundAst::FoundParent(did, ii), Err(_) => csearch::FoundAst::NotFound } @@ -879,7 +890,13 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc, Some('r') | Some('p') => { let generics = doc_generics(item_doc, tcx, cdata, tag_method_ty_generics); let predicates = doc_predicates(item_doc, tcx, cdata, tag_method_ty_generics); - let fty = doc_method_fty(item_doc, tcx, cdata); + let ity = tcx.lookup_item_type(def_id).ty; + let fty = match ity.sty { + ty::TyBareFn(_, fty) => fty.clone(), + _ => tcx.sess.bug(&format!( + "the type {:?} of the method {:?} is not a function?", + ity, name)) + }; let explicit_self = get_explicit_self(item_doc); ty::MethodTraitItem(Rc::new(ty::Method::new(name, @@ -983,18 +1000,6 @@ pub fn get_associated_consts<'tcx>(intr: Rc, }).collect() } -pub fn get_type_name_if_impl(cdata: Cmd, - node_id: DefIndex) -> Option { - let item = cdata.lookup_item(node_id); - if item_family(item) != Impl { - return None; - } - - reader::tagged_docs(item, tag_item_impl_type_basename).nth(0).map(|doc| { - token::intern(doc.as_str_slice()) - }) -} - pub fn get_methods_if_impl(intr: Rc, cdata: Cmd, node_id: DefIndex) @@ -1279,24 +1284,19 @@ pub fn each_implementation_for_trait(cdata: Cmd, mut callback: F) where F: FnMut(DefId), { - if cdata.cnum == def_id.krate { - 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)); - } - return; - } - // Do a reverse lookup beforehand to avoid touching the crate_num // hash map in the loop below. if let Some(crate_local_did) = reverse_translate_def_id(cdata, def_id) { let def_id_u64 = def_to_u64(crate_local_did); let impls_doc = reader::get_doc(rbml::Doc::new(cdata.data()), tag_impls); - for impl_doc in reader::tagged_docs(impls_doc, tag_impls_impl) { - let impl_trait = reader::get_doc(impl_doc, tag_impls_impl_trait_def_id); - if reader::doc_as_u64(impl_trait) == def_id_u64 { - callback(item_def_id(impl_doc, cdata)); + for trait_doc in reader::tagged_docs(impls_doc, tag_impls_trait) { + let trait_def_id = reader::get_doc(trait_doc, tag_def_id); + if reader::doc_as_u64(trait_def_id) != def_id_u64 { + continue; + } + for impl_doc in reader::tagged_docs(trait_doc, tag_impls_trait_impl) { + callback(translated_def_id(cdata, impl_doc)); } } } @@ -1484,6 +1484,19 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc, ty::Generics { types: types, regions: regions } } +fn doc_predicate<'tcx>(cdata: Cmd, + doc: rbml::Doc, + tcx: &ty::ctxt<'tcx>) + -> ty::Predicate<'tcx> +{ + let predicate_pos = cdata.xref_index.lookup( + cdata.data(), reader::doc_as_u32(doc)).unwrap() as usize; + TyDecoder::new( + cdata.data(), cdata.cnum, predicate_pos, tcx, + &mut |did| translate_def_id(cdata, did) + ).parse_predicate() +} + fn doc_predicates<'tcx>(base_doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd, @@ -1493,17 +1506,17 @@ fn doc_predicates<'tcx>(base_doc: rbml::Doc, let doc = reader::get_doc(base_doc, tag); let mut predicates = subst::VecPerParamSpace::empty(); - for predicate_doc in reader::tagged_docs(doc, tag_predicate) { - let space_doc = reader::get_doc(predicate_doc, tag_predicate_space); - let space = subst::ParamSpace::from_uint(reader::doc_as_u8(space_doc) as usize); - - 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)) - .parse_predicate(); - - predicates.push(space, data); + for predicate_doc in reader::tagged_docs(doc, tag_type_predicate) { + predicates.push(subst::TypeSpace, + doc_predicate(cdata, predicate_doc, tcx)); + } + for predicate_doc in reader::tagged_docs(doc, tag_self_predicate) { + predicates.push(subst::SelfSpace, + doc_predicate(cdata, predicate_doc, tcx)); + } + for predicate_doc in reader::tagged_docs(doc, tag_fn_predicate) { + predicates.push(subst::FnSpace, + doc_predicate(cdata, predicate_doc, tcx)); } ty::GenericPredicates { predicates: predicates } @@ -1584,4 +1597,3 @@ pub fn def_path(cdata: Cmd, id: DefIndex) -> hir_map::DefPath { def_key(parent_doc) }) } - diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 1511ea2bc07db..9d2b1548f29d8 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -20,12 +20,13 @@ use metadata::cstore; use metadata::cstore::LOCAL_CRATE; use metadata::decoder; use metadata::tyencode; -use metadata::index::IndexData; +use metadata::index::{self, IndexData}; use metadata::inline::InlinedItemRef; use middle::def; use middle::def_id::{CRATE_DEF_INDEX, DefId}; use middle::dependency_format::Linkage; use middle::stability; +use middle::subst; use middle::ty::{self, Ty}; use util::nodemap::{FnvHashMap, NodeMap, NodeSet}; @@ -82,12 +83,29 @@ impl<'a, 'tcx> EncodeContext<'a,'tcx> { } } -fn encode_name(rbml_w: &mut Encoder, name: Name) { - rbml_w.wr_tagged_str(tag_paths_data_name, &name.as_str()); +/// "interned" entries referenced by id +#[derive(PartialEq, Eq, Hash)] +pub enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) } + +struct CrateIndex<'tcx> { + items: IndexData, + xrefs: FnvHashMap, u32>, // sequentially-assigned +} + +impl<'tcx> CrateIndex<'tcx> { + fn record(&mut self, id: DefId, rbml_w: &mut Encoder) { + let position = rbml_w.mark_stable_position(); + self.items.record(id, position); + } + + fn add_xref(&mut self, xref: XRef<'tcx>) -> u32 { + let old_len = self.xrefs.len() as u32; + *self.xrefs.entry(xref).or_insert(old_len) + } } -fn encode_impl_type_basename(rbml_w: &mut Encoder, name: Name) { - rbml_w.wr_tagged_str(tag_item_impl_type_basename, &name.as_str()); +fn encode_name(rbml_w: &mut Encoder, name: Name) { + rbml_w.wr_tagged_str(tag_paths_data_name, &name.as_str()); } fn encode_def_id(rbml_w: &mut Encoder, id: DefId) { @@ -155,18 +173,22 @@ fn encode_item_variances(rbml_w: &mut Encoder, fn encode_bounds_and_type_for_item<'a, 'tcx>(rbml_w: &mut Encoder, ecx: &EncodeContext<'a, 'tcx>, + index: &mut CrateIndex<'tcx>, id: NodeId) { encode_bounds_and_type(rbml_w, ecx, + index, &ecx.tcx.lookup_item_type(ecx.tcx.map.local_def_id(id)), &ecx.tcx.lookup_predicates(ecx.tcx.map.local_def_id(id))); } fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder, ecx: &EncodeContext<'a, 'tcx>, + index: &mut CrateIndex<'tcx>, scheme: &ty::TypeScheme<'tcx>, predicates: &ty::GenericPredicates<'tcx>) { - encode_generics(rbml_w, ecx, &scheme.generics, &predicates, tag_item_generics); + encode_generics(rbml_w, ecx, index, + &scheme.generics, &predicates, tag_item_generics); encode_type(ecx, rbml_w, scheme.ty); } @@ -240,22 +262,6 @@ fn encode_region(ecx: &EncodeContext, rbml_w.end_tag(); } -fn encode_method_fty<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, - rbml_w: &mut Encoder, - typ: &ty::BareFnTy<'tcx>) { - rbml_w.start_tag(tag_item_method_fty); - - let ty_str_ctxt = &tyencode::ctxt { - diag: ecx.diag, - ds: def_to_string, - tcx: ecx.tcx, - abbrevs: &ecx.type_abbrevs - }; - tyencode::enc_bare_fn_ty(rbml_w, ty_str_ctxt, typ); - - rbml_w.end_tag(); -} - fn encode_symbol(ecx: &EncodeContext, rbml_w: &mut Encoder, id: NodeId) { @@ -282,8 +288,7 @@ fn encode_parent_item(rbml_w: &mut Encoder, id: DefId) { } fn encode_struct_fields(rbml_w: &mut Encoder, - variant: ty::VariantDef, - origin: DefId) { + variant: ty::VariantDef) { for f in &variant.fields { if f.name == special_idents::unnamed_field.name { rbml_w.start_tag(tag_item_unnamed_field); @@ -293,16 +298,15 @@ fn encode_struct_fields(rbml_w: &mut Encoder, } encode_struct_field_family(rbml_w, f.vis); encode_def_id(rbml_w, f.did); - rbml_w.wr_tagged_u64(tag_item_field_origin, def_to_u64(origin)); rbml_w.end_tag(); } } -fn encode_enum_variant_info(ecx: &EncodeContext, - rbml_w: &mut Encoder, - id: NodeId, - vis: hir::Visibility, - index: &mut IndexData) { +fn encode_enum_variant_info<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, + rbml_w: &mut Encoder, + id: NodeId, + vis: hir::Visibility, + index: &mut CrateIndex<'tcx>) { debug!("encode_enum_variant_info(id={})", id); let mut disr_val = 0; @@ -337,14 +341,14 @@ fn encode_enum_variant_info(ecx: &EncodeContext, let stab = stability::lookup(ecx.tcx, vid); encode_stability(rbml_w, stab); - encode_struct_fields(rbml_w, variant, vid); + encode_struct_fields(rbml_w, variant); let specified_disr_val = variant.disr_val; if specified_disr_val != disr_val { encode_disr_val(ecx, rbml_w, specified_disr_val); disr_val = specified_disr_val; } - encode_bounds_and_type_for_item(rbml_w, ecx, variant_node_id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, variant_node_id); ecx.tcx.map.with_path(variant_node_id, |path| encode_path(rbml_w, path)); rbml_w.end_tag(); @@ -440,15 +444,6 @@ fn encode_info_for_mod(ecx: &EncodeContext, def_to_u64(ecx.tcx.map.local_def_id(auxiliary_node_id))); true }); - - if let hir::ItemImpl(..) = item.node { - let (name, did) = (item.name, item.id); - debug!("(encoding info for module) ... encoding impl {} ({}/{})", - name, - did, ecx.tcx.map.node_to_string(did)); - - rbml_w.wr_tagged_u64(tag_mod_impl, def_to_u64(ecx.tcx.map.local_def_id(did))); - } } encode_path(rbml_w, path.clone()); @@ -527,23 +522,19 @@ fn encode_item_sort(rbml_w: &mut Encoder, sort: char) { rbml_w.wr_tagged_u8(tag_item_trait_item_sort, sort as u8); } -fn encode_parent_sort(rbml_w: &mut Encoder, sort: char) { - rbml_w.wr_tagged_u8(tag_item_trait_parent_sort, sort as u8); -} - fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, field: ty::FieldDef<'tcx>, - global_index: &mut IndexData) { + index: &mut CrateIndex<'tcx>) { let nm = field.name; let id = ecx.local_id(field.did); - global_index.record(field.did, rbml_w); + 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_bounds_and_type_for_item(rbml_w, ecx, index, id); encode_def_id_and_key(ecx, rbml_w, field.did); let stab = stability::lookup(ecx.tcx, field.did); @@ -552,20 +543,19 @@ fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.end_tag(); } -fn encode_info_for_struct_ctor(ecx: &EncodeContext, - rbml_w: &mut Encoder, - name: Name, - ctor_id: NodeId, - index: &mut IndexData, - struct_id: NodeId) { +fn encode_info_for_struct_ctor<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, + rbml_w: &mut Encoder, + name: Name, + ctor_id: NodeId, + index: &mut CrateIndex<'tcx>, + struct_id: NodeId) { 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_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_bounds_and_type_for_item(rbml_w, ecx, index, ctor_id); encode_name(rbml_w, name); ecx.tcx.map.with_path(ctor_id, |path| encode_path(rbml_w, path)); encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(struct_id)); @@ -587,6 +577,7 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext, fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder, ecx: &EncodeContext<'a, 'tcx>, + index: &mut CrateIndex<'tcx>, generics: &ty::Generics<'tcx>, predicates: &ty::GenericPredicates<'tcx>, tag: usize) @@ -631,53 +622,48 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder, rbml_w.end_tag(); } - encode_predicates_in_current_doc(rbml_w, ecx, predicates); + encode_predicates_in_current_doc(rbml_w, ecx, index, predicates); rbml_w.end_tag(); } fn encode_predicates_in_current_doc<'a,'tcx>(rbml_w: &mut Encoder, - ecx: &EncodeContext<'a,'tcx>, + _ecx: &EncodeContext<'a,'tcx>, + index: &mut CrateIndex<'tcx>, predicates: &ty::GenericPredicates<'tcx>) { - let ty_str_ctxt = &tyencode::ctxt { - diag: ecx.diag, - ds: def_to_string, - tcx: ecx.tcx, - abbrevs: &ecx.type_abbrevs - }; - for (space, _, predicate) in predicates.predicates.iter_enumerated() { - rbml_w.start_tag(tag_predicate); - - rbml_w.wr_tagged_u8(tag_predicate_space, space as u8); - - rbml_w.start_tag(tag_predicate_data); - tyencode::enc_predicate(rbml_w, ty_str_ctxt, predicate); - rbml_w.end_tag(); + let tag = match space { + subst::TypeSpace => tag_type_predicate, + subst::SelfSpace => tag_self_predicate, + subst::FnSpace => tag_fn_predicate + }; - rbml_w.end_tag(); + rbml_w.wr_tagged_u32(tag, + index.add_xref(XRef::Predicate(predicate.clone()))); } } fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder, ecx: &EncodeContext<'a,'tcx>, + index: &mut CrateIndex<'tcx>, predicates: &ty::GenericPredicates<'tcx>, tag: usize) { rbml_w.start_tag(tag); - encode_predicates_in_current_doc(rbml_w, ecx, predicates); + encode_predicates_in_current_doc(rbml_w, ecx, index, predicates); rbml_w.end_tag(); } fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, + index: &mut CrateIndex<'tcx>, method_ty: &ty::Method<'tcx>) { 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, + encode_generics(rbml_w, ecx, index, + &method_ty.generics, &method_ty.predicates, tag_method_ty_generics); - encode_method_fty(ecx, rbml_w, &method_ty.fty); encode_visibility(rbml_w, method_ty.vis); encode_explicit_self(rbml_w, &method_ty.explicit_self); match method_ty.explicit_self { @@ -688,16 +674,18 @@ fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, } } -fn encode_info_for_associated_const(ecx: &EncodeContext, - rbml_w: &mut Encoder, - associated_const: &ty::AssociatedConst, - impl_path: PathElems, - parent_id: NodeId, - impl_item_opt: Option<&hir::ImplItem>) { +fn encode_info_for_associated_const<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, + rbml_w: &mut Encoder, + index: &mut CrateIndex<'tcx>, + associated_const: &ty::AssociatedConst, + impl_path: PathElems, + parent_id: NodeId, + impl_item_opt: Option<&hir::ImplItem>) { debug!("encode_info_for_associated_const({:?},{:?})", associated_const.def_id, associated_const.name); + index.record(associated_const.def_id, rbml_w); rbml_w.start_tag(tag_items_data_item); encode_def_id_and_key(ecx, rbml_w, associated_const.def_id); @@ -708,7 +696,8 @@ fn encode_info_for_associated_const(ecx: &EncodeContext, encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); encode_item_sort(rbml_w, 'C'); - encode_bounds_and_type_for_item(rbml_w, ecx, ecx.local_id(associated_const.def_id)); + encode_bounds_and_type_for_item(rbml_w, ecx, index, + ecx.local_id(associated_const.def_id)); let stab = stability::lookup(ecx.tcx, associated_const.def_id); encode_stability(rbml_w, stab); @@ -729,6 +718,7 @@ fn encode_info_for_associated_const(ecx: &EncodeContext, fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, + index: &mut CrateIndex<'tcx>, m: &ty::Method<'tcx>, impl_path: PathElems, is_default_impl: bool, @@ -737,18 +727,18 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, debug!("encode_info_for_method: {:?} {:?}", m.def_id, m.name); + index.record(m.def_id, rbml_w); rbml_w.start_tag(tag_items_data_item); - encode_method_ty_fields(ecx, rbml_w, m); + encode_method_ty_fields(ecx, rbml_w, index, m); encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); encode_item_sort(rbml_w, 'r'); let stab = stability::lookup(ecx.tcx, m.def_id); encode_stability(rbml_w, stab); - // The type for methods gets encoded twice, which is unfortunate. let m_node_id = ecx.local_id(m.def_id); - encode_bounds_and_type_for_item(rbml_w, ecx, m_node_id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, m_node_id); let elem = ast_map::PathName(m.name); encode_path(rbml_w, impl_path.chain(Some(elem))); @@ -779,6 +769,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, + index: &mut CrateIndex<'tcx>, associated_type: &ty::AssociatedType<'tcx>, impl_path: PathElems, parent_id: NodeId, @@ -787,6 +778,7 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, associated_type.def_id, associated_type.name); + index.record(associated_type.def_id, rbml_w); rbml_w.start_tag(tag_items_data_item); encode_def_id_and_key(ecx, rbml_w, associated_type.def_id); @@ -805,7 +797,7 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, if let Some(ii) = impl_item_opt { encode_attributes(rbml_w, &ii.attrs); } else { - encode_predicates(rbml_w, ecx, + encode_predicates(rbml_w, ecx, index, &ecx.tcx.lookup_predicates(associated_type.def_id), tag_item_generics); } @@ -873,20 +865,6 @@ fn encode_inherent_implementations(ecx: &EncodeContext, } } -// Encodes the implementations of a trait defined in this crate. -fn encode_extension_implementations(ecx: &EncodeContext, - rbml_w: &mut Encoder, - trait_def_id: DefId) { - assert!(trait_def_id.is_local()); - let def = ecx.tcx.lookup_trait_def(trait_def_id); - - def.for_each_impl(ecx.tcx, |impl_def_id| { - rbml_w.start_tag(tag_items_data_item_extension_impl); - encode_def_id(rbml_w, impl_def_id); - rbml_w.end_tag(); - }); -} - fn encode_stability(rbml_w: &mut Encoder, stab_opt: Option<&attr::Stability>) { stab_opt.map(|stab| { rbml_w.start_tag(tag_items_data_item_stability); @@ -895,12 +873,40 @@ 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 IndexData, - path: PathElems, - vis: hir::Visibility) { +fn encode_xrefs<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, + rbml_w: &mut Encoder, + xrefs: FnvHashMap, u32>) +{ + let ty_str_ctxt = &tyencode::ctxt { + diag: ecx.diag, + ds: def_to_string, + tcx: ecx.tcx, + abbrevs: &ecx.type_abbrevs + }; + + let mut xref_positions = vec![0; xrefs.len()]; + rbml_w.start_tag(tag_xref_data); + for (xref, id) in xrefs.into_iter() { + xref_positions[id as usize] = rbml_w.mark_stable_position() as u32; + match xref { + XRef::Predicate(p) => { + tyencode::enc_predicate(rbml_w, ty_str_ctxt, &p) + } + } + } + rbml_w.end_tag(); + + rbml_w.start_tag(tag_xref_index); + index::write_dense_index(xref_positions, rbml_w.writer); + rbml_w.end_tag(); +} + +fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, + rbml_w: &mut Encoder, + item: &hir::Item, + index: &mut CrateIndex<'tcx>, + path: PathElems, + vis: hir::Visibility) { let tcx = ecx.tcx; debug!("encoding info for item at {}", @@ -919,7 +925,7 @@ fn encode_info_for_item(ecx: &EncodeContext, } else { encode_family(rbml_w, 'c'); } - encode_bounds_and_type_for_item(rbml_w, ecx, item.id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_symbol(ecx, rbml_w, item.id); encode_name(rbml_w, item.name); encode_path(rbml_w, path); @@ -933,7 +939,7 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.start_tag(tag_items_data_item); 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_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_name(rbml_w, item.name); encode_path(rbml_w, path); encode_attributes(rbml_w, &item.attrs); @@ -948,7 +954,7 @@ fn encode_info_for_item(ecx: &EncodeContext, 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); + encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_name(rbml_w, item.name); encode_path(rbml_w, path); encode_attributes(rbml_w, &item.attrs); @@ -998,7 +1004,7 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.start_tag(tag_items_data_item); 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_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_name(rbml_w, item.name); encode_path(rbml_w, path); encode_visibility(rbml_w, vis); @@ -1012,7 +1018,7 @@ fn encode_info_for_item(ecx: &EncodeContext, 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); + encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_name(rbml_w, item.name); encode_attributes(rbml_w, &item.attrs); encode_repr_attrs(rbml_w, ecx, &item.attrs); @@ -1039,10 +1045,6 @@ fn encode_info_for_item(ecx: &EncodeContext, let def = ecx.tcx.lookup_adt_def(def_id); let variant = def.struct_variant(); - for field in &variant.fields { - encode_field(ecx, rbml_w, field, index); - } - /* Index the class*/ index.record(def_id, rbml_w); @@ -1050,7 +1052,7 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.start_tag(tag_items_data_item); 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); + encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_item_variances(rbml_w, ecx, item.id); encode_name(rbml_w, item.name); @@ -1063,22 +1065,29 @@ fn encode_info_for_item(ecx: &EncodeContext, /* Encode def_ids for each field and method for methods, write all the stuff get_trait_method needs to know*/ - encode_struct_fields(rbml_w, variant, def_id); + encode_struct_fields(rbml_w, variant); encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item)); // Encode inherent implementations for this structure. encode_inherent_implementations(ecx, rbml_w, def_id); + if let Some(ctor_id) = struct_def.ctor_id { + let ctor_did = ecx.tcx.map.local_def_id(ctor_id); + rbml_w.wr_tagged_u64(tag_items_data_item_struct_ctor, + def_to_u64(ctor_did)); + } + rbml_w.end_tag(); + for field in &variant.fields { + encode_field(ecx, rbml_w, field, index); + } + // If this is a tuple-like struct, encode the type of the constructor. - match struct_def.ctor_id { - Some(ctor_id) => { - encode_info_for_struct_ctor(ecx, rbml_w, item.name, - ctor_id, index, item.id); - } - None => {} + if let Some(ctor_id) = struct_def.ctor_id { + encode_info_for_struct_ctor(ecx, rbml_w, item.name, + ctor_id, index, item.id); } } hir::ItemDefaultImpl(unsafety, _) => { @@ -1093,7 +1102,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); rbml_w.end_tag(); } - hir::ItemImpl(unsafety, polarity, _, _, ref ty, ref ast_items) => { + hir::ItemImpl(unsafety, polarity, _, _, _, ref ast_items) => { // We need to encode information about the default methods we // have inherited, so we drive this based on the impl structure. let impl_items = tcx.impl_items.borrow(); @@ -1103,7 +1112,7 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.start_tag(tag_items_data_item); 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_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_name(rbml_w, item.name); encode_attributes(rbml_w, &item.attrs); encode_unsafety(rbml_w, unsafety); @@ -1118,13 +1127,6 @@ fn encode_info_for_item(ecx: &EncodeContext, None => {} } - match ty.node { - hir::TyPath(None, ref path) if path.segments.len() == 1 => { - let name = path.segments.last().unwrap().identifier.name; - encode_impl_type_basename(rbml_w, name); - } - _ => {} - } for &item_def_id in items { rbml_w.start_tag(tag_item_impl_item); match item_def_id { @@ -1162,12 +1164,11 @@ fn encode_info_for_item(ecx: &EncodeContext, None }; - 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) => { encode_info_for_associated_const(ecx, rbml_w, + index, &*associated_const, path.clone(), item.id, @@ -1176,6 +1177,7 @@ fn encode_info_for_item(ecx: &EncodeContext, ty::MethodTraitItem(ref method_type) => { encode_info_for_method(ecx, rbml_w, + index, &**method_type, path.clone(), false, @@ -1185,6 +1187,7 @@ fn encode_info_for_item(ecx: &EncodeContext, ty::TypeTraitItem(ref associated_type) => { encode_info_for_associated_type(ecx, rbml_w, + index, &**associated_type, path.clone(), item.id, @@ -1205,9 +1208,11 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_paren_sugar(rbml_w, trait_def.paren_sugar); encode_defaulted(rbml_w, tcx.trait_has_default_impl(def_id)); encode_associated_type_names(rbml_w, &trait_def.associated_type_names); - encode_generics(rbml_w, ecx, &trait_def.generics, &trait_predicates, + encode_generics(rbml_w, ecx, index, + &trait_def.generics, &trait_predicates, tag_item_generics); - encode_predicates(rbml_w, ecx, &tcx.lookup_super_predicates(def_id), + encode_predicates(rbml_w, ecx, index, + &tcx.lookup_super_predicates(def_id), tag_item_super_predicates); encode_trait_ref(rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref); encode_name(rbml_w, item.name); @@ -1237,9 +1242,6 @@ fn encode_info_for_item(ecx: &EncodeContext, } encode_path(rbml_w, path.clone()); - // Encode the implementations of this trait. - encode_extension_implementations(ecx, rbml_w, def_id); - // Encode inherent implementations for this trait. encode_inherent_implementations(ecx, rbml_w, def_id); @@ -1251,7 +1253,6 @@ fn encode_info_for_item(ecx: &EncodeContext, assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE); index.record(item_def_id.def_id(), rbml_w); - rbml_w.start_tag(tag_items_data_item); encode_parent_item(rbml_w, def_id); @@ -1274,8 +1275,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_family(rbml_w, 'C'); - encode_bounds_and_type_for_item(rbml_w, - ecx, + encode_bounds_and_type_for_item(rbml_w, ecx, index, ecx.local_id(associated_const.def_id)); is_nonstatic_method = false; @@ -1283,7 +1283,7 @@ fn encode_info_for_item(ecx: &EncodeContext, ty::MethodTraitItem(method_ty) => { let method_def_id = item_def_id.def_id(); - encode_method_ty_fields(ecx, rbml_w, &*method_ty); + encode_method_ty_fields(ecx, rbml_w, index, &*method_ty); let elem = ast_map::PathName(method_ty.name); encode_path(rbml_w, @@ -1299,7 +1299,8 @@ fn encode_info_for_item(ecx: &EncodeContext, METHOD_FAMILY); } } - encode_bounds_and_type_for_item(rbml_w, ecx, ecx.local_id(method_def_id)); + encode_bounds_and_type_for_item(rbml_w, ecx, index, + ecx.local_id(method_def_id)); is_nonstatic_method = method_ty.explicit_self != ty::StaticExplicitSelfCategory; @@ -1323,8 +1324,6 @@ fn encode_info_for_item(ecx: &EncodeContext, } } - encode_parent_sort(rbml_w, 't'); - let trait_item = &*ms[i]; encode_attributes(rbml_w, &trait_item.attrs); match trait_item.node { @@ -1344,10 +1343,8 @@ fn encode_info_for_item(ecx: &EncodeContext, if is_nonstatic_method { // FIXME: I feel like there is something funny // going on. - encode_bounds_and_type_for_item( - rbml_w, - ecx, - ecx.local_id(item_def_id.def_id())); + encode_bounds_and_type_for_item(rbml_w, ecx, index, + ecx.local_id(item_def_id.def_id())); } if body.is_some() { @@ -1372,23 +1369,22 @@ fn encode_info_for_item(ecx: &EncodeContext, } } -fn encode_info_for_foreign_item(ecx: &EncodeContext, - rbml_w: &mut Encoder, - nitem: &hir::ForeignItem, - index: &mut IndexData, - path: PathElems, - abi: abi::Abi) { +fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, + rbml_w: &mut Encoder, + nitem: &hir::ForeignItem, + index: &mut CrateIndex<'tcx>, + path: PathElems, + abi: abi::Abi) { 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_and_key(ecx, rbml_w, def_id); encode_visibility(rbml_w, nitem.vis); match nitem.node { hir::ForeignItemFn(ref fndecl, _) => { encode_family(rbml_w, FN_FAMILY); - encode_bounds_and_type_for_item(rbml_w, ecx, nitem.id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, nitem.id); encode_name(rbml_w, nitem.name); if abi == abi::RustIntrinsic || abi == abi::PlatformIntrinsic { encode_inlined_item(ecx, rbml_w, InlinedItemRef::Foreign(nitem)); @@ -1405,7 +1401,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, } else { encode_family(rbml_w, 'c'); } - encode_bounds_and_type_for_item(rbml_w, ecx, nitem.id); + encode_bounds_and_type_for_item(rbml_w, ecx, index, nitem.id); encode_attributes(rbml_w, &*nitem.attrs); let stab = stability::lookup(ecx.tcx, ecx.tcx.map.local_def_id(nitem.id)); encode_stability(rbml_w, stab); @@ -1420,7 +1416,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, fn my_visit_expr(expr: &hir::Expr, rbml_w: &mut Encoder, ecx: &EncodeContext, - index: &mut IndexData) { + index: &mut CrateIndex) { match expr.node { hir::ExprClosure(..) => { let def_id = ecx.tcx.map.local_def_id(expr.id); @@ -1446,19 +1442,19 @@ fn my_visit_expr(expr: &hir::Expr, } } -fn my_visit_item(i: &hir::Item, - rbml_w: &mut Encoder, - ecx: &EncodeContext, - index: &mut IndexData) { +fn my_visit_item<'a, 'tcx>(i: &hir::Item, + rbml_w: &mut Encoder, + ecx: &EncodeContext<'a, 'tcx>, + index: &mut CrateIndex<'tcx>) { ecx.tcx.map.with_path(i.id, |path| { encode_info_for_item(ecx, rbml_w, i, index, path, i.vis); }); } -fn my_visit_foreign_item(ni: &hir::ForeignItem, - rbml_w: &mut Encoder, - ecx: &EncodeContext, - index: &mut IndexData) { +fn my_visit_foreign_item<'a, 'tcx>(ni: &hir::ForeignItem, + rbml_w: &mut Encoder, + ecx: &EncodeContext<'a, 'tcx>, + index: &mut CrateIndex<'tcx>) { debug!("writing foreign item {}::{}", ecx.tcx.map.path_to_string(ni.id), ni.name); @@ -1474,7 +1470,7 @@ 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 IndexData, + index: &'a mut CrateIndex<'tcx>, } impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for EncodeVisitor<'a, 'b, 'c, 'tcx> { @@ -1492,14 +1488,17 @@ impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for EncodeVisitor<'a, 'b, 'c, 'tcx> { } } -fn encode_info_for_items(ecx: &EncodeContext, - rbml_w: &mut Encoder, - krate: &hir::Crate) - -> IndexData { - let mut index = IndexData::new(ecx.tcx.map.num_local_def_ids()); - +fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, + rbml_w: &mut Encoder, + krate: &hir::Crate) + -> CrateIndex<'tcx> { + let mut index = CrateIndex { + items: IndexData::new(ecx.tcx.map.num_local_def_ids()), + xrefs: FnvHashMap() + }; rbml_w.start_tag(tag_items_data); - index.record_index(CRATE_DEF_INDEX, rbml_w); + + index.record(DefId::local(CRATE_DEF_INDEX), rbml_w); encode_info_for_mod(ecx, rbml_w, &krate.module, @@ -1519,7 +1518,7 @@ fn encode_info_for_items(ecx: &EncodeContext, index } -fn encode_index(rbml_w: &mut Encoder, index: IndexData) { +fn encode_item_index(rbml_w: &mut Encoder, index: IndexData) { rbml_w.start_tag(tag_index); index.write_index(rbml_w.writer); rbml_w.end_tag(); @@ -1747,53 +1746,44 @@ fn encode_struct_field_attrs(ecx: &EncodeContext, -struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> { - ecx: &'a EncodeContext<'b, 'tcx>, - rbml_w: &'a mut Encoder<'c>, +struct ImplVisitor<'a, 'tcx:'a> { + tcx: &'a ty::ctxt<'tcx>, + impls: FnvHashMap> } -impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> { +impl<'a, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &hir::Item) { - if let hir::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node { - let def_id = self.ecx.tcx.def_map.borrow().get(&trait_ref.ref_id).unwrap().def_id(); - - // Load eagerly if this is an implementation of the Drop trait - // or if the trait is not defined in this crate. - if Some(def_id) == self.ecx.tcx.lang_items.drop_trait() || - def_id.krate != LOCAL_CRATE { - self.rbml_w.start_tag(tag_impls_impl); - encode_def_id(self.rbml_w, self.ecx.tcx.map.local_def_id(item.id)); - self.rbml_w.wr_tagged_u64(tag_impls_impl_trait_def_id, def_to_u64(def_id)); - self.rbml_w.end_tag(); + if let hir::ItemImpl(..) = item.node { + let impl_id = self.tcx.map.local_def_id(item.id); + if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) { + self.impls.entry(trait_ref.def_id) + .or_insert(vec![]) + .push(impl_id); } } visit::walk_item(self, item); } } -/// Encodes implementations that are eagerly loaded. -/// -/// None of this is necessary in theory; we can load all implementations -/// lazily. However, in two cases the optimizations to lazily load -/// implementations are not yet implemented. These two cases, which require us -/// to load implementations eagerly, are: -/// -/// * Destructors (implementations of the Drop trait). -/// -/// * Implementations of traits not defined in this crate. +/// Encodes an index, mapping each trait to its (local) implementations. fn encode_impls<'a>(ecx: &'a EncodeContext, krate: &hir::Crate, rbml_w: &'a mut Encoder) { - rbml_w.start_tag(tag_impls); + let mut visitor = ImplVisitor { + tcx: ecx.tcx, + impls: FnvHashMap() + }; + visit::walk_crate(&mut visitor, krate); - { - let mut visitor = ImplVisitor { - ecx: ecx, - rbml_w: rbml_w, - }; - visit::walk_crate(&mut visitor, krate); + rbml_w.start_tag(tag_impls); + for (trait_, trait_impls) in visitor.impls { + rbml_w.start_tag(tag_impls_trait); + encode_def_id(rbml_w, trait_); + for impl_ in trait_impls { + rbml_w.wr_tagged_u64(tag_impls_trait_impl, def_to_u64(impl_)); + } + rbml_w.end_tag(); } - rbml_w.end_tag(); } @@ -1939,6 +1929,7 @@ fn encode_metadata_inner(wr: &mut Cursor>, misc_bytes: u64, item_bytes: u64, index_bytes: u64, + xref_bytes: u64, zero_bytes: u64, total_bytes: u64, } @@ -1954,6 +1945,7 @@ fn encode_metadata_inner(wr: &mut Cursor>, misc_bytes: 0, item_bytes: 0, index_bytes: 0, + xref_bytes: 0, zero_bytes: 0, total_bytes: 0, }; @@ -2035,14 +2027,18 @@ fn encode_metadata_inner(wr: &mut Cursor>, // Encode and index the items. rbml_w.start_tag(tag_items); i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap(); - let items_index = encode_info_for_items(&ecx, &mut rbml_w, krate); + let index = encode_info_for_items(&ecx, &mut rbml_w, krate); stats.item_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i; rbml_w.end_tag(); i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap(); - encode_index(&mut rbml_w, items_index); + encode_item_index(&mut rbml_w, index.items); stats.index_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i; + i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap(); + encode_xrefs(&ecx, &mut rbml_w, index.xrefs); + stats.xref_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i; + encode_struct_field_attrs(&ecx, &mut rbml_w, krate); stats.total_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap(); @@ -2066,13 +2062,14 @@ fn encode_metadata_inner(wr: &mut Cursor>, println!(" misc bytes: {}", stats.misc_bytes); println!(" item bytes: {}", stats.item_bytes); println!(" index bytes: {}", stats.index_bytes); + println!(" xref bytes: {}", stats.xref_bytes); println!(" zero bytes: {}", stats.zero_bytes); println!(" total bytes: {}", stats.total_bytes); } } // Get the encoded string for a type -pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> String { +pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> Vec { let mut wr = Cursor::new(Vec::new()); tyencode::enc_ty(&mut Encoder::new(&mut wr), &tyencode::ctxt { diag: tcx.sess.diagnostic(), @@ -2080,5 +2077,5 @@ pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> String { tcx: tcx, abbrevs: &RefCell::new(FnvHashMap()) }, t); - String::from_utf8(wr.into_inner()).unwrap() + wr.into_inner() } diff --git a/src/librustc/metadata/index.rs b/src/librustc/metadata/index.rs index c60b789a2f1bf..60bbdaddd7516 100644 --- a/src/librustc/metadata/index.rs +++ b/src/librustc/metadata/index.rs @@ -10,7 +10,6 @@ use middle::def_id::{DefId, DefIndex}; use rbml; -use rbml::writer::Encoder; use std::io::{Cursor, Write}; use std::slice; use std::u32; @@ -74,16 +73,14 @@ impl IndexData { } } - pub fn record(&mut self, def_id: DefId, encoder: &mut Encoder) { + pub fn record(&mut self, def_id: DefId, position: u64) { assert!(def_id.is_local()); - self.record_index(def_id.index, encoder) + self.record_index(def_id.index, position) } - pub fn record_index(&mut self, item: DefIndex, encoder: &mut Encoder) { + pub fn record_index(&mut self, item: DefIndex, position: u64) { let item = item.as_usize(); - let position = encoder.mark_stable_position(); - assert!(position < (u32::MAX as u64)); let position = position as u32; @@ -101,6 +98,38 @@ impl IndexData { } } +/// A dense index with integer keys. Different API from IndexData (should +/// these be merged?) +pub struct DenseIndex { + start: usize, + end: usize +} + +impl DenseIndex { + pub fn lookup(&self, buf: &[u8], ix: u32) -> Option { + let data = bytes_to_words(&buf[self.start..self.end]); + data.get(ix as usize).map(|d| u32::from_be(*d)) + } + pub fn from_buf(buf: &[u8], start: usize, end: usize) -> Self { + assert!((end-start)%4 == 0 && start <= end && end <= buf.len()); + DenseIndex { + start: start, + end: end + } + } +} + +pub fn write_dense_index(entries: Vec, buf: &mut Cursor>) { + let elen = entries.len(); + assert!(elen < u32::MAX as usize); + + for entry in entries { + write_be_u32(buf, entry); + } + + info!("write_dense_index: {} entries", elen); +} + fn write_be_u32(w: &mut W, u: u32) { let _ = w.write_all(&[ (u >> 24) as u8, diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 4657323c1726d..d03af6b672284 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -98,6 +98,12 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { return &self.data[start_pos..end_pos]; } + fn parse_vuint(&mut self) -> usize { + let res = rbml::reader::vuint_at(self.data, self.pos).unwrap(); + self.pos = res.next; + res.val + } + fn parse_name(&mut self, last: char) -> ast::Name { fn is_last(b: char, c: char) -> bool { return c == b; } let bytes = self.scan(|a| is_last(last, a)); @@ -373,11 +379,8 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { // we return it (modulo closure types, see below). But if not, then we // jump to offset 123 and read the type from there. - let pos = self.parse_hex(); - assert_eq!(self.next(), ':'); - let len = self.parse_hex(); - assert_eq!(self.next(), '#'); - let key = ty::CReaderCacheKey {cnum: self.krate, pos: pos, len: len }; + let pos = self.parse_vuint(); + let key = ty::CReaderCacheKey { cnum: self.krate, pos: pos }; match tcx.rcache.borrow().get(&key).cloned() { Some(tt) => { // If there is a closure buried in the type some where, then we @@ -476,19 +479,6 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { subst::ParamSpace::from_uint(self.parse_uint()) } - fn parse_hex(&mut self) -> usize { - let mut n = 0; - loop { - let cur = self.peek(); - if (cur < '0' || cur > '9') && (cur < 'a' || cur > 'f') { return n; } - self.pos = self.pos + 1; - n *= 16; - if '0' <= cur && cur <= '9' { - n += (cur as usize) - ('0' as usize); - } else { n += 10 + (cur as usize) - ('a' as usize); } - }; - } - fn parse_abi_set(&mut self) -> abi::Abi { assert_eq!(self.next(), '['); let bytes = self.scan(|c| c == ']'); diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 01e6e30b53f77..1b993a00e2844 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -14,6 +14,7 @@ #![allow(non_camel_case_types)] use std::cell::RefCell; +use std::io::Cursor; use std::io::prelude::*; use middle::def_id::DefId; @@ -30,7 +31,7 @@ use syntax::abi::Abi; use syntax::ast; use syntax::diagnostic::SpanHandler; -use rbml::writer::Encoder; +use rbml::writer::{self, Encoder}; macro_rules! mywrite { ($w:expr, $($arg:tt)*) => ({ write!($w.writer, $($arg)*); }) } @@ -47,14 +48,14 @@ pub struct ctxt<'a, 'tcx: 'a> { // Extra parameters are for converting to/from def_ids in the string rep. // Whatever format you choose should not contain pipe characters. pub struct ty_abbrev { - s: String + s: Vec } pub type abbrev_map<'tcx> = RefCell, ty_abbrev>>; pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) { match cx.abbrevs.borrow_mut().get(&t) { - Some(a) => { w.writer.write_all(a.s.as_bytes()); return; } + Some(a) => { w.writer.write_all(&a.s); return; } None => {} } @@ -166,19 +167,22 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) { let end = w.mark_stable_position(); let len = end - pos; - fn estimate_sz(u: u64) -> u64 { - let mut n = u; - let mut len = 0; - while n != 0 { len += 1; n = n >> 4; } - return len; - } - let abbrev_len = 3 + estimate_sz(pos) + estimate_sz(len); - if abbrev_len < len { - // I.e. it's actually an abbreviation. - cx.abbrevs.borrow_mut().insert(t, ty_abbrev { - s: format!("#{:x}:{:x}#", pos, len) - }); - } + + let buf: &mut [u8] = &mut [0; 16]; // vuint < 15 bytes + let mut abbrev = Cursor::new(buf); + abbrev.write_all(b"#"); + writer::write_vuint(&mut abbrev, pos as usize); + + cx.abbrevs.borrow_mut().insert(t, ty_abbrev { + s: if abbrev.position() < len { + abbrev.get_ref()[..abbrev.position() as usize].to_owned() + } else { + // if the abbreviation is longer than the real type, + // don't use #-notation. However, insert it here so + // other won't have to `mark_stable_position` + w.writer.get_ref()[pos as usize..end as usize].to_owned() + } + }); } fn enc_mutability(w: &mut Encoder, mt: hir::Mutability) { diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 672ae5d3fb69c..6c23307c67776 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -33,7 +33,6 @@ use middle::def_id::DefId; use middle::privacy::{AllPublic, LastMod}; use middle::region; use middle::subst; -use middle::subst::VecPerParamSpace; use middle::ty::{self, Ty}; use syntax::{ast, ast_util, codemap}; @@ -124,7 +123,8 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, tcx: &ty::ctxt<'tcx>, path: Vec, def_path: ast_map::DefPath, - par_doc: rbml::Doc) + par_doc: rbml::Doc, + orig_did: DefId) -> Result<&'tcx InlinedItem, (Vec, ast_map::DefPath)> { match par_doc.opt_child(c::tag_ast) { @@ -163,6 +163,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, name); region::resolve_inlined_item(&tcx.sess, &tcx.region_maps, ii); decode_side_tables(dcx, ast_doc); + copy_item_types(dcx, ii, orig_did); match *ii { InlinedItem::Item(ref i) => { debug!(">>> DECODED ITEM >>>\n{}\n<<< DECODED ITEM <<<", @@ -554,36 +555,6 @@ pub fn encode_cast_kind(ebml_w: &mut Encoder, kind: cast::CastKind) { kind.encode(ebml_w).unwrap(); } -pub trait vtable_decoder_helpers<'tcx> { - fn read_vec_per_param_space(&mut self, f: F) -> VecPerParamSpace where - F: FnMut(&mut Self) -> T; -} - -impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> { - fn read_vec_per_param_space(&mut self, mut f: F) -> VecPerParamSpace where - F: FnMut(&mut reader::Decoder<'a>) -> T, - { - let types = self.read_to_vec(|this| Ok(f(this))).unwrap(); - let selfs = self.read_to_vec(|this| Ok(f(this))).unwrap(); - let fns = self.read_to_vec(|this| Ok(f(this))).unwrap(); - VecPerParamSpace::new(types, selfs, fns) - } -} - -// ___________________________________________________________________________ -// - -fn encode_vec_per_param_space(rbml_w: &mut Encoder, - v: &subst::VecPerParamSpace, - mut f: F) where - F: FnMut(&mut Encoder, &T), -{ - for &space in &subst::ParamSpace::all() { - rbml_w.emit_from_vec(v.get_slice(space), - |rbml_w, n| Ok(f(rbml_w, n))).unwrap(); - } -} - // ______________________________________________________________________ // Encoding and decoding the side tables @@ -606,16 +577,10 @@ trait rbml_writer_helpers<'tcx> { fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region); fn emit_ty<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, ty: Ty<'tcx>); fn emit_tys<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, tys: &[Ty<'tcx>]); - fn emit_type_param_def<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, - type_param_def: &ty::TypeParameterDef<'tcx>); - fn emit_region_param_def(&mut self, ecx: &e::EncodeContext, - region_param_def: &ty::RegionParameterDef); fn emit_predicate<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, predicate: &ty::Predicate<'tcx>); fn emit_trait_ref<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, ty: &ty::TraitRef<'tcx>); - fn emit_type_scheme<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, - type_scheme: ty::TypeScheme<'tcx>); fn emit_substs<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, substs: &subst::Substs<'tcx>); fn emit_existential_bounds<'b>(&mut self, ecx: &e::EncodeContext<'b,'tcx>, @@ -648,22 +613,6 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> { self.emit_opaque(|this| Ok(e::write_trait_ref(ecx, this, trait_ref))); } - fn emit_type_param_def<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, - type_param_def: &ty::TypeParameterDef<'tcx>) { - self.emit_opaque(|this| { - Ok(tyencode::enc_type_param_def(this, - &ecx.ty_str_ctxt(), - type_param_def)) - }); - } - fn emit_region_param_def(&mut self, ecx: &e::EncodeContext, - region_param_def: &ty::RegionParameterDef) { - self.emit_opaque(|this| { - Ok(tyencode::enc_region_param_def(this, - &ecx.ty_str_ctxt(), - region_param_def)) - }); - } fn emit_predicate<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, predicate: &ty::Predicate<'tcx>) { self.emit_opaque(|this| { @@ -673,32 +622,6 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> { }); } - fn emit_type_scheme<'b>(&mut self, - ecx: &e::EncodeContext<'b, 'tcx>, - type_scheme: ty::TypeScheme<'tcx>) { - use serialize::Encoder; - - self.emit_struct("TypeScheme", 2, |this| { - this.emit_struct_field("generics", 0, |this| { - this.emit_struct("Generics", 2, |this| { - this.emit_struct_field("types", 0, |this| { - Ok(encode_vec_per_param_space( - this, &type_scheme.generics.types, - |this, def| this.emit_type_param_def(ecx, def))) - }); - this.emit_struct_field("regions", 1, |this| { - Ok(encode_vec_per_param_space( - this, &type_scheme.generics.regions, - |this, def| this.emit_region_param_def(ecx, def))) - }) - }) - }); - this.emit_struct_field("ty", 1, |this| { - Ok(this.emit_ty(ecx, type_scheme.ty)) - }) - }); - } - fn emit_existential_bounds<'b>(&mut self, ecx: &e::EncodeContext<'b,'tcx>, bounds: &ty::ExistentialBounds<'tcx>) { self.emit_opaque(|this| Ok(tyencode::enc_existential_bounds(this, @@ -918,23 +841,6 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, } } - let opt_def_id = tcx.map.opt_local_def_id(id); - if let Some(lid) = opt_def_id { - if let Some(type_scheme) = tcx.tcache.borrow().get(&lid) { - rbml_w.tag(c::tag_table_tcache, |rbml_w| { - rbml_w.id(id); - rbml_w.emit_type_scheme(ecx, type_scheme.clone()); - }) - } - } - - if let Some(type_param_def) = tcx.ty_param_defs.borrow().get(&id) { - rbml_w.tag(c::tag_table_param_defs, |rbml_w| { - rbml_w.id(id); - rbml_w.emit_type_param_def(ecx, type_param_def) - }) - } - let method_call = ty::MethodCall::expr(id); if let Some(method) = tcx.tables.borrow().method_map.get(&method_call) { rbml_w.tag(c::tag_table_method_map, |rbml_w| { @@ -1005,14 +911,8 @@ trait rbml_decoder_decoder_helpers<'tcx> { -> ty::TraitRef<'tcx>; fn read_poly_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> ty::PolyTraitRef<'tcx>; - fn read_type_param_def<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) - -> ty::TypeParameterDef<'tcx>; - fn read_region_param_def(&mut self, dcx: &DecodeContext) - -> ty::RegionParameterDef; fn read_predicate<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> ty::Predicate<'tcx>; - fn read_type_scheme<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) - -> ty::TypeScheme<'tcx>; fn read_existential_bounds<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> ty::ExistentialBounds<'tcx>; fn read_substs<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) @@ -1124,48 +1024,12 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { ty::Binder(self.read_ty_encoded(dcx, |decoder| decoder.parse_trait_ref())) } - fn read_type_param_def<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) - -> ty::TypeParameterDef<'tcx> { - self.read_ty_encoded(dcx, |decoder| decoder.parse_type_param_def()) - } - fn read_region_param_def(&mut self, dcx: &DecodeContext) - -> ty::RegionParameterDef { - self.read_ty_encoded(dcx, |decoder| decoder.parse_region_param_def()) - } fn read_predicate<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> ty::Predicate<'tcx> { self.read_ty_encoded(dcx, |decoder| decoder.parse_predicate()) } - fn read_type_scheme<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) - -> ty::TypeScheme<'tcx> { - self.read_struct("TypeScheme", 3, |this| { - Ok(ty::TypeScheme { - generics: this.read_struct_field("generics", 0, |this| { - this.read_struct("Generics", 2, |this| { - Ok(ty::Generics { - types: - this.read_struct_field("types", 0, |this| { - Ok(this.read_vec_per_param_space( - |this| this.read_type_param_def(dcx))) - }).unwrap(), - - regions: - this.read_struct_field("regions", 1, |this| { - Ok(this.read_vec_per_param_space( - |this| this.read_region_param_def(dcx))) - }).unwrap(), - }) - }) - }).unwrap(), - ty: this.read_struct_field("ty", 1, |this| { - Ok(this.read_ty(dcx)) - }).unwrap() - }) - }).unwrap() - } - fn read_existential_bounds<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> ty::ExistentialBounds<'tcx> { @@ -1385,15 +1249,6 @@ fn decode_side_tables(dcx: &DecodeContext, let ub = val_dsr.read_upvar_capture(dcx); dcx.tcx.tables.borrow_mut().upvar_capture_map.insert(upvar_id, ub); } - c::tag_table_tcache => { - let type_scheme = val_dsr.read_type_scheme(dcx); - let lid = dcx.tcx.map.local_def_id(id); - dcx.tcx.register_item_type(lid, type_scheme); - } - c::tag_table_param_defs => { - let bounds = val_dsr.read_type_param_def(dcx); - dcx.tcx.ty_param_defs.borrow_mut().insert(id, bounds); - } c::tag_table_method_map => { let (autoderef, method) = val_dsr.read_method_callee(dcx); let method_call = ty::MethodCall { @@ -1429,6 +1284,50 @@ fn decode_side_tables(dcx: &DecodeContext, } } +// copy the tcache entries from the original item to the new +// inlined item +fn copy_item_types(dcx: &DecodeContext, ii: &InlinedItem, orig_did: DefId) { + fn copy_item_type(dcx: &DecodeContext, + inlined_id: ast::NodeId, + remote_did: DefId) { + let inlined_did = dcx.tcx.map.local_def_id(inlined_id); + dcx.tcx.register_item_type(inlined_did, + dcx.tcx.lookup_item_type(remote_did)); + + } + // copy the entry for the item itself + let item_node_id = match ii { + &InlinedItem::Item(ref i) => i.id, + &InlinedItem::TraitItem(_, ref ti) => ti.id, + &InlinedItem::ImplItem(_, ref ii) => ii.id, + &InlinedItem::Foreign(ref fi) => fi.id + }; + copy_item_type(dcx, item_node_id, orig_did); + + // copy the entries of inner items + if let &InlinedItem::Item(ref item) = ii { + match item.node { + hir::ItemEnum(ref def, _) => { + let orig_def = dcx.tcx.lookup_adt_def(orig_did); + for (i_variant, orig_variant) in + def.variants.iter().zip(orig_def.variants.iter()) + { + copy_item_type(dcx, i_variant.node.id, orig_variant.did); + } + } + hir::ItemStruct(ref def, _) => { + if let Some(ctor_id) = def.ctor_id { + let ctor_did = dcx.tcx.lookup_adt_def(orig_did) + .struct_variant().ctor_id; + debug!("copying ctor {:?}", ctor_did); + copy_item_type(dcx, ctor_id, ctor_did); + } + } + _ => {} + } + } +} + // ______________________________________________________________________ // Testing of astencode_gen diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index d3f427e770cf3..e275ac7bc7dc6 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -143,7 +143,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>, } let mut used_ref_id = false; let expr_id = match csearch::maybe_get_item_ast(tcx, def_id, - Box::new(|a, b, c, d, e| astencode::decode_inlined_item(a, b, c, d, e))) { + Box::new(astencode::decode_inlined_item)) { csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node { hir::ItemConst(_, ref const_expr) => Some(const_expr.id), _ => None @@ -199,7 +199,7 @@ fn inline_const_fn_from_external_crate(tcx: &ty::ctxt, def_id: DefId) } let fn_id = match csearch::maybe_get_item_ast(tcx, def_id, - box |a, b, c, d, e| astencode::decode_inlined_item(a, b, c, d, e)) { + box astencode::decode_inlined_item) { csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => Some(item.id), csearch::FoundAst::Found(&InlinedItem::ImplItem(_, ref item)) => Some(item.id), _ => None diff --git a/src/librustc/middle/def_id.rs b/src/librustc/middle/def_id.rs index ed7a1d75a52e9..ba4eac9e9eb86 100644 --- a/src/librustc/middle/def_id.rs +++ b/src/librustc/middle/def_id.rs @@ -82,5 +82,3 @@ impl DefId { self.krate == LOCAL_CRATE } } - - diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs index 315268fd0b626..fddfb7b583eb3 100644 --- a/src/librustc/middle/ty/mod.rs +++ b/src/librustc/middle/ty/mod.rs @@ -367,7 +367,6 @@ pub type MethodMap<'tcx> = FnvHashMap>; pub struct CReaderCacheKey { pub cnum: CrateNum, pub pos: usize, - pub len: usize } /// A restriction that certain types must be the same size. The use of @@ -1474,7 +1473,10 @@ pub struct VariantDefData<'tcx, 'container: 'tcx> { pub did: DefId, pub name: Name, // struct's name if this is a struct pub disr_val: Disr, - pub fields: Vec> + pub fields: Vec>, + /// The DefId of the variant's ctor (unless the variant is a + /// tuple-like struct variant, this is just the variant's def-id). + pub ctor_id: DefId } pub struct FieldDefData<'tcx, 'container: 'tcx> { @@ -2820,4 +2822,3 @@ pub trait HasTypeFlags { !self.has_type_flags(TypeFlags::HAS_LOCAL_NAMES) } } - diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 512f2a9c59f6b..bae14afd81d66 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -215,7 +215,7 @@ fn symbol_hash<'tcx>(tcx: &ty::ctxt<'tcx>, symbol_hasher.input_str(&meta[..]); } symbol_hasher.input_str("-"); - symbol_hasher.input_str(&encoder::encoded_ty(tcx, t)); + symbol_hasher.input(&encoder::encoded_ty(tcx, t)); // Prefix with 'h' so that it never blends into adjacent digits let mut hash = String::from("h"); hash.push_str(&truncated_hash_result(symbol_hasher)); diff --git a/src/librustc_trans/trans/inline.rs b/src/librustc_trans/trans/inline.rs index 14b65bcb75504..b8f75df8c11ca 100644 --- a/src/librustc_trans/trans/inline.rs +++ b/src/librustc_trans/trans/inline.rs @@ -44,7 +44,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) let csearch_result = csearch::maybe_get_item_ast( ccx.tcx(), fn_id, - Box::new(|a,b,c,d,e| astencode::decode_inlined_item(a, b, c, d,e))); + Box::new(astencode::decode_inlined_item)); let inline_id = match csearch_result { csearch::FoundAst::NotFound => { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 7a70bc73b7338..25a61414ab514 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1102,7 +1102,8 @@ fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>, did: DefId, name: ast::Name, disr_val: ty::Disr, - def: &hir::StructDef) -> ty::VariantDefData<'tcx, 'tcx> { + def: &hir::StructDef, + ctor_id: DefId) -> ty::VariantDefData<'tcx, 'tcx> { let mut seen_fields: FnvHashMap = FnvHashMap(); let fields = def.fields.iter().map(|f| { let fid = tcx.map.local_def_id(f.node.id); @@ -1129,7 +1130,8 @@ fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>, did: did, name: name, disr_val: disr_val, - fields: fields + fields: fields, + ctor_id: ctor_id } } @@ -1140,10 +1142,12 @@ fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>, { let did = tcx.map.local_def_id(it.id); + let ctor_id = def.ctor_id.map_or(did, + |ctor_id| tcx.map.local_def_id(ctor_id)); tcx.intern_adt_def( did, ty::AdtKind::Struct, - vec![convert_struct_variant(tcx, did, it.name, 0, def)] + vec![convert_struct_variant(tcx, did, it.name, 0, def, ctor_id)] ) } @@ -1233,11 +1237,12 @@ fn convert_enum_def<'tcx>(tcx: &ty::ctxt<'tcx>, special_idents::unnamed_field.name, hir::Visibility::Public ) - }).collect() + }).collect(), + ctor_id: did } } hir::StructVariantKind(ref def) => { - convert_struct_variant(tcx, did, name, disr, &def) + convert_struct_variant(tcx, did, name, disr, &def, did) } } }