diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index 06a40f1dd277d..b6202084296bb 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -189,6 +189,7 @@ 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_items_data_item_inherent_impl: usize = 0x80; pub const tag_items_data_item_extension_impl: usize = 0x81; diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 7132ac4895aa1..6caefec48783a 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -304,31 +304,23 @@ pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum) decoder::get_native_libraries(&*cdata) } -pub fn each_impl(cstore: &cstore::CStore, - crate_num: ast::CrateNum, - callback: F) where - F: FnMut(ast::DefId), -{ - let cdata = cstore.get_crate_data(crate_num); - decoder::each_impl(&*cdata, callback) -} - -pub fn each_implementation_for_type(cstore: &cstore::CStore, - def_id: ast::DefId, - callback: F) where +pub fn each_inherent_implementation_for_type(cstore: &cstore::CStore, + def_id: ast::DefId, + callback: F) where F: FnMut(ast::DefId), { let cdata = cstore.get_crate_data(def_id.krate); - decoder::each_implementation_for_type(&*cdata, def_id.node, callback) + decoder::each_inherent_implementation_for_type(&*cdata, def_id.node, callback) } pub fn each_implementation_for_trait(cstore: &cstore::CStore, def_id: ast::DefId, - callback: F) where + mut callback: F) where F: FnMut(ast::DefId), { - let cdata = cstore.get_crate_data(def_id.krate); - decoder::each_implementation_for_trait(&*cdata, def_id.node, callback) + cstore.iter_crate_data(|_, cdata| { + decoder::each_implementation_for_trait(cdata, def_id, &mut callback) + }) } /// If the given def ID describes an item belonging to a trait (either a diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 00fc42341c389..382dc437bdc48 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -21,7 +21,8 @@ use metadata::common::*; use metadata::csearch::MethodInfo; use metadata::csearch; use metadata::cstore; -use metadata::tydecode::{parse_ty_data, parse_region_data, parse_def_id, +use metadata::encoder::def_to_u64; +use metadata::tydecode::{parse_ty_data, parse_region_data, parse_type_param_def_data, parse_bare_fn_ty_data, parse_trait_ref_data, parse_predicate_data}; use middle::def; @@ -190,29 +191,32 @@ fn item_symbol(item: rbml::Doc) -> String { reader::get_doc(item, tag_items_data_item_symbol).as_str().to_string() } -fn item_parent_item(d: rbml::Doc) -> Option { +fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> ast::DefId { + let id = reader::doc_as_u64(d); + let def_id = ast::DefId { krate: (id >> 32) as u32, node: id as u32 }; + translate_def_id(cdata, def_id) +} + +fn item_parent_item(cdata: Cmd, d: rbml::Doc) -> Option { let mut ret = None; reader::tagged_docs(d, tag_items_data_parent_item, |did| { - ret = Some(reader::with_doc_data(did, parse_def_id)); + ret = Some(translated_def_id(cdata, did)); false }); ret } -fn item_reqd_and_translated_parent_item(cnum: ast::CrateNum, - d: rbml::Doc) -> ast::DefId { - let trait_did = item_parent_item(d).expect("item without parent"); - ast::DefId { krate: cnum, node: trait_did.node } +fn item_require_parent_item(cdata: Cmd, d: rbml::Doc) -> ast::DefId { + translated_def_id(cdata, reader::get_doc(d, tag_items_data_parent_item)) } fn item_def_id(d: rbml::Doc, cdata: Cmd) -> ast::DefId { - let tagdoc = reader::get_doc(d, tag_def_id); - return translate_def_id(cdata, reader::with_doc_data(tagdoc, parse_def_id)); + translated_def_id(cdata, reader::get_doc(d, tag_def_id)) } fn get_provided_source(d: rbml::Doc, cdata: Cmd) -> Option { reader::maybe_get_doc(d, tag_item_method_provided_source).map(|doc| { - translate_def_id(cdata, reader::with_doc_data(doc, parse_def_id)) + translated_def_id(cdata, doc) }) } @@ -261,14 +265,12 @@ fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) } fn enum_variant_ids(item: rbml::Doc, cdata: Cmd) -> Vec { - let mut ids: Vec = Vec::new(); - let v = tag_items_data_item_variant; - reader::tagged_docs(item, v, |p| { - let ext = reader::with_doc_data(p, parse_def_id); - ids.push(ast::DefId { krate: cdata.cnum, node: ext.node }); + let mut ids = vec![]; + reader::tagged_docs(item, tag_items_data_item_variant, |p| { + ids.push(translated_def_id(cdata, p)); true }); - return ids; + ids } fn item_path(item_doc: rbml::Doc) -> Vec { @@ -303,8 +305,7 @@ fn item_name(intr: &IdentInterner, item: rbml::Doc) -> ast::Name { } } -fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum) - -> DefLike { +fn item_to_def_like(cdata: Cmd, item: rbml::Doc, did: ast::DefId) -> DefLike { let fam = item_family(item); match fam { Constant => { @@ -314,11 +315,9 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum) // See the comment for methods below. let provenance = if reader::maybe_get_doc( item, tag_item_trait_parent_sort).is_some() { - def::FromTrait(item_reqd_and_translated_parent_item(cnum, - item)) + def::FromTrait(item_require_parent_item(cdata, item)) } else { - def::FromImpl(item_reqd_and_translated_parent_item(cnum, - item)) + def::FromImpl(item_require_parent_item(cdata, item)) }; DlDef(def::DefAssociatedConst(did, provenance)) } else { @@ -339,17 +338,15 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum) // a trait_parent_sort. let provenance = if reader::maybe_get_doc( item, tag_item_trait_parent_sort).is_some() { - def::FromTrait(item_reqd_and_translated_parent_item(cnum, - item)) + def::FromTrait(item_require_parent_item(cdata, item)) } else { - def::FromImpl(item_reqd_and_translated_parent_item(cnum, - item)) + def::FromImpl(item_require_parent_item(cdata, item)) }; DlDef(def::DefMethod(did, provenance)) } Type => { if item_sort(item) == Some('t') { - let trait_did = item_reqd_and_translated_parent_item(cnum, item); + let trait_did = item_require_parent_item(cdata, item); DlDef(def::DefAssociatedTy(trait_did, did)) } else { DlDef(def::DefTy(did, false)) @@ -358,11 +355,11 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum) Mod => DlDef(def::DefMod(did)), ForeignMod => DlDef(def::DefForeignMod(did)), StructVariant => { - let enum_did = item_reqd_and_translated_parent_item(cnum, item); + let enum_did = item_require_parent_item(cdata, item); DlDef(def::DefVariant(enum_did, did, true)) } TupleVariant => { - let enum_did = item_reqd_and_translated_parent_item(cnum, item); + let enum_did = item_require_parent_item(cdata, item); DlDef(def::DefVariant(enum_did, did, false)) } Trait => DlDef(def::DefTrait(did)), @@ -560,9 +557,7 @@ fn each_child_of_item_or_crate(intr: Rc, { // Iterate over all children. let _ = reader::tagged_docs(item_doc, tag_mod_child, |child_info_doc| { - let child_def_id = reader::with_doc_data(child_info_doc, - parse_def_id); - let child_def_id = translate_def_id(cdata, child_def_id); + let child_def_id = translated_def_id(cdata, child_info_doc); // This item may be in yet another crate if it was the child of a // reexport. @@ -584,9 +579,7 @@ fn each_child_of_item_or_crate(intr: Rc, Some(child_item_doc) => { // Hand off the item to the callback. let child_name = item_name(&*intr, child_item_doc); - let def_like = item_to_def_like(child_item_doc, - child_def_id, - cdata.cnum); + let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id); let visibility = item_visibility(child_item_doc); callback(def_like, child_name, visibility); @@ -615,9 +608,8 @@ fn each_child_of_item_or_crate(intr: Rc, 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); - let static_method_def_like = item_to_def_like(impl_method_doc, - impl_item_def_id, - cdata.cnum); + let static_method_def_like = item_to_def_like(cdata, impl_method_doc, + impl_item_def_id); callback(static_method_def_like, static_method_name, item_visibility(impl_method_doc)); @@ -633,9 +625,7 @@ fn each_child_of_item_or_crate(intr: Rc, let _ = each_reexport(item_doc, |reexport_doc| { let def_id_doc = reader::get_doc(reexport_doc, tag_items_data_item_reexport_def_id); - let child_def_id = reader::with_doc_data(def_id_doc, - parse_def_id); - let child_def_id = translate_def_id(cdata, child_def_id); + let child_def_id = translated_def_id(cdata, def_id_doc); let name_doc = reader::get_doc(reexport_doc, tag_items_data_item_reexport_name); @@ -657,9 +647,7 @@ fn each_child_of_item_or_crate(intr: Rc, // Get the item. if let Some(child_item_doc) = maybe_find_item(child_def_id.node, other_crates_items) { // Hand off the item to the callback. - let def_like = item_to_def_like(child_item_doc, - child_def_id, - child_def_id.krate); + 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 // a public re-export. callback(def_like, token::intern(name), ast::Public); @@ -733,9 +721,8 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeI match decode_inlined_item(cdata, tcx, path, item_doc) { Ok(ii) => csearch::FoundAst::Found(ii), Err(path) => { - match item_parent_item(item_doc) { + match item_parent_item(cdata, item_doc) { Some(did) => { - let did = translate_def_id(cdata, did); let parent_item = lookup_item(did.node, cdata.data()); match decode_inlined_item(cdata, tcx, path, parent_item) { Ok(ii) => csearch::FoundAst::FoundParent(did, ii), @@ -759,7 +746,7 @@ pub fn get_enum_variant_defs(intr: &IdentInterner, let item = find_item(did.node, items); let name = item_name(intr, item); let visibility = item_visibility(item); - match item_to_def_like(item, *did, cdata.cnum) { + match item_to_def_like(cdata, item, *did) { DlDef(def @ def::DefVariant(..)) => (def, name, visibility), _ => unreachable!() } @@ -889,8 +876,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc, let def_id = item_def_id(method_doc, cdata); - let container_id = item_reqd_and_translated_parent_item(cdata.cnum, - method_doc); + let container_id = item_require_parent_item(cdata, method_doc); let container_doc = lookup_item(container_id.node, cdata.data()); let container = match item_family(container_doc) { Trait => TraitContainer(container_id), @@ -1094,7 +1080,7 @@ pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd, let item = lookup_item(node_id, cdata.data()); let mut ret = None; reader::tagged_docs(item, tag_items_data_item_is_tuple_struct_ctor, |_| { - ret = Some(item_reqd_and_translated_parent_item(cdata.cnum, item)); + ret = Some(item_require_parent_item(cdata, item)); false }); ret @@ -1144,7 +1130,7 @@ pub fn get_struct_fields(intr: Rc, cdata: Cmd, id: ast::NodeId) let name = item_name(&*intr, an_item); let did = item_def_id(an_item, cdata); let tagdoc = reader::get_doc(an_item, tag_item_field_origin); - let origin_id = translate_def_id(cdata, reader::with_doc_data(tagdoc, parse_def_id)); + let origin_id = translated_def_id(cdata, tagdoc); result.push(ty::field_ty { name: name, id: did, @@ -1158,7 +1144,7 @@ pub fn get_struct_fields(intr: Rc, cdata: Cmd, id: ast::NodeId) let did = item_def_id(an_item, cdata); let tagdoc = reader::get_doc(an_item, tag_item_field_origin); let f = item_family(an_item); - let origin_id = translate_def_id(cdata, reader::with_doc_data(tagdoc, parse_def_id)); + let origin_id = translated_def_id(cdata, tagdoc); result.push(ty::field_ty { name: special_idents::unnamed_field.name, id: did, @@ -1342,55 +1328,77 @@ pub fn translate_def_id(cdata: Cmd, did: ast::DefId) -> ast::DefId { } } -pub fn each_impl(cdata: Cmd, mut callback: F) where - F: FnMut(ast::DefId), -{ - let impls_doc = reader::get_doc(rbml::Doc::new(cdata.data()), tag_impls); - let _ = reader::tagged_docs(impls_doc, tag_impls_impl, |impl_doc| { - callback(item_def_id(impl_doc, cdata)); - true - }); +// Translate a DefId from the current compilation environment to a DefId +// for an external crate. +fn reverse_translate_def_id(cdata: Cmd, did: ast::DefId) -> Option { + if did.krate == cdata.cnum { + return Some(ast::DefId { krate: ast::LOCAL_CRATE, node: did.node }); + } + + for (&local, &global) in &cdata.cnum_map { + if global == did.krate { + return Some(ast::DefId { krate: local, node: did.node }); + } + } + + None } -pub fn each_implementation_for_type(cdata: Cmd, - id: ast::NodeId, - mut callback: F) +pub fn each_inherent_implementation_for_type(cdata: Cmd, + id: ast::NodeId, + mut callback: F) where F: FnMut(ast::DefId), { let item_doc = lookup_item(id, cdata.data()); reader::tagged_docs(item_doc, tag_items_data_item_inherent_impl, |impl_doc| { - let implementation_def_id = item_def_id(impl_doc, cdata); - callback(implementation_def_id); + if reader::maybe_get_doc(impl_doc, tag_item_trait_ref).is_none() { + callback(item_def_id(impl_doc, cdata)); + } true }); } pub fn each_implementation_for_trait(cdata: Cmd, - id: ast::NodeId, + def_id: ast::DefId, mut callback: F) where F: FnMut(ast::DefId), { - let item_doc = lookup_item(id, cdata.data()); + if cdata.cnum == def_id.krate { + let item_doc = lookup_item(def_id.node, cdata.data()); + let _ = reader::tagged_docs(item_doc, + tag_items_data_item_extension_impl, + |impl_doc| { + callback(item_def_id(impl_doc, cdata)); + true + }); + return; + } - let _ = reader::tagged_docs(item_doc, - tag_items_data_item_extension_impl, - |impl_doc| { - let implementation_def_id = item_def_id(impl_doc, cdata); - callback(implementation_def_id); - true - }); + // 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); + let _ = reader::tagged_docs(impls_doc, tag_impls_impl, |impl_doc| { + 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)); + } + true + }); + } } pub fn get_trait_of_item(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) -> Option { let item_doc = lookup_item(id, cdata.data()); - let parent_item_id = match item_parent_item(item_doc) { + let parent_item_id = match item_parent_item(cdata, item_doc) { None => return None, Some(item_id) => item_id, }; - let parent_item_id = translate_def_id(cdata, parent_item_id); let parent_item_doc = lookup_item(parent_item_id.node, cdata.data()); match item_family(parent_item_doc) { Trait => Some(item_def_id(parent_item_doc, cdata)), @@ -1538,8 +1546,7 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc, let name = item_name(&*token::get_ident_interner(), ident_str_doc); let def_id_doc = reader::get_doc(rp_doc, tag_region_param_def_def_id); - let def_id = reader::with_doc_data(def_id_doc, parse_def_id); - let def_id = translate_def_id(cdata, def_id); + let def_id = translated_def_id(cdata, def_id_doc); let doc = reader::get_doc(rp_doc, tag_region_param_def_space); let space = subst::ParamSpace::from_uint(reader::doc_as_u64(doc) as usize); diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 90dd452e06b5b..afc71f83975c2 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -91,8 +91,8 @@ fn encode_impl_type_basename(rbml_w: &mut Encoder, name: ast::Name) { rbml_w.wr_tagged_str(tag_item_impl_type_basename, &token::get_name(name)); } -pub fn encode_def_id(rbml_w: &mut Encoder, id: DefId) { - rbml_w.wr_tagged_str(tag_def_id, &def_to_string(id)); +fn encode_def_id(rbml_w: &mut Encoder, id: DefId) { + rbml_w.wr_tagged_u64(tag_def_id, def_to_u64(id)); } #[derive(Clone)] @@ -122,6 +122,10 @@ fn encode_family(rbml_w: &mut Encoder, c: char) { rbml_w.wr_tagged_u8(tag_items_data_item_family, c as u8); } +pub fn def_to_u64(did: DefId) -> u64 { + (did.krate as u64) << 32 | (did.node as u64) +} + pub fn def_to_string(did: DefId) -> String { format!("{}:{}", did.krate, did.node) } @@ -153,9 +157,9 @@ fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder, } fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) { - let s = def_to_string(vid); - rbml_w.wr_tagged_str(tag_items_data_item_variant, &s[..]); - rbml_w.wr_tagged_str(tag_mod_child, &s[..]); + let id = def_to_u64(vid); + rbml_w.wr_tagged_u64(tag_items_data_item_variant, id); + rbml_w.wr_tagged_u64(tag_mod_child, id); } pub fn write_closure_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, @@ -260,7 +264,7 @@ fn encode_disr_val(_: &EncodeContext, } fn encode_parent_item(rbml_w: &mut Encoder, id: DefId) { - rbml_w.wr_tagged_str(tag_items_data_parent_item, &def_to_string(id)); + rbml_w.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(id)); } fn encode_struct_fields(rbml_w: &mut Encoder, @@ -275,7 +279,7 @@ fn encode_struct_fields(rbml_w: &mut Encoder, } encode_struct_field_family(rbml_w, f.vis); encode_def_id(rbml_w, f.id); - rbml_w.wr_tagged_str(tag_item_field_origin, &def_to_string(origin)); + rbml_w.wr_tagged_u64(tag_item_field_origin, def_to_u64(origin)); rbml_w.end_tag(); } } @@ -358,8 +362,8 @@ fn encode_reexported_static_method(rbml_w: &mut Encoder, debug!("(encode reexported static method) {}::{}", exp.name, token::get_name(method_name)); rbml_w.start_tag(tag_items_data_item_reexport); - rbml_w.wr_tagged_str(tag_items_data_item_reexport_def_id, - &def_to_string(method_def_id)); + rbml_w.wr_tagged_u64(tag_items_data_item_reexport_def_id, + def_to_u64(method_def_id)); rbml_w.wr_tagged_str(tag_items_data_item_reexport_name, &format!("{}::{}", exp.name, token::get_name(method_name))); @@ -495,8 +499,8 @@ fn encode_reexports(ecx: &EncodeContext, exp.def_id.node, id); rbml_w.start_tag(tag_items_data_item_reexport); - rbml_w.wr_tagged_str(tag_items_data_item_reexport_def_id, - &def_to_string(exp.def_id)); + rbml_w.wr_tagged_u64(tag_items_data_item_reexport_def_id, + def_to_u64(exp.def_id)); rbml_w.wr_tagged_str(tag_items_data_item_reexport_name, exp.name.as_str()); rbml_w.end_tag(); @@ -526,12 +530,12 @@ fn encode_info_for_mod(ecx: &EncodeContext, // Encode info about all the module children. for item in &md.items { - rbml_w.wr_tagged_str(tag_mod_child, - &def_to_string(local_def(item.id))); + rbml_w.wr_tagged_u64(tag_mod_child, + def_to_u64(local_def(item.id))); each_auxiliary_node_id(&**item, |auxiliary_node_id| { - rbml_w.wr_tagged_str(tag_mod_child, - &def_to_string(local_def(auxiliary_node_id))); + rbml_w.wr_tagged_u64(tag_mod_child, + def_to_u64(local_def(auxiliary_node_id))); true }); @@ -541,8 +545,7 @@ fn encode_info_for_mod(ecx: &EncodeContext, token::get_ident(ident), did, ecx.tcx.map.node_to_string(did)); - rbml_w.wr_tagged_str(tag_mod_impl, - &def_to_string(local_def(did))); + rbml_w.wr_tagged_u64(tag_mod_impl, def_to_u64(local_def(did))); } } @@ -619,8 +622,7 @@ fn encode_parent_sort(rbml_w: &mut Encoder, sort: char) { fn encode_provided_source(rbml_w: &mut Encoder, source_opt: Option) { if let Some(source) = source_opt { - rbml_w.wr_tagged_str(tag_item_method_provided_source, - &def_to_string(source)); + rbml_w.wr_tagged_u64(tag_item_method_provided_source, def_to_u64(source)); } } @@ -725,8 +727,8 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder, encode_name(rbml_w, param.name); rbml_w.end_tag(); - rbml_w.wr_tagged_str(tag_region_param_def_def_id, - &def_to_string(param.def_id)); + rbml_w.wr_tagged_u64(tag_region_param_def_def_id, + def_to_u64(param.def_id)); rbml_w.wr_tagged_u64(tag_region_param_def_space, param.space.to_uint() as u64); @@ -1089,8 +1091,8 @@ fn encode_info_for_item(ecx: &EncodeContext, // Encode all the items in this module. for foreign_item in &fm.items { - rbml_w.wr_tagged_str(tag_mod_child, - &def_to_string(local_def(foreign_item.id))); + rbml_w.wr_tagged_u64(tag_mod_child, + def_to_u64(local_def(foreign_item.id))); } encode_visibility(rbml_w, vis); encode_stability(rbml_w, stab); @@ -1335,8 +1337,8 @@ fn encode_info_for_item(ecx: &EncodeContext, } rbml_w.end_tag(); - rbml_w.wr_tagged_str(tag_mod_child, - &def_to_string(method_def_id.def_id())); + rbml_w.wr_tagged_u64(tag_mod_child, + def_to_u64(method_def_id.def_id())); } encode_path(rbml_w, path.clone()); @@ -1893,6 +1895,7 @@ impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> { def_id.krate != ast::LOCAL_CRATE { self.rbml_w.start_tag(tag_impls_impl); encode_def_id(self.rbml_w, local_def(item.id)); + self.rbml_w.wr_tagged_u64(tag_impls_impl_trait_def_id, def_to_u64(def_id)); self.rbml_w.end_tag(); } } @@ -1932,12 +1935,12 @@ fn encode_misc_info(ecx: &EncodeContext, rbml_w.start_tag(tag_misc_info); rbml_w.start_tag(tag_misc_info_crate_items); for item in &krate.module.items { - rbml_w.wr_tagged_str(tag_mod_child, - &def_to_string(local_def(item.id))); + rbml_w.wr_tagged_u64(tag_mod_child, + def_to_u64(local_def(item.id))); each_auxiliary_node_id(&**item, |auxiliary_node_id| { - rbml_w.wr_tagged_str(tag_mod_child, - &def_to_string(local_def(auxiliary_node_id))); + rbml_w.wr_tagged_u64(tag_mod_child, + def_to_u64(local_def(auxiliary_node_id))); true }); } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 5298c9682b48c..3ec400b35c95a 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2564,9 +2564,11 @@ impl<'tcx> TraitDef<'tcx> { tcx: &ctxt<'tcx>, impl_def_id: DefId, impl_trait_ref: TraitRef<'tcx>) { + debug!("TraitDef::record_impl for {}, from {}", + self.repr(tcx), impl_trait_ref.repr(tcx)); + // We don't want to borrow_mut after we already populated all impls, // so check if an impl is present with an immutable borrow first. - if let Some(sty) = fast_reject::simplify_type(tcx, impl_trait_ref.self_ty(), false) { if let Some(is) = self.nonblanket_impls.borrow().get(&sty) { @@ -6336,10 +6338,10 @@ pub fn populate_implementations_for_primitive_if_necessary(tcx: &ctxt, tcx.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id); } -/// Populates the type context with all the implementations for the given type -/// if necessary. -pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt, - type_id: ast::DefId) { +/// Populates the type context with all the inherent implementations for +/// the given type if necessary. +pub fn populate_inherent_implementations_for_type_if_necessary(tcx: &ctxt, + type_id: ast::DefId) { if type_id.krate == LOCAL_CRATE { return } @@ -6348,37 +6350,15 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt, return } - debug!("populate_implementations_for_type_if_necessary: searching for {:?}", type_id); + debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}", type_id); let mut inherent_impls = Vec::new(); - csearch::each_implementation_for_type(&tcx.sess.cstore, type_id, |impl_def_id| { - let impl_items = csearch::get_impl_items(&tcx.sess.cstore, impl_def_id); - - // Record the implementation, if needed - if let Some(trait_ref) = csearch::get_impl_trait(tcx, impl_def_id) { - let trait_def = lookup_trait_def(tcx, trait_ref.def_id); - trait_def.record_impl(tcx, impl_def_id, trait_ref); - } else { - inherent_impls.push(impl_def_id); - } - - // For any methods that use a default implementation, add them to - // the map. This is a bit unfortunate. - for impl_item_def_id in &impl_items { - let method_def_id = impl_item_def_id.def_id(); - match impl_or_trait_item(tcx, method_def_id) { - MethodTraitItem(method) => { - if let Some(source) = method.provided_source { - tcx.provided_method_sources - .borrow_mut() - .insert(method_def_id, source); - } - } - _ => {} - } - } + csearch::each_inherent_implementation_for_type(&tcx.sess.cstore, type_id, |impl_def_id| { + // Record the implementation. + inherent_impls.push(impl_def_id); // Store the implementation info. + let impl_items = csearch::get_impl_items(&tcx.sess.cstore, impl_def_id); tcx.impl_items.borrow_mut().insert(impl_def_id, impl_items); }); @@ -6388,18 +6368,18 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt, /// Populates the type context with all the implementations for the given /// trait if necessary. -pub fn populate_implementations_for_trait_if_necessary( - tcx: &ctxt, - trait_id: ast::DefId) { +pub fn populate_implementations_for_trait_if_necessary(tcx: &ctxt, trait_id: ast::DefId) { if trait_id.krate == LOCAL_CRATE { return } let def = lookup_trait_def(tcx, trait_id); if def.flags.get().intersects(TraitFlags::IMPLS_VALID) { - return + return; } + debug!("populate_implementations_for_trait_if_necessary: searching for {}", def.repr(tcx)); + if csearch::is_defaulted_trait(&tcx.sess.cstore, trait_id) { record_trait_has_default_impl(tcx, trait_id); } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index c94fa03702681..6171df218bb60 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -371,7 +371,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: ast::DefId) { // Read the inherent implementation candidates for this type from the // metadata if necessary. - ty::populate_implementations_for_type_if_necessary(self.tcx(), def_id); + ty::populate_inherent_implementations_for_type_if_necessary(self.tcx(), def_id); if let Some(impl_infos) = self.tcx().inherent_impls.borrow().get(&def_id) { for &impl_def_id in &***impl_infos { diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 05b74a5cc226b..4dc1596b1ff7c 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -16,13 +16,10 @@ // mappings. That mapping code resides here. -use metadata::csearch::{each_impl, get_impl_trait}; -use metadata::csearch; use middle::subst::{self, Subst}; use middle::ty::RegionEscape; use middle::ty::{ImplContainer, ImplOrTraitItemId, ConstTraitItemId}; -use middle::ty::{MethodTraitItemId, TypeTraitItemId}; -use middle::ty::{ParameterEnvironment, lookup_item_type}; +use middle::ty::{MethodTraitItemId, TypeTraitItemId, ParameterEnvironment}; use middle::ty::{Ty, ty_bool, ty_char, ty_enum, ty_err}; use middle::ty::{ty_param, TypeScheme, ty_ptr}; use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup}; @@ -33,7 +30,6 @@ use middle::ty; use CrateCtxt; use middle::infer::InferCtxt; use middle::infer::new_infer_ctxt; -use std::collections::HashSet; use std::cell::RefCell; use std::rc::Rc; use syntax::ast::{Crate, DefId}; @@ -130,11 +126,6 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { Rc::new((*v.borrow()).clone())); } - // Bring in external crates. It's fine for this to happen after the - // coherence checks, because we ensure by construction that no errors - // can happen at link time. - self.add_external_crates(); - // Populate the table of destructors. It might seem a bit strange to // do this here, but it's actually the most convenient place, since // the coherence tables contain the trait -> type mappings. @@ -267,11 +258,6 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { trait_def.record_impl(self.crate_context.tcx, impl_def_id, impl_trait_ref); } - fn get_self_type_for_implementation(&self, impl_did: DefId) - -> TypeScheme<'tcx> { - self.crate_context.tcx.tcache.borrow().get(&impl_did).unwrap().clone() - } - // Converts an implementation in the AST to a vector of items. fn create_impl_from_item(&self, item: &Item) -> Vec { match item.node { @@ -313,66 +299,6 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } } - // External crate handling - - fn add_external_impl(&self, - impls_seen: &mut HashSet, - impl_def_id: DefId) { - let tcx = self.crate_context.tcx; - let impl_items = csearch::get_impl_items(&tcx.sess.cstore, - impl_def_id); - - // Make sure we don't visit the same implementation multiple times. - if !impls_seen.insert(impl_def_id) { - // Skip this one. - return - } - // Good. Continue. - - let _ = lookup_item_type(tcx, impl_def_id); - let associated_traits = get_impl_trait(tcx, impl_def_id); - - // Do a sanity check. - assert!(associated_traits.is_some()); - - // Record all the trait items. - if let Some(trait_ref) = associated_traits { - self.add_trait_impl(trait_ref, impl_def_id); - } - - // For any methods that use a default implementation, add them to - // the map. This is a bit unfortunate. - for item_def_id in &impl_items { - let impl_item = ty::impl_or_trait_item(tcx, item_def_id.def_id()); - match impl_item { - ty::MethodTraitItem(ref method) => { - if let Some(source) = method.provided_source { - tcx.provided_method_sources - .borrow_mut() - .insert(item_def_id.def_id(), source); - } - } - _ => {} - } - } - - tcx.impl_items.borrow_mut().insert(impl_def_id, impl_items); - } - - // Adds implementations and traits from external crates to the coherence - // info. - fn add_external_crates(&self) { - let mut impls_seen = HashSet::new(); - - let crate_store = &self.crate_context.tcx.sess.cstore; - crate_store.iter_crate_data(|crate_number, _crate_metadata| { - each_impl(crate_store, crate_number, |def_id| { - assert_eq!(crate_number, def_id.krate); - self.add_external_impl(&mut impls_seen, def_id) - }) - }) - } - // // Destructors // @@ -395,7 +321,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } let method_def_id = items[0]; - let self_type = self.get_self_type_for_implementation(impl_did); + let self_type = ty::lookup_item_type(tcx, impl_did); match self_type.ty.sty { ty::ty_enum(type_def_id, _) | ty::ty_struct(type_def_id, _) | @@ -451,7 +377,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { return } - let self_type = self.get_self_type_for_implementation(impl_did); + let self_type = ty::lookup_item_type(tcx, impl_did); debug!("check_implementations_of_copy: self_type={} (bound)", self_type.repr(tcx)); diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index 46cce54301168..e9c69c84630ef 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -48,14 +48,9 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> { // check_for_overlapping_impls_of_trait() check, since that // check can populate this table further with impls from other // crates. - let trait_defs : Vec<&ty::TraitDef> = { - let d = self.tcx.trait_defs.borrow(); - d.values().map(|&v|v).collect() - }; + let trait_defs: Vec<_> = self.tcx.trait_defs.borrow().values().cloned().collect(); for trait_def in trait_defs { - // FIXME -- it seems like this method actually pushes - // duplicate impls onto the list ty::populate_implementations_for_trait_if_necessary( self.tcx, trait_def.trait_ref.def_id); diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 0d59577a6d802..3ce8835b1a8de 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -221,7 +221,7 @@ fn build_type(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEn pub fn build_impls(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> Vec { - ty::populate_implementations_for_type_if_necessary(tcx, did); + ty::populate_inherent_implementations_for_type_if_necessary(tcx, did); let mut impls = Vec::new(); match tcx.inherent_impls.borrow().get(&did) {