rustc_metadata: Encode list of all crate's traits into metadata
This commit is contained in:
parent
e91ad5fc62
commit
90e371027e
12 changed files with 96 additions and 113 deletions
|
@ -1406,6 +1406,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||
)
|
||||
}
|
||||
|
||||
fn get_traits(&'a self) -> impl Iterator<Item = DefId> + 'a {
|
||||
self.root.traits.decode(self).map(|index| self.local_def_id(index))
|
||||
}
|
||||
|
||||
fn get_implementations_for_trait(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
|
|
@ -4,9 +4,11 @@ use crate::native_libs;
|
|||
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::stable_map::FxHashMap;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, DefKind};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
|
||||
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
||||
use rustc_middle::hir::exports::Export;
|
||||
use rustc_middle::middle::exported_symbols::ExportedSymbol;
|
||||
use rustc_middle::middle::stability::DeprecationEntry;
|
||||
|
@ -195,6 +197,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
|||
|
||||
extra_filename => { cdata.root.extra_filename.clone() }
|
||||
|
||||
traits_in_crate => { tcx.arena.alloc_from_iter(cdata.get_traits()) }
|
||||
|
||||
implementations_of_trait => {
|
||||
cdata.get_implementations_for_trait(tcx, Some(other))
|
||||
}
|
||||
|
@ -285,6 +289,28 @@ pub fn provide(providers: &mut Providers) {
|
|||
foreign_modules::collect(tcx).into_iter().map(|m| (m.def_id, m)).collect();
|
||||
Lrc::new(modules)
|
||||
},
|
||||
traits_in_crate: |tcx, cnum| {
|
||||
assert_eq!(cnum, LOCAL_CRATE);
|
||||
|
||||
#[derive(Default)]
|
||||
struct TraitsVisitor {
|
||||
traits: Vec<DefId>,
|
||||
}
|
||||
impl ItemLikeVisitor<'_> for TraitsVisitor {
|
||||
fn visit_item(&mut self, item: &hir::Item<'_>) {
|
||||
if let hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) = item.kind {
|
||||
self.traits.push(item.def_id.to_def_id());
|
||||
}
|
||||
}
|
||||
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
|
||||
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
|
||||
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
|
||||
}
|
||||
|
||||
let mut visitor = TraitsVisitor::default();
|
||||
tcx.hir().visit_all_item_likes(&mut visitor);
|
||||
tcx.arena.alloc_slice(&visitor.traits)
|
||||
},
|
||||
|
||||
// Returns a map from a sufficiently visible external item (i.e., an
|
||||
// external item that is visible from at least one local module) to a
|
||||
|
|
|
@ -614,8 +614,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
|
||||
// Encode the def IDs of impls, for coherence checking.
|
||||
i = self.position();
|
||||
let impls = self.encode_impls();
|
||||
let impl_bytes = self.position() - i;
|
||||
let (traits, impls) = self.encode_traits_and_impls();
|
||||
let traits_and_impls_bytes = self.position() - i;
|
||||
|
||||
let tcx = self.tcx;
|
||||
|
||||
|
@ -727,6 +727,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
foreign_modules,
|
||||
source_map,
|
||||
impls,
|
||||
traits,
|
||||
exported_symbols,
|
||||
interpret_alloc_index,
|
||||
tables,
|
||||
|
@ -753,7 +754,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
eprintln!(" diagnostic item bytes: {}", diagnostic_item_bytes);
|
||||
eprintln!(" native bytes: {}", native_lib_bytes);
|
||||
eprintln!(" source_map bytes: {}", source_map_bytes);
|
||||
eprintln!(" impl bytes: {}", impl_bytes);
|
||||
eprintln!("traits and impls bytes: {}", traits_and_impls_bytes);
|
||||
eprintln!(" exp. symbols bytes: {}", exported_symbols_bytes);
|
||||
eprintln!(" def-path table bytes: {}", def_path_table_bytes);
|
||||
eprintln!(" def-path hashes bytes: {}", def_path_hash_map_bytes);
|
||||
|
@ -1784,16 +1785,23 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
/// Encodes an index, mapping each trait to its (local) implementations.
|
||||
fn encode_impls(&mut self) -> Lazy<[TraitImpls]> {
|
||||
empty_proc_macro!(self);
|
||||
debug!("EncodeContext::encode_impls()");
|
||||
fn encode_traits_and_impls(&mut self) -> (Lazy<[DefIndex]>, Lazy<[TraitImpls]>) {
|
||||
if self.is_proc_macro {
|
||||
return (Lazy::empty(), Lazy::empty());
|
||||
}
|
||||
debug!("EncodeContext::encode_traits_and_impls()");
|
||||
let tcx = self.tcx;
|
||||
let mut visitor = ImplVisitor { tcx, impls: FxHashMap::default() };
|
||||
let mut visitor =
|
||||
TraitsAndImplsVisitor { tcx, impls: FxHashMap::default(), traits: Default::default() };
|
||||
tcx.hir().visit_all_item_likes(&mut visitor);
|
||||
|
||||
let mut all_traits = visitor.traits;
|
||||
let mut all_impls: Vec<_> = visitor.impls.into_iter().collect();
|
||||
|
||||
// Bring everything into deterministic order for hashing
|
||||
all_traits.sort_by_cached_key(|&local_def_index| {
|
||||
tcx.hir().def_path_hash(LocalDefId { local_def_index })
|
||||
});
|
||||
all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id));
|
||||
|
||||
let all_impls: Vec<_> = all_impls
|
||||
|
@ -1811,7 +1819,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
})
|
||||
.collect();
|
||||
|
||||
self.lazy(&all_impls)
|
||||
(self.lazy(&all_traits), self.lazy(&all_impls))
|
||||
}
|
||||
|
||||
// Encodes all symbols exported from this crate into the metadata.
|
||||
|
@ -2033,27 +2041,34 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
struct ImplVisitor<'tcx> {
|
||||
struct TraitsAndImplsVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
traits: Vec<DefIndex>,
|
||||
impls: FxHashMap<DefId, Vec<(DefIndex, Option<fast_reject::SimplifiedType>)>>,
|
||||
}
|
||||
|
||||
impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> {
|
||||
impl<'tcx, 'v> ItemLikeVisitor<'v> for TraitsAndImplsVisitor<'tcx> {
|
||||
fn visit_item(&mut self, item: &hir::Item<'_>) {
|
||||
if let hir::ItemKind::Impl { .. } = item.kind {
|
||||
if let Some(trait_ref) = self.tcx.impl_trait_ref(item.def_id.to_def_id()) {
|
||||
let simplified_self_ty = fast_reject::simplify_type(
|
||||
self.tcx,
|
||||
trait_ref.self_ty(),
|
||||
SimplifyParams::No,
|
||||
StripReferences::No,
|
||||
);
|
||||
|
||||
self.impls
|
||||
.entry(trait_ref.def_id)
|
||||
.or_default()
|
||||
.push((item.def_id.local_def_index, simplified_self_ty));
|
||||
match item.kind {
|
||||
hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) => {
|
||||
self.traits.push(item.def_id.local_def_index);
|
||||
}
|
||||
hir::ItemKind::Impl(..) => {
|
||||
if let Some(trait_ref) = self.tcx.impl_trait_ref(item.def_id.to_def_id()) {
|
||||
let simplified_self_ty = fast_reject::simplify_type(
|
||||
self.tcx,
|
||||
trait_ref.self_ty(),
|
||||
SimplifyParams::No,
|
||||
StripReferences::No,
|
||||
);
|
||||
|
||||
self.impls
|
||||
.entry(trait_ref.def_id)
|
||||
.or_default()
|
||||
.push((item.def_id.local_def_index, simplified_self_ty));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -222,6 +222,7 @@ crate struct CrateRoot<'tcx> {
|
|||
diagnostic_items: Lazy<[(Symbol, DefIndex)]>,
|
||||
native_libraries: Lazy<[NativeLib]>,
|
||||
foreign_modules: Lazy<[ForeignModule]>,
|
||||
traits: Lazy<[DefIndex]>,
|
||||
impls: Lazy<[TraitImpls]>,
|
||||
interpret_alloc_index: Lazy<[u32]>,
|
||||
proc_macro_data: Option<ProcMacroData>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue