提交 592165fb 编写于 作者: E Eduard Burtescu

Fix ty::populate_implementations_for_trait_if_necessary to load the trait's...

Fix ty::populate_implementations_for_trait_if_necessary to load the trait's impls from all the crates.
上级 aeb92bab
...@@ -189,6 +189,7 @@ pub enum astencode_tag { // Reserves 0x50 -- 0x6f ...@@ -189,6 +189,7 @@ pub enum astencode_tag { // Reserves 0x50 -- 0x6f
pub const tag_impls: usize = 0x109; // top-level only pub const tag_impls: usize = 0x109; // top-level only
pub const tag_impls_impl: usize = 0x7f; 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_inherent_impl: usize = 0x80;
pub const tag_items_data_item_extension_impl: usize = 0x81; pub const tag_items_data_item_extension_impl: usize = 0x81;
......
...@@ -324,11 +324,12 @@ pub fn each_inherent_implementation_for_type<F>(cstore: &cstore::CStore, ...@@ -324,11 +324,12 @@ pub fn each_inherent_implementation_for_type<F>(cstore: &cstore::CStore,
pub fn each_implementation_for_trait<F>(cstore: &cstore::CStore, pub fn each_implementation_for_trait<F>(cstore: &cstore::CStore,
def_id: ast::DefId, def_id: ast::DefId,
callback: F) where mut callback: F) where
F: FnMut(ast::DefId), F: FnMut(ast::DefId),
{ {
let cdata = cstore.get_crate_data(def_id.krate); cstore.iter_crate_data(|_, cdata| {
decoder::each_implementation_for_trait(&*cdata, def_id.node, callback) decoder::each_implementation_for_trait(cdata, def_id, &mut callback)
})
} }
/// If the given def ID describes an item belonging to a trait (either a /// If the given def ID describes an item belonging to a trait (either a
......
...@@ -1328,6 +1328,22 @@ pub fn translate_def_id(cdata: Cmd, did: ast::DefId) -> ast::DefId { ...@@ -1328,6 +1328,22 @@ pub fn translate_def_id(cdata: Cmd, did: ast::DefId) -> ast::DefId {
} }
} }
// 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<ast::DefId> {
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_impl<F>(cdata: Cmd, mut callback: F) where pub fn each_impl<F>(cdata: Cmd, mut callback: F) where
F: FnMut(ast::DefId), F: FnMut(ast::DefId),
{ {
...@@ -1355,19 +1371,35 @@ pub fn each_inherent_implementation_for_type<F>(cdata: Cmd, ...@@ -1355,19 +1371,35 @@ pub fn each_inherent_implementation_for_type<F>(cdata: Cmd,
} }
pub fn each_implementation_for_trait<F>(cdata: Cmd, pub fn each_implementation_for_trait<F>(cdata: Cmd,
id: ast::NodeId, def_id: ast::DefId,
mut callback: F) where mut callback: F) where
F: FnMut(ast::DefId), 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, // Do a reverse lookup beforehand to avoid touching the crate_num
tag_items_data_item_extension_impl, // hash map in the loop below.
|impl_doc| { if let Some(crate_local_did) = reverse_translate_def_id(cdata, def_id) {
let implementation_def_id = item_def_id(impl_doc, cdata); let def_id_u64 = def_to_u64(crate_local_did);
callback(implementation_def_id);
true 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) pub fn get_trait_of_item(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
......
...@@ -1895,6 +1895,7 @@ fn visit_item(&mut self, item: &ast::Item) { ...@@ -1895,6 +1895,7 @@ fn visit_item(&mut self, item: &ast::Item) {
def_id.krate != ast::LOCAL_CRATE { def_id.krate != ast::LOCAL_CRATE {
self.rbml_w.start_tag(tag_impls_impl); self.rbml_w.start_tag(tag_impls_impl);
encode_def_id(self.rbml_w, local_def(item.id)); 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(); self.rbml_w.end_tag();
} }
} }
......
...@@ -2564,9 +2564,11 @@ pub fn record_impl(&self, ...@@ -2564,9 +2564,11 @@ pub fn record_impl(&self,
tcx: &ctxt<'tcx>, tcx: &ctxt<'tcx>,
impl_def_id: DefId, impl_def_id: DefId,
impl_trait_ref: TraitRef<'tcx>) { 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, // 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. // so check if an impl is present with an immutable borrow first.
if let Some(sty) = fast_reject::simplify_type(tcx, if let Some(sty) = fast_reject::simplify_type(tcx,
impl_trait_ref.self_ty(), false) { impl_trait_ref.self_ty(), false) {
if let Some(is) = self.nonblanket_impls.borrow().get(&sty) { if let Some(is) = self.nonblanket_impls.borrow().get(&sty) {
...@@ -6366,18 +6368,18 @@ pub fn populate_inherent_implementations_for_type_if_necessary(tcx: &ctxt, ...@@ -6366,18 +6368,18 @@ pub fn populate_inherent_implementations_for_type_if_necessary(tcx: &ctxt,
/// Populates the type context with all the implementations for the given /// Populates the type context with all the implementations for the given
/// trait if necessary. /// trait if necessary.
pub fn populate_implementations_for_trait_if_necessary( pub fn populate_implementations_for_trait_if_necessary(tcx: &ctxt, trait_id: ast::DefId) {
tcx: &ctxt,
trait_id: ast::DefId) {
if trait_id.krate == LOCAL_CRATE { if trait_id.krate == LOCAL_CRATE {
return return
} }
let def = lookup_trait_def(tcx, trait_id); let def = lookup_trait_def(tcx, trait_id);
if def.flags.get().intersects(TraitFlags::IMPLS_VALID) { 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) { if csearch::is_defaulted_trait(&tcx.sess.cstore, trait_id) {
record_trait_has_default_impl(tcx, trait_id); record_trait_has_default_impl(tcx, trait_id);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册