about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-01-16 14:25:25 +0000
committerbors <bors@rust-lang.org>2022-01-16 14:25:25 +0000
commit48e89b00caa94829a5f07e0f1ecb33bf37431244 (patch)
treea928f002bc17f2c6a6bd1d512e01086aa257fc65
parent7be8693984d32d2f65ce9ded4f65b6b7340bddce (diff)
parent4549b135719aa81bbb0427087963c7af3e8f6bdc (diff)
Auto merge of #92245 - petrochenkov:cmrval, r=nagisa
rustc_metadata: Switch all decoder methods from vectors to iterators

To avoid allocations in some cases.

Also remove unnecessary `is_proc_macro_crate` checks from decoder, currently the general strategy is to shift all the work to the encoder and assume that all the encoded data is correct and can be decoded unconditionally in the decoder.
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs100
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs33
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs9
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs10
-rw-r--r--compiler/rustc_resolve/src/lib.rs1
5 files changed, 66 insertions, 87 deletions
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 85c0d28d5ea..39aa1844d69 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1033,45 +1033,33 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
 
     /// Iterates over all the stability attributes in the given crate.
     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))
     }
 
     /// Iterates over the language items in the given crate.
     fn get_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] {
-        if self.root.is_proc_macro_crate() {
-            // Proc macro crates do not export any lang-items to the target.
-            &[]
-        } else {
-            tcx.arena.alloc_from_iter(
-                self.root
-                    .lang_items
-                    .decode(self)
-                    .map(|(def_index, index)| (self.local_def_id(def_index), index)),
-            )
-        }
+        tcx.arena.alloc_from_iter(
+            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.
     fn get_diagnostic_items(self) -> DiagnosticItems {
-        if self.root.is_proc_macro_crate() {
-            // Proc macro crates do not export any diagnostic-items to the target.
-            Default::default()
-        } else {
-            let mut id_to_name = FxHashMap::default();
-            let name_to_id = self
-                .root
-                .diagnostic_items
-                .decode(self)
-                .map(|(name, def_index)| {
-                    let id = self.local_def_id(def_index);
-                    id_to_name.insert(id, name);
-                    (name, id)
-                })
-                .collect();
-            DiagnosticItems { id_to_name, name_to_id }
-        }
+        let mut id_to_name = FxHashMap::default();
+        let name_to_id = self
+            .root
+            .diagnostic_items
+            .decode(self)
+            .map(|(name, def_index)| {
+                let id = self.local_def_id(def_index);
+                id_to_name.insert(id, name);
+                (name, id)
+            })
+            .collect();
+        DiagnosticItems { id_to_name, name_to_id }
     }
 
     /// Iterates over all named children of the given module,
@@ -1346,26 +1334,28 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             .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
             .tables
             .children
             .get(self, id)
             .unwrap_or_else(Lazy::empty)
             .decode(self)
-            .map(|index| respan(self.get_span(index, sess), self.item_ident(index, sess).name))
-            .collect()
+            .map(move |index| respan(self.get_span(index, sess), self.item_ident(index, sess).name))
     }
 
-    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
             .tables
             .children
             .get(self, id)
             .unwrap_or_else(Lazy::empty)
             .decode(self)
-            .map(|field_index| self.get_visibility(field_index))
-            .collect()
+            .map(move |field_index| self.get_visibility(field_index))
     }
 
     fn get_inherent_implementations_for_type(
@@ -1401,8 +1391,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         tcx: TyCtxt<'tcx>,
         trait_def_id: DefId,
     ) -> &'tcx [(DefId, Option<SimplifiedType>)] {
-        if self.root.is_proc_macro_crate() {
-            // proc-macro crates export no trait impls.
+        if self.trait_impls.is_empty() {
             return &[];
         }
 
@@ -1437,13 +1426,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         })
     }
 
