rustc_metadata: Do not encode unnecessary module children
This commit is contained in:
parent
52ca603da7
commit
233fa659f4
@ -14,6 +14,8 @@
|
|||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(extend_one)]
|
#![feature(extend_one)]
|
||||||
|
#![feature(generator_trait)]
|
||||||
|
#![feature(generators)]
|
||||||
#![feature(let_else)]
|
#![feature(let_else)]
|
||||||
#![feature(hash_raw_entry)]
|
#![feature(hash_raw_entry)]
|
||||||
#![feature(maybe_uninit_uninit_array)]
|
#![feature(maybe_uninit_uninit_array)]
|
||||||
@ -113,6 +115,9 @@ pub mod unhash;
|
|||||||
pub use ena::undo_log;
|
pub use ena::undo_log;
|
||||||
pub use ena::unify;
|
pub use ena::unify;
|
||||||
|
|
||||||
|
use std::ops::{Generator, GeneratorState};
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
pub struct OnDrop<F: Fn()>(pub F);
|
pub struct OnDrop<F: Fn()>(pub F);
|
||||||
|
|
||||||
impl<F: Fn()> OnDrop<F> {
|
impl<F: Fn()> OnDrop<F> {
|
||||||
@ -131,6 +136,26 @@ impl<F: Fn()> Drop for OnDrop<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct IterFromGenerator<G>(G);
|
||||||
|
|
||||||
|
impl<G: Generator<Return = ()> + Unpin> Iterator for IterFromGenerator<G> {
|
||||||
|
type Item = G::Yield;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
match Pin::new(&mut self.0).resume(()) {
|
||||||
|
GeneratorState::Yielded(n) => Some(n),
|
||||||
|
GeneratorState::Complete(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An adapter for turning a generator closure into an iterator, similar to `iter::from_fn`.
|
||||||
|
pub fn iter_from_generator<G: Generator<Return = ()> + Unpin>(
|
||||||
|
generator: G,
|
||||||
|
) -> impl Iterator<Item = G::Yield> {
|
||||||
|
IterFromGenerator(generator)
|
||||||
|
}
|
||||||
|
|
||||||
// See comments in src/librustc_middle/lib.rs
|
// See comments in src/librustc_middle/lib.rs
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn __noop_fix_for_27438() {}
|
pub fn __noop_fix_for_27438() {}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(drain_filter)]
|
#![feature(drain_filter)]
|
||||||
|
#![feature(generators)]
|
||||||
#![feature(let_else)]
|
#![feature(let_else)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
|
@ -1089,63 +1089,32 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
// Iterate over all children.
|
// Iterate over all children.
|
||||||
if let Some(children) = self.root.tables.children.get(self, id) {
|
if let Some(children) = self.root.tables.children.get(self, id) {
|
||||||
for child_index in children.decode((self, sess)) {
|
for child_index in children.decode((self, sess)) {
|
||||||
if let Some(ident) = self.opt_item_ident(child_index, sess) {
|
let ident = self.item_ident(child_index, sess);
|
||||||
let kind = self.def_kind(child_index);
|
let kind = self.def_kind(child_index);
|
||||||
let def_id = self.local_def_id(child_index);
|
let def_id = self.local_def_id(child_index);
|
||||||
let res = Res::Def(kind, def_id);
|
let res = Res::Def(kind, def_id);
|
||||||
let vis = self.get_visibility(child_index);
|
let vis = self.get_visibility(child_index);
|
||||||
let span = self.get_span(child_index, sess);
|
let span = self.get_span(child_index, sess);
|
||||||
let macro_rules = match kind {
|
let macro_rules = match kind {
|
||||||
DefKind::Macro(..) => match self.kind(child_index) {
|
DefKind::Macro(..) => match self.kind(child_index) {
|
||||||
EntryKind::MacroDef(_, macro_rules) => macro_rules,
|
EntryKind::MacroDef(_, macro_rules) => macro_rules,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
callback(ModChild { ident, res, vis, span, macro_rules });
|
callback(ModChild { ident, res, vis, span, macro_rules });
|
||||||
|
|
||||||
// For non-re-export structs and variants add their constructors to children.
|
// For non-re-export structs and variants add their constructors to children.
|
||||||
// Re-export lists automatically contain constructors when necessary.
|
// Re-export lists automatically contain constructors when necessary.
|
||||||
match kind {
|
match kind {
|
||||||
DefKind::Struct => {
|
DefKind::Struct => {
|
||||||
if let Some((ctor_def_id, ctor_kind)) =
|
if let Some((ctor_def_id, ctor_kind)) =
|
||||||
self.get_ctor_def_id_and_kind(child_index)
|
self.get_ctor_def_id_and_kind(child_index)
|
||||||
{
|
{
|
||||||
let ctor_res =
|
|
||||||
Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
|
|
||||||
let vis = self.get_visibility(ctor_def_id.index);
|
|
||||||
callback(ModChild {
|
|
||||||
ident,
|
|
||||||
res: ctor_res,
|
|
||||||
vis,
|
|
||||||
span,
|
|
||||||
macro_rules: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DefKind::Variant => {
|
|
||||||
// Braced variants, unlike structs, generate unusable names in
|
|
||||||
// value namespace, they are reserved for possible future use.
|
|
||||||
// It's ok to use the variant's id as a ctor id since an
|
|
||||||
// error will be reported on any use of such resolution anyway.
|
|
||||||
let (ctor_def_id, ctor_kind) = self
|
|
||||||
.get_ctor_def_id_and_kind(child_index)
|
|
||||||
.unwrap_or((def_id, CtorKind::Fictive));
|
|
||||||
let ctor_res =
|
let ctor_res =
|
||||||
Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id);
|
Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
|
||||||
let mut vis = self.get_visibility(ctor_def_id.index);
|
let vis = self.get_visibility(ctor_def_id.index);
|
||||||
if ctor_def_id == def_id && vis.is_public() {
|
|
||||||
// For non-exhaustive variants lower the constructor visibility to
|
|
||||||
// within the crate. We only need this for fictive constructors,
|
|
||||||
// for other constructors correct visibilities
|
|
||||||
// were already encoded in metadata.
|
|
||||||
let mut attrs = self.get_item_attrs(def_id.index, sess);
|
|
||||||
if attrs.any(|item| item.has_name(sym::non_exhaustive)) {
|
|
||||||
let crate_def_id = self.local_def_id(CRATE_DEF_INDEX);
|
|
||||||
vis = ty::Visibility::Restricted(crate_def_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
callback(ModChild {
|
callback(ModChild {
|
||||||
ident,
|
ident,
|
||||||
res: ctor_res,
|
res: ctor_res,
|
||||||
@ -1154,8 +1123,32 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
macro_rules: false,
|
macro_rules: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
DefKind::Variant => {
|
||||||
|
// Braced variants, unlike structs, generate unusable names in
|
||||||
|
// value namespace, they are reserved for possible future use.
|
||||||
|
// It's ok to use the variant's id as a ctor id since an
|
||||||
|
// error will be reported on any use of such resolution anyway.
|
||||||
|
let (ctor_def_id, ctor_kind) = self
|
||||||
|
.get_ctor_def_id_and_kind(child_index)
|
||||||
|
.unwrap_or((def_id, CtorKind::Fictive));
|
||||||
|
let ctor_res =
|
||||||
|
Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id);
|
||||||
|
let mut vis = self.get_visibility(ctor_def_id.index);
|
||||||
|
if ctor_def_id == def_id && vis.is_public() {
|
||||||
|
// For non-exhaustive variants lower the constructor visibility to
|
||||||
|
// within the crate. We only need this for fictive constructors,
|
||||||
|
// for other constructors correct visibilities
|
||||||
|
// were already encoded in metadata.
|
||||||
|
let mut attrs = self.get_item_attrs(def_id.index, sess);
|
||||||
|
if attrs.any(|item| item.has_name(sym::non_exhaustive)) {
|
||||||
|
let crate_def_id = self.local_def_id(CRATE_DEF_INDEX);
|
||||||
|
vis = ty::Visibility::Restricted(crate_def_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback(ModChild { ident, res: ctor_res, vis, span, macro_rules: false });
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ use crate::rmeta::*;
|
|||||||
|
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
||||||
|
use rustc_data_structures::iter_from_generator;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator};
|
use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
@ -1107,21 +1108,26 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||||||
// Encode this here because we don't do it in encode_def_ids.
|
// Encode this here because we don't do it in encode_def_ids.
|
||||||
record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id));
|
record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id));
|
||||||
} else {
|
} else {
|
||||||
let direct_children = md.item_ids.iter().map(|item_id| item_id.def_id.local_def_index);
|
record!(self.tables.children[def_id] <- iter_from_generator(|| {
|
||||||
// Foreign items are planted into their parent modules from name resolution point of view.
|
for item_id in md.item_ids {
|
||||||
let tcx = self.tcx;
|
match tcx.hir().item(*item_id).kind {
|
||||||
let foreign_item_children = md
|
// Foreign items are planted into their parent modules
|
||||||
.item_ids
|
// from name resolution point of view.
|
||||||
.iter()
|
hir::ItemKind::ForeignMod { items, .. } => {
|
||||||
.filter_map(|item_id| match tcx.hir().item(*item_id).kind {
|
for foreign_item in items {
|
||||||
hir::ItemKind::ForeignMod { items, .. } => {
|
yield foreign_item.id.def_id.local_def_index;
|
||||||
Some(items.iter().map(|fi_ref| fi_ref.id.def_id.local_def_index))
|
}
|
||||||
|
}
|
||||||
|
// Only encode named non-reexport children, reexports are encoded
|
||||||
|
// separately and unnamed items are not used by name resolution.
|
||||||
|
hir::ItemKind::ExternCrate(..) => continue,
|
||||||
|
_ if tcx.def_key(item_id.def_id.to_def_id()).get_opt_name().is_some() => {
|
||||||
|
yield item_id.def_id.local_def_index;
|
||||||
|
}
|
||||||
|
_ => continue,
|
||||||
}
|
}
|
||||||
_ => None,
|
}
|
||||||
})
|
}));
|
||||||
.flatten();
|
|
||||||
|
|
||||||
record!(self.tables.children[def_id] <- direct_children.chain(foreign_item_children));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user