Skip to content

Commit 48e89b0

Browse files
committed
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.
2 parents 7be8693 + 4549b13 commit 48e89b0

File tree

5 files changed

+66
-87
lines changed

5 files changed

+66
-87
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

+33-67
Original file line numberDiff line numberDiff line change
@@ -1033,45 +1033,33 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
10331033

10341034
/// Iterates over all the stability attributes in the given crate.
10351035
fn get_lib_features(self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Option<Symbol>)] {
1036-
// FIXME: For a proc macro crate, not sure whether we should return the "host"
1037-
// features or an empty Vec. Both don't cause ICEs.
10381036
tcx.arena.alloc_from_iter(self.root.lib_features.decode(self))
10391037
}
10401038

10411039
/// Iterates over the language items in the given crate.
10421040
fn get_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] {
1043-
if self.root.is_proc_macro_crate() {
1044-
// Proc macro crates do not export any lang-items to the target.
1045-
&[]
1046-
} else {
1047-
tcx.arena.alloc_from_iter(
1048-
self.root
1049-
.lang_items
1050-
.decode(self)
1051-
.map(|(def_index, index)| (self.local_def_id(def_index), index)),
1052-
)
1053-
}
1041+
tcx.arena.alloc_from_iter(
1042+
self.root
1043+
.lang_items
1044+
.decode(self)
1045+
.map(|(def_index, index)| (self.local_def_id(def_index), index)),
1046+
)
10541047
}
10551048

10561049
/// Iterates over the diagnostic items in the given crate.
10571050
fn get_diagnostic_items(self) -> DiagnosticItems {
1058-
if self.root.is_proc_macro_crate() {
1059-
// Proc macro crates do not export any diagnostic-items to the target.
1060-
Default::default()
1061-
} else {
1062-
let mut id_to_name = FxHashMap::default();
1063-
let name_to_id = self
1064-
.root
1065-
.diagnostic_items
1066-
.decode(self)
1067-
.map(|(name, def_index)| {
1068-
let id = self.local_def_id(def_index);
1069-
id_to_name.insert(id, name);
1070-
(name, id)
1071-
})
1072-
.collect();
1073-
DiagnosticItems { id_to_name, name_to_id }
1074-
}
1051+
let mut id_to_name = FxHashMap::default();
1052+
let name_to_id = self
1053+
.root
1054+
.diagnostic_items
1055+
.decode(self)
1056+
.map(|(name, def_index)| {
1057+
let id = self.local_def_id(def_index);
1058+
id_to_name.insert(id, name);
1059+
(name, id)
1060+
})
1061+
.collect();
1062+
DiagnosticItems { id_to_name, name_to_id }
10751063
}
10761064

10771065
/// Iterates over all named children of the given module,
@@ -1346,26 +1334,28 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
13461334
.decode((self, sess))
13471335
}
13481336

1349-
fn get_struct_field_names(self, id: DefIndex, sess: &Session) -> Vec<Spanned<Symbol>> {
1337+
fn get_struct_field_names(
1338+
self,
1339+
id: DefIndex,
1340+
sess: &'a Session,
1341+
) -> impl Iterator<Item = Spanned<Symbol>> + 'a {
13501342
self.root
13511343
.tables
13521344
.children
13531345
.get(self, id)
13541346
.unwrap_or_else(Lazy::empty)
13551347
.decode(self)
1356-
.map(|index| respan(self.get_span(index, sess), self.item_ident(index, sess).name))
1357-
.collect()
1348+
.map(move |index| respan(self.get_span(index, sess), self.item_ident(index, sess).name))
13581349
}
13591350

1360-
fn get_struct_field_visibilities(self, id: DefIndex) -> Vec<Visibility> {
1351+
fn get_struct_field_visibilities(self, id: DefIndex) -> impl Iterator<Item = Visibility> + 'a {
13611352
self.root
13621353
.tables
13631354
.children
13641355
.get(self, id)
13651356
.unwrap_or_else(Lazy::empty)
13661357
.decode(self)
1367-
.map(|field_index| self.get_visibility(field_index))
1368-
.collect()
1358+
.map(move |field_index| self.get_visibility(field_index))
13691359
}
13701360

13711361
fn get_inherent_implementations_for_type(
@@ -1401,8 +1391,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
14011391
tcx: TyCtxt<'tcx>,
14021392
trait_def_id: DefId,
14031393
) -> &'tcx [(DefId, Option<SimplifiedType>)] {
1404-
if self.root.is_proc_macro_crate() {
1405-
// proc-macro crates export no trait impls.
1394+
if self.trait_impls.is_empty() {
14061395
return &[];
14071396
}
14081397

@@ -1437,13 +1426,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
14371426
})
14381427
}
14391428

