rustc_metadata: Switch all decoder methods from vectors to iterators

Also remove unnecessary `is_proc_macro_crate` checks from decoder
This commit is contained in:
Vadim Petrochenkov 2021-12-24 14:57:21 +08:00
parent a0984b4e4c
commit 4549b13571
5 changed files with 66 additions and 87 deletions

View file

@ -1033,45 +1033,33 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
/// Iterates over all the stability attributes in the given crate. /// Iterates over all the stability attributes in the given crate.
fn get_lib_features(self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Option<Symbol>)] { fn get_lib_features(self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Option<Symbol>)] {
// FIXME: For a proc macro crate, not sure whether we should return the "host"
// features or an empty Vec. Both don't cause ICEs.
tcx.arena.alloc_from_iter(self.root.lib_features.decode(self)) tcx.arena.alloc_from_iter(self.root.lib_features.decode(self))
} }
/// Iterates over the language items in the given crate. /// Iterates over the language items in the given crate.
fn get_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] { fn get_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] {
if self.root.is_proc_macro_crate() { tcx.arena.alloc_from_iter(
// Proc macro crates do not export any lang-items to the target. self.root
&[] .lang_items
} else { .decode(self)
tcx.arena.alloc_from_iter( .map(|(def_index, index)| (self.local_def_id(def_index), index)),
self.root )
.lang_items
.decode(self)
.map(|(def_index, index)| (self.local_def_id(def_index), index)),
)
}
} }
/// Iterates over the diagnostic items in the given crate. /// Iterates over the diagnostic items in the given crate.
fn get_diagnostic_items(self) -> DiagnosticItems { fn get_diagnostic_items(self) -> DiagnosticItems {
if self.root.is_proc_macro_crate() { let mut id_to_name = FxHashMap::default();
// Proc macro crates do not export any diagnostic-items to the target. let name_to_id = self
Default::default() .root
} else { .diagnostic_items
let mut id_to_name = FxHashMap::default(); .decode(self)
let name_to_id = self .map(|(name, def_index)| {
.root let id = self.local_def_id(def_index);
.diagnostic_items id_to_name.insert(id, name);
.decode(self) (name, id)
.map(|(name, def_index)| { })
let id = self.local_def_id(def_index); .collect();
id_to_name.insert(id, name); DiagnosticItems { id_to_name, name_to_id }
(name, id)
})
.collect();
DiagnosticItems { id_to_name, name_to_id }
}
} }
/// Iterates over all named children of the given module, /// Iterates over all named children of the given module,
@ -1346,26 +1334,28 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.decode((self, sess)) .decode((self, sess))
} }
fn get_struct_field_names(self, id: DefIndex, sess: &Session) -> Vec<Spanned<Symbol>> { fn get_struct_field_names(
self,
id: DefIndex,
sess: &'a Session,
) -> impl Iterator<Item = Spanned<Symbol>> + 'a {
self.root self.root
.tables .tables
.children .children
.get(self, id) .get(self, id)
.unwrap_or_else(Lazy::empty) .unwrap_or_else(Lazy::empty)
.decode(self) .decode(self)
.map(|index| respan(self.get_span(index, sess), self.item_ident(index, sess).name)) .map(move |index| respan(self.get_span(index, sess), self.item_ident(index, sess).name))
.collect()
} }
fn get_struct_field_visibilities(self, id: DefIndex) -> Vec<Visibility> { fn get_struct_field_visibilities(self, id: DefIndex) -> impl Iterator<Item = Visibility> + 'a {
self.root self.root
.tables .tables
.children .children
.get(self, id) .get(self, id)
.unwrap_or_else(Lazy::empty) .unwrap_or_else(Lazy::empty)
.decode(self) .decode(self)
.map(|field_index| self.get_visibility(field_index)) .map(move |field_index| self.get_visibility(field_index))
.collect()
} }
fn get_inherent_implementations_for_type( fn get_inherent_implementations_for_type(
@ -1401,8 +1391,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
trait_def_id: DefId, trait_def_id: DefId,
) -> &'tcx [(DefId, Option<SimplifiedType>)] { ) -> &'tcx [(DefId, Option<SimplifiedType>)] {
if self.root.is_proc_macro_crate() { if self.trait_impls.is_empty() {
// proc-macro crates export no trait impls.
return &[]; return &[];
} }
@ -1437,13 +1426,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}) })
} }
fn get_native_libraries(self, sess: &Session) -> Vec<NativeLib> { fn get_native_libraries(self, sess: &'a Session) -> impl Iterator<Item = NativeLib> + 'a {
if self.root.is_proc_macro_crate() { self.root.native_libraries.decode((self, sess))
// Proc macro crates do not have any *target* native libraries.
vec![]
} else {
self.root.native_libraries.decode((self, sess)).collect()
}
} }
fn get_proc_macro_quoted_span(self, index: usize, sess: &Session) -> Span { fn get_proc_macro_quoted_span(self, index: usize, sess: &Session) -> Span {
@ -1455,15 +1439,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.decode((self, sess)) .decode((self, sess))
} }
fn get_foreign_modules(self, tcx: TyCtxt<'tcx>) -> Lrc<FxHashMap<DefId, ForeignModule>> { fn get_foreign_modules(self, sess: &'a Session) -> impl Iterator<Item = ForeignModule> + '_ {
if self.root.is_proc_macro_crate() { self.root.foreign_modules.decode((self, sess))
// Proc macro crates do not have any *target* foreign modules.
Lrc::new(FxHashMap::default())
} else {
let modules: FxHashMap<DefId, ForeignModule> =
self.root.foreign_modules.decode((self, tcx.sess)).map(|m| (m.def_id, m)).collect();
Lrc::new(modules)
}
} }
fn get_dylib_dependency_formats( fn get_dylib_dependency_formats(
@ -1479,12 +1456,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
} }
fn get_missing_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] { fn get_missing_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] {
if self.root.is_proc_macro_crate() { tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode(self))
// Proc macro crates do not depend on any target weak lang-items.
&[]
} else {
tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode(self))
}
} }
fn get_fn_param_names(self, tcx: TyCtxt<'tcx>, id: DefIndex) -> &'tcx [Ident] { fn get_fn_param_names(self, tcx: TyCtxt<'tcx>, id: DefIndex) -> &'tcx [Ident] {
@ -1500,13 +1472,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
self, self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportLevel)] { ) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportLevel)] {
if self.root.is_proc_macro_crate() { tcx.arena.alloc_from_iter(self.root.exported_symbols.decode((self, tcx)))
// If this crate is a custom derive crate, then we're not even going to
// link those in so we skip those crates.
&[]
} else {
tcx.arena.alloc_from_iter(self.root.exported_symbols.decode((self, tcx)))
}
} }
fn get_rendered_const(self, id: DefIndex) -> String { fn get_rendered_const(self, id: DefIndex) -> String {

View file

@ -179,8 +179,10 @@ provide! { <'tcx> tcx, def_id, other, cdata,
reachable_non_generics reachable_non_generics
} }
native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess)) } native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess).collect()) }
foreign_modules => { cdata.get_foreign_modules(tcx) } foreign_modules => {
Lrc::new(cdata.get_foreign_modules(tcx.sess).map(|m| (m.def_id, m)).collect())
}
crate_hash => { cdata.root.hash } crate_hash => { cdata.root.hash }
crate_host_hash => { cdata.host_hash } crate_host_hash => { cdata.host_hash }
crate_name => { cdata.root.name } crate_name => { cdata.root.name }
@ -371,11 +373,18 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
} }
impl CStore { impl CStore {
pub fn struct_field_names_untracked(&self, def: DefId, sess: &Session) -> Vec<Spanned<Symbol>> { pub fn struct_field_names_untracked<'a>(
&'a self,
def: DefId,
sess: &'a Session,
) -> impl Iterator<Item = Spanned<Symbol>> + 'a {
self.get_crate_data(def.krate).get_struct_field_names(def.index, sess) self.get_crate_data(def.krate).get_struct_field_names(def.index, sess)
} }
pub fn struct_field_visibilities_untracked(&self, def: DefId) -> Vec<Visibility> { pub fn struct_field_visibilities_untracked(
&self,
def: DefId,
) -> impl Iterator<Item = Visibility> + '_ {
self.get_crate_data(def.krate).get_struct_field_visibilities(def.index) self.get_crate_data(def.krate).get_struct_field_visibilities(def.index)
} }
@ -460,8 +469,12 @@ impl CStore {
self.get_crate_data(cnum).num_def_ids() self.get_crate_data(cnum).num_def_ids()
} }
pub fn item_attrs_untracked(&self, def_id: DefId, sess: &Session) -> Vec<ast::Attribute> { pub fn item_attrs_untracked<'a>(
self.get_crate_data(def_id.krate).get_item_attrs(def_id.index, sess).collect() &'a self,
def_id: DefId,
sess: &'a Session,
) -> impl Iterator<Item = ast::Attribute> + 'a {
self.get_crate_data(def_id.krate).get_item_attrs(def_id.index, sess)
} }
pub fn get_proc_macro_quoted_span_untracked( pub fn get_proc_macro_quoted_span_untracked(
@ -473,15 +486,15 @@ impl CStore {
self.get_crate_data(cnum).get_proc_macro_quoted_span(id, sess) self.get_crate_data(cnum).get_proc_macro_quoted_span(id, sess)
} }
pub fn traits_in_crate_untracked(&self, cnum: CrateNum) -> Vec<DefId> { pub fn traits_in_crate_untracked(&self, cnum: CrateNum) -> impl Iterator<Item = DefId> + '_ {
self.get_crate_data(cnum).get_traits().collect() self.get_crate_data(cnum).get_traits()
} }
pub fn trait_impls_in_crate_untracked( pub fn trait_impls_in_crate_untracked(
&self, &self,
cnum: CrateNum, cnum: CrateNum,
) -> Vec<(DefId, Option<SimplifiedType>)> { ) -> impl Iterator<Item = (DefId, Option<SimplifiedType>)> + '_ {
self.get_crate_data(cnum).get_trait_impls().collect() self.get_crate_data(cnum).get_trait_impls()
} }
} }