-    fn get_native_libraries(self, sess: &Session) -> Vec<NativeLib> {
-        if self.root.is_proc_macro_crate() {
-            // Proc macro crates do not have any *target* native libraries.
-            vec![]
-        } else {
-            self.root.native_libraries.decode((self, sess)).collect()
-        }
+    fn get_native_libraries(self, sess: &'a Session) -> impl Iterator<Item = NativeLib> + 'a {
+        self.root.native_libraries.decode((self, sess))
     }
 
     fn get_proc_macro_quoted_span(self, index: usize, sess: &Session) -> Span {
@@ -1455,15 +1439,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             .decode((self, sess))
     }
 
-    fn get_foreign_modules(self, tcx: TyCtxt<'tcx>) -> Lrc<FxHashMap<DefId, ForeignModule>> {
-        if self.root.is_proc_macro_crate() {
-            // 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_foreign_modules(self, sess: &'a Session) -> impl Iterator<Item = ForeignModule> + '_ {
+        self.root.foreign_modules.decode((self, sess))
     }
 
     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] {
-        if self.root.is_proc_macro_crate() {
-            // 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))
-        }
+        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] {
@@ -1500,13 +1472,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         self,
         tcx: TyCtxt<'tcx>,
     ) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportLevel)] {
-        if self.root.is_proc_macro_crate() {
-            // 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)))
-        }
+        tcx.arena.alloc_from_iter(self.root.exported_symbols.decode((self, tcx)))
     }
 
     fn get_rendered_const(self, id: DefIndex) -> String {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index a639772fde7..9b59c14c2fe 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -179,8 +179,10 @@ provide! { <'tcx> tcx, def_id, other, cdata,
 
         reachable_non_generics
     }
-    native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess)) }
-    foreign_modules => { cdata.get_foreign_modules(tcx) }
+    native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess).collect()) }
+    foreign_modules => {
+        Lrc::new(cdata.get_foreign_modules(tcx.sess).map(|m| (m.def_id, m)).collect())
+    }
     crate_hash => { cdata.root.hash }
     crate_host_hash => { cdata.host_hash }
     crate_name => { cdata.root.name }
@@ -371,11 +373,18 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
 }
 
 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)
     }
 
-    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)
     }
 
@@ -460,8 +469,12 @@ impl CStore {
         self.get_crate_data(cnum).num_def_ids()
     }
 
-    pub fn item_attrs_untracked(&self, def_id: DefId, sess: &Session) -> Vec<ast::Attribute> {
-        self.get_crate_data(def_id.krate).get_item_attrs(def_id.index, sess).collect()
+    pub fn item_attrs_untracked<'a>(
+        &'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(
@@ -473,15 +486,15 @@ impl CStore {
         self.get_crate_data(cnum).get_proc_macro_quoted_span(id, sess)
     }
 
-    pub fn traits_in_crate_untracked(&self, cnum: CrateNum) -> Vec<DefId> {
-        self.get_crate_data(cnum).get_traits().collect()
+    pub fn traits_in_crate_untracked(&self, cnum: CrateNum) -> impl Iterator<Item = DefId> + '_ {
+        self.get_crate_data(cnum).get_traits()
     }
 
     pub fn trait_impls_in_crate_untracked(
         &self,
         cnum: CrateNum,
-    ) -> Vec<(DefId, Option<SimplifiedType>)> {
-        self.get_crate_data(cnum).get_trait_impls().collect()
+    ) -> impl Iterator<Item = (DefId, Option<SimplifiedType>)> + '_ {
+        self.get_crate_data(cnum).get_trait_impls()
     }
 }
 
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 052770b201a..631b8fef668 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -999,12 +999,14 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
         let cstore = self.r.cstore();
         match res {
             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);
                 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_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
                         .struct_constructors
                         .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);
             }
             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);
             }
             Res::Def(DefKind::AssocFn, def_id) => {
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 941c2a70d11..c7edcb077b9 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -914,11 +914,8 @@ impl<'a> Resolver<'a> {
                             // a note about editions
                             let note = if let Some(did) = did {
                                 let requires_note = !did.is_local()
-                                    && this
-                                        .cstore()
-                                        .item_attrs_untracked(did, this.session)
-                                        .iter()
-                                        .any(|attr| {
+                                    && this.cstore().item_attrs_untracked(did, this.session).any(
+                                        |attr| {
                                             if attr.has_name(sym::rustc_diagnostic_item) {
                                                 [sym::TryInto, sym::TryFrom, sym::FromIterator]
                                                     .map(|x| Some(x))
@@ -926,7 +923,8 @@ impl<'a> Resolver<'a> {
                                             } else {
                                                 false
                                             }
-                                        });
+                                        },
+                                    );
 
                                 requires_note.then(|| {
                                     format!(
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 25137c6eda7..f5b2ba8fd72 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -3442,7 +3442,6 @@ impl<'a> Resolver<'a> {
                 let attr = self
                     .cstore()
                     .item_attrs_untracked(def_id, self.session)
-                    .into_iter()
                     .find(|a| a.has_name(sym::rustc_legacy_const_generics))?;
                 let mut ret = Vec::new();
                 for meta in attr.meta_item_list()? {