1440-
fn get_native_libraries(self, sess: &Session) -> Vec<NativeLib> {
1441-
if self.root.is_proc_macro_crate() {
1442-
// Proc macro crates do not have any *target* native libraries.
1443-
vec![]
1444-
} else {
1445-
self.root.native_libraries.decode((self, sess)).collect()
1446-
}
1429+
fn get_native_libraries(self, sess: &'a Session) -> impl Iterator<Item = NativeLib> + 'a {
1430+
self.root.native_libraries.decode((self, sess))
14471431
}
14481432

14491433
fn get_proc_macro_quoted_span(self, index: usize, sess: &Session) -> Span {
@@ -1455,15 +1439,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
14551439
.decode((self, sess))
14561440
}
14571441

1458-
fn get_foreign_modules(self, tcx: TyCtxt<'tcx>) -> Lrc<FxHashMap<DefId, ForeignModule>> {
1459-
if self.root.is_proc_macro_crate() {
1460-
// Proc macro crates do not have any *target* foreign modules.
1461-
Lrc::new(FxHashMap::default())
1462-
} else {
1463-
let modules: FxHashMap<DefId, ForeignModule> =
1464-
self.root.foreign_modules.decode((self, tcx.sess)).map(|m| (m.def_id, m)).collect();
1465-
Lrc::new(modules)
1466-
}
1442+
fn get_foreign_modules(self, sess: &'a Session) -> impl Iterator<Item = ForeignModule> + '_ {
1443+
self.root.foreign_modules.decode((self, sess))
14671444
}
14681445

14691446
fn get_dylib_dependency_formats(
@@ -1479,12 +1456,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
14791456
}
14801457

14811458
fn get_missing_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] {
1482-
if self.root.is_proc_macro_crate() {
1483-
// Proc macro crates do not depend on any target weak lang-items.
1484-
&[]
1485-
} else {
1486-
tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode(self))
1487-
}
1459+
tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode(self))
14881460
}
14891461

14901462
fn get_fn_param_names(self, tcx: TyCtxt<'tcx>, id: DefIndex) -> &'tcx [Ident] {
@@ -1500,13 +1472,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
15001472
self,
15011473
tcx: TyCtxt<'tcx>,
15021474
) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportLevel)] {
1503-
if self.root.is_proc_macro_crate() {
1504-
// If this crate is a custom derive crate, then we're not even going to
1505-
// link those in so we skip those crates.
1506-
&[]
1507-
} else {
1508-
tcx.arena.alloc_from_iter(self.root.exported_symbols.decode((self, tcx)))
1509-
}
1475+
tcx.arena.alloc_from_iter(self.root.exported_symbols.decode((self, tcx)))
15101476
}
15111477

15121478
fn get_rendered_const(self, id: DefIndex) -> String {

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+23-10
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,10 @@ provide! { <'tcx> tcx, def_id, other, cdata,
179179

180180
reachable_non_generics
181181
}
182-
native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess)) }
183-
foreign_modules => { cdata.get_foreign_modules(tcx) }
182+
native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess).collect()) }
183+
foreign_modules => {
184+
Lrc::new(cdata.get_foreign_modules(tcx.sess).map(|m| (m.def_id, m)).collect())
185+
}
184186
crate_hash => { cdata.root.hash }
185187
crate_host_hash => { cdata.host_hash }
186188
crate_name => { cdata.root.name }
@@ -371,11 +373,18 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
371373
}
372374

373375
impl CStore {
374-
pub fn struct_field_names_untracked(&self, def: DefId, sess: &Session) -> Vec<Spanned<Symbol>> {
376+
pub fn struct_field_names_untracked<'a>(
377+
&'a self,
378+
def: DefId,
379+
sess: &'a Session,
380+
) -> impl Iterator<Item = Spanned<Symbol>> + 'a {
375381
self.get_crate_data(def.krate).get_struct_field_names(def.index, sess)
376382
}
377383

378-
pub fn struct_field_visibilities_untracked(&self, def: DefId) -> Vec<Visibility> {
384+
pub fn struct_field_visibilities_untracked(
385+
&self,
386+
def: DefId,
387+
) -> impl Iterator<Item = Visibility> + '_ {
379388
self.get_crate_data(def.krate).get_struct_field_visibilities(def.index)
380389
}
381390