View file

@ -999,12 +999,14 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
let cstore = self.r.cstore(); let cstore = self.r.cstore();
match res { match res {
Res::Def(DefKind::Struct, def_id) => { Res::Def(DefKind::Struct, def_id) => {
let field_names = cstore.struct_field_names_untracked(def_id, self.r.session); let field_names =
cstore.struct_field_names_untracked(def_id, self.r.session).collect();
let ctor = cstore.ctor_def_id_and_kind_untracked(def_id); let ctor = cstore.ctor_def_id_and_kind_untracked(def_id);
if let Some((ctor_def_id, ctor_kind)) = ctor { if let Some((ctor_def_id, ctor_kind)) = ctor {
let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id); let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
let ctor_vis = cstore.visibility_untracked(ctor_def_id); let ctor_vis = cstore.visibility_untracked(ctor_def_id);
let field_visibilities = cstore.struct_field_visibilities_untracked(def_id); let field_visibilities =
cstore.struct_field_visibilities_untracked(def_id).collect();
self.r self.r
.struct_constructors .struct_constructors
.insert(def_id, (ctor_res, ctor_vis, field_visibilities)); .insert(def_id, (ctor_res, ctor_vis, field_visibilities));
@ -1012,7 +1014,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
self.insert_field_names(def_id, field_names); self.insert_field_names(def_id, field_names);
} }
Res::Def(DefKind::Union, def_id) => { Res::Def(DefKind::Union, def_id) => {
let field_names = cstore.struct_field_names_untracked(def_id, self.r.session); let field_names =
cstore.struct_field_names_untracked(def_id, self.r.session).collect();
self.insert_field_names(def_id, field_names); self.insert_field_names(def_id, field_names);
} }
Res::Def(DefKind::AssocFn, def_id) => { Res::Def(DefKind::AssocFn, def_id) => {

View file

@ -914,11 +914,8 @@ impl<'a> Resolver<'a> {
// a note about editions // a note about editions
let note = if let Some(did) = did { let note = if let Some(did) = did {
let requires_note = !did.is_local() let requires_note = !did.is_local()
&& this && this.cstore().item_attrs_untracked(did, this.session).any(
.cstore() |attr| {
.item_attrs_untracked(did, this.session)
.iter()
.any(|attr| {
if attr.has_name(sym::rustc_diagnostic_item) { if attr.has_name(sym::rustc_diagnostic_item) {
[sym::TryInto, sym::TryFrom, sym::FromIterator] [sym::TryInto, sym::TryFrom, sym::FromIterator]
.map(|x| Some(x)) .map(|x| Some(x))
@ -926,7 +923,8 @@ impl<'a> Resolver<'a> {
} else { } else {
false false
} }
}); },
);
requires_note.then(|| { requires_note.then(|| {
format!( format!(

View file

@ -3442,7 +3442,6 @@ impl<'a> Resolver<'a> {
let attr = self let attr = self
.cstore() .cstore()
.item_attrs_untracked(def_id, self.session) .item_attrs_untracked(def_id, self.session)
.into_iter()
.find(|a| a.has_name(sym::rustc_legacy_const_generics))?; .find(|a| a.has_name(sym::rustc_legacy_const_generics))?;
let mut ret = Vec::new(); let mut ret = Vec::new();
for meta in attr.meta_item_list()? { for meta in attr.meta_item_list()? {