@@ -460,8 +469,12 @@ impl CStore {
460469
self.get_crate_data(cnum).num_def_ids()
461470
}
462471

463-
pub fn item_attrs_untracked(&self, def_id: DefId, sess: &Session) -> Vec<ast::Attribute> {
464-
self.get_crate_data(def_id.krate).get_item_attrs(def_id.index, sess).collect()
472+
pub fn item_attrs_untracked<'a>(
473+
&'a self,
474+
def_id: DefId,
475+
sess: &'a Session,
476+
) -> impl Iterator<Item = ast::Attribute> + 'a {
477+
self.get_crate_data(def_id.krate).get_item_attrs(def_id.index, sess)
465478
}
466479

467480
pub fn get_proc_macro_quoted_span_untracked(
@@ -473,15 +486,15 @@ impl CStore {
473486
self.get_crate_data(cnum).get_proc_macro_quoted_span(id, sess)
474487
}
475488

476-
pub fn traits_in_crate_untracked(&self, cnum: CrateNum) -> Vec<DefId> {
477-
self.get_crate_data(cnum).get_traits().collect()
489+
pub fn traits_in_crate_untracked(&self, cnum: CrateNum) -> impl Iterator<Item = DefId> + '_ {
490+
self.get_crate_data(cnum).get_traits()
478491
}
479492

480493
pub fn trait_impls_in_crate_untracked(
481494
&self,
482495
cnum: CrateNum,
483-
) -> Vec<(DefId, Option<SimplifiedType>)> {
484-
self.get_crate_data(cnum).get_trait_impls().collect()
496+
) -> impl Iterator<Item = (DefId, Option<SimplifiedType>)> + '_ {
497+
self.get_crate_data(cnum).get_trait_impls()
485498
}
486499
}
487500

compiler/rustc_resolve/src/build_reduced_graph.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -999,20 +999,23 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
999999
let cstore = self.r.cstore();
10001000
match res {
10011001
Res::Def(DefKind::Struct, def_id) => {
1002-
let field_names = cstore.struct_field_names_untracked(def_id, self.r.session);
1002+
let field_names =
1003+
cstore.struct_field_names_untracked(def_id, self.r.session).collect();
10031004
let ctor = cstore.ctor_def_id_and_kind_untracked(def_id);
10041005
if let Some((ctor_def_id, ctor_kind)) = ctor {
10051006
let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
10061007
let ctor_vis = cstore.visibility_untracked(ctor_def_id);
1007-
let field_visibilities = cstore.struct_field_visibilities_untracked(def_id);
1008+
let field_visibilities =
1009+
cstore.struct_field_visibilities_untracked(def_id).collect();
10081010
self.r
10091011
.struct_constructors
10101012
.insert(def_id, (ctor_res, ctor_vis, field_visibilities));
10111013
}
10121014
self.insert_field_names(def_id, field_names);
10131015
}
10141016
Res::Def(DefKind::Union, def_id) => {
1015-
let field_names = cstore.struct_field_names_untracked(def_id, self.r.session);
1017+
let field_names =
1018+
cstore.struct_field_names_untracked(def_id, self.r.session).collect();
10161019
self.insert_field_names(def_id, field_names);
10171020
}
10181021
Res::Def(DefKind::AssocFn, def_id) => {

compiler/rustc_resolve/src/diagnostics.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -914,19 +914,17 @@ impl<'a> Resolver<'a> {
914914
// a note about editions
915915
let note = if let Some(did) = did {
916916
let requires_note = !did.is_local()
917-
&& this
918-
.cstore()
919-
.item_attrs_untracked(did, this.session)
920-
.iter()
921-
.any(|attr| {
917+
&& this.cstore().item_attrs_untracked(did, this.session).any(
918+
|attr| {
922919
if attr.has_name(sym::rustc_diagnostic_item) {
923920
[sym::TryInto, sym::TryFrom, sym::FromIterator]
924921
.map(|x| Some(x))
925922
.contains(&attr.value_str())
926923
} else {
927924
false
928925
}
929-
});
926+
},
927+
);
930928

931929
requires_note.then(|| {
932930
format!(

compiler/rustc_resolve/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -3442,7 +3442,6 @@ impl<'a> Resolver<'a> {
34423442
let attr = self
34433443
.cstore()
34443444
.item_attrs_untracked(def_id, self.session)
3445-
.into_iter()
34463445
.find(|a| a.has_name(sym::rustc_legacy_const_generics))?;
34473446
let mut ret = Vec::new();
34483447
for meta in attr.meta_item_list()? {

0 commit comments

Comments
 (0)