From 239084ceac080a76c2120ee9bb3c7b76b9b17294 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Wed, 30 Oct 2024 23:10:37 -0400 Subject: [PATCH 1/2] Querify MonoItem collection --- compiler/rustc_middle/src/mir/mono.rs | 73 ++++++++++++------- compiler/rustc_middle/src/query/erase.rs | 4 + compiler/rustc_middle/src/query/keys.rs | 18 +++++ compiler/rustc_middle/src/query/mod.rs | 13 +++- .../rustc_middle/src/query/on_disk_cache.rs | 10 ++- compiler/rustc_middle/src/ty/codec.rs | 11 +++ compiler/rustc_middle/src/ty/mod.rs | 1 + compiler/rustc_monomorphize/src/collector.rs | 55 ++++++-------- .../rustc_monomorphize/src/partitioning.rs | 6 +- 9 files changed, 128 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index d8d99deeb2c95..e4fc820a88f45 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -19,6 +19,7 @@ use rustc_target::spec::SymbolVisibility; use tracing::debug; use crate::dep_graph::{DepNode, WorkProduct, WorkProductId}; +use crate::query::Providers; use crate::ty::{GenericArgs, Instance, InstanceKind, SymbolName, TyCtxt}; /// Describes how a monomorphization will be instantiated in object files. @@ -46,7 +47,7 @@ pub enum InstantiationMode { LocalCopy, } -#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash, HashStable)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash, HashStable, TyEncodable, TyDecodable)] pub enum MonoItem<'tcx> { Fn(Instance<'tcx>), Static(DefId), @@ -62,30 +63,6 @@ impl<'tcx> MonoItem<'tcx> { } } - // Note: if you change how item size estimates work, you might need to - // change NON_INCR_MIN_CGU_SIZE as well. - pub fn size_estimate(&self, tcx: TyCtxt<'tcx>) -> usize { - match *self { - MonoItem::Fn(instance) => { - match instance.def { - // "Normal" functions size estimate: the number of - // statements, plus one for the terminator. - InstanceKind::Item(..) - | InstanceKind::DropGlue(..) - | InstanceKind::AsyncDropGlueCtorShim(..) => { - let mir = tcx.instance_mir(instance.def); - mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum() - } - // Other compiler-generated shims size estimate: 1 - _ => 1, - } - } - // Conservatively estimate the size of a static declaration or - // assembly item to be 1. - MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1, - } - } - pub fn is_generic_fn(&self) -> bool { match self { MonoItem::Fn(instance) => instance.args.non_erasable_generics().next().is_some(), @@ -556,3 +533,49 @@ impl<'tcx> CodegenUnitNameBuilder<'tcx> { Symbol::intern(&cgu_name) } } + +/// See module-level docs on some contect for "mentioned" items. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] +pub enum CollectionMode { + /// Collect items that are used, i.e., actually needed for codegen. + /// + /// Which items are used can depend on optimization levels, as MIR optimizations can remove + /// uses. + UsedItems, + /// Collect items that are mentioned. The goal of this mode is that it is independent of + /// optimizations: the set of "mentioned" items is computed before optimizations are run. + /// + /// The exact contents of this set are *not* a stable guarantee. (For instance, it is currently + /// computed after drop-elaboration. If we ever do some optimizations even in debug builds, we + /// might decide to run them before computing mentioned items.) The key property of this set is + /// that it is optimization-independent. + MentionedItems, +} + +// Note: if you change how item size estimates work, you might need to +// change NON_INCR_MIN_CGU_SIZE as well. +fn size_estimate<'tcx>(tcx: TyCtxt<'tcx>, item: MonoItem<'tcx>) -> usize { + match item { + MonoItem::Fn(instance) => { + match instance.def { + // "Normal" functions size estimate: the number of + // statements, plus one for the terminator. + InstanceKind::Item(..) + | InstanceKind::DropGlue(..) + | InstanceKind::AsyncDropGlueCtorShim(..) => { + let mir = tcx.instance_mir(instance.def); + mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum() + } + // Other compiler-generated shims size estimate: 1 + _ => 1, + } + } + // Conservatively estimate the size of a static declaration or + // assembly item to be 1. + MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1, + } +} + +pub fn provide(providers: &mut Providers) { + providers.size_estimate = size_estimate; +} diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 1d4c36e28bdba..013847f0b2d53 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -216,6 +216,10 @@ impl EraseType for (&'_ T0, &'_ [T1]) { type Result = [u8; size_of::<(&'static (), &'static [()])>()]; } +impl EraseType for (&'_ [T0], &'_ [T1]) { + type Result = [u8; size_of::<(&'static [()], &'static [()])>()]; +} + impl EraseType for (&'_ T0, Result<(), ErrorGuaranteed>) { type Result = [u8; size_of::<(&'static (), Result<(), ErrorGuaranteed>)>()]; } diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index fe28ef0f70c79..e35bcbf837e5e 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -7,6 +7,8 @@ use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{DUMMY_SP, Span}; use crate::infer::canonical::CanonicalQueryInput; +use crate::mir::mono::CollectionMode; +use crate::query::MonoItem; use crate::ty::fast_reject::SimplifiedType; use crate::ty::layout::{TyAndLayout, ValidityRequirement}; use crate::ty::{self, GenericArg, GenericArgsRef, Ty, TyCtxt}; @@ -85,6 +87,14 @@ impl<'tcx> Key for ty::Instance<'tcx> { } } +impl<'tcx> Key for MonoItem<'tcx> { + type Cache = DefaultCache; + + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + tcx.def_span(self.def_id()) + } +} + impl<'tcx> Key for mir::interpret::GlobalId<'tcx> { type Cache = DefaultCache; @@ -590,3 +600,11 @@ impl<'tcx> Key for (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>) { } } } + +impl<'tcx> Key for (ty::Instance<'tcx>, CollectionMode) { + type Cache = DefaultCache; + + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + self.0.default_span(tcx) + } +} diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 41d0b47388cce..357e37cce18ee 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -40,6 +40,7 @@ use rustc_session::cstore::{ }; use rustc_session::lint::LintExpectationId; use rustc_span::def_id::LOCAL_CRATE; +use rustc_span::source_map::Spanned; use rustc_span::symbol::Symbol; use rustc_span::{DUMMY_SP, Span}; use rustc_target::spec::PanicStrategy; @@ -59,7 +60,7 @@ use crate::mir::interpret::{ EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, GlobalId, LitToConstError, LitToConstInput, }; -use crate::mir::mono::CodegenUnit; +use crate::mir::mono::{CodegenUnit, CollectionMode, MonoItem}; use crate::query::erase::{Erase, erase, restore}; use crate::query::plumbing::{ CyclePlaceholder, DynamicQuery, query_ensure, query_ensure_error_guaranteed, query_get_at, @@ -2314,6 +2315,16 @@ rustc_queries! { desc { "whether the item should be made inlinable across crates" } separate_provide_extern } + + query items_of_instance(key: (ty::Instance<'tcx>, CollectionMode)) -> (&'tcx [Spanned>], &'tcx [Spanned>]) { + desc { "collecting items used by `{}`", key.0 } + cache_on_disk_if { true } + } + + query size_estimate(key: MonoItem<'tcx>) -> usize { + desc { "estimating codegen size of `{}`", key } + cache_on_disk_if { true } + } } rustc_query_append! { define_callbacks! } diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index 8b77a4a81ca8d..3849cb72668f6 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs @@ -12,6 +12,7 @@ use rustc_index::{Idx, IndexVec}; use rustc_macros::{Decodable, Encodable}; use rustc_middle::dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState}; +use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::{self, interpret}; use rustc_middle::ty::codec::{RefDecodable, TyDecoder, TyEncoder}; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -22,7 +23,7 @@ use rustc_session::Session; use rustc_span::hygiene::{ ExpnId, HygieneDecodeContext, HygieneEncodeContext, SyntaxContext, SyntaxContextData, }; -use rustc_span::source_map::SourceMap; +use rustc_span::source_map::{SourceMap, Spanned}; use rustc_span::{ BytePos, CachingSourceMapView, ExpnData, ExpnHash, Pos, RelativeBytePos, SourceFile, Span, SpanDecoder, SpanEncoder, StableSourceFileId, Symbol, @@ -773,6 +774,13 @@ impl<'a, 'tcx> Decodable> for &'tcx [rustc_ast::InlineAsm } } +impl<'a, 'tcx> Decodable> for &'tcx [Spanned>] { + #[inline] + fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self { + RefDecodable::decode(d) + } +} + impl<'a, 'tcx> Decodable> for &'tcx crate::traits::specialization_graph::Graph { diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index b5358f0ca35e9..47a84d4b25821 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -13,9 +13,11 @@ use std::marker::DiscriminantKind; use rustc_abi::{FieldIdx, VariantIdx}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::LocalDefId; +use rustc_middle::mir::mono::MonoItem; use rustc_middle::ty::TyCtxt; use rustc_serialize::{Decodable, Encodable}; use rustc_span::Span; +use rustc_span::source_map::Spanned; pub use rustc_type_ir::{TyDecoder, TyEncoder}; use crate::arena::ArenaAllocatable; @@ -397,6 +399,15 @@ impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> } } +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for [Spanned>] { + fn decode(decoder: &mut D) -> &'tcx Self { + decoder + .interner() + .arena + .alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder))) + } +} + impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for ty::List { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8a324be32e777..c216fd2965e48 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2154,6 +2154,7 @@ pub fn provide(providers: &mut Providers) { print::provide(providers); super::util::bug::provide(providers); super::middle::provide(providers); + super::mir::mono::provide(providers); *providers = Providers { trait_impls_of: trait_def::trait_impls_of_provider, incoherent_impls: trait_def::incoherent_impls_provider, diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 50bab0da606f8..65b2063f643e7 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -219,7 +219,7 @@ use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::{AllocId, ErrorHandled, GlobalAlloc, Scalar}; -use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; +use rustc_middle::mir::mono::{CollectionMode, InstantiationMode, MonoItem}; use rustc_middle::mir::visit::Visitor as MirVisitor; use rustc_middle::mir::{self, Location, MentionedItem, traversal}; use rustc_middle::query::TyCtxtAt; @@ -268,24 +268,6 @@ struct SharedState<'tcx> { usage_map: MTLock>, } -/// See module-level docs on some contect for "mentioned" items. -#[derive(Copy, Clone, Debug, PartialEq)] -enum CollectionMode { - /// Collect items that are used, i.e., actually needed for codegen. - /// - /// Which items are used can depend on optimization levels, as MIR optimizations can remove - /// uses. - UsedItems, - /// Collect items that are mentioned. The goal of this mode is that it is independent of - /// optimizations: the set of "mentioned" items is computed before optimizations are run. - /// - /// The exact contents of this set are *not* a stable guarantee. (For instance, it is currently - /// computed after drop-elaboration. If we ever do some optimizations even in debug builds, we - /// might decide to run them before computing mentioned items.) The key property of this set is - /// that it is optimization-independent. - MentionedItems, -} - impl<'tcx> UsageMap<'tcx> { fn new() -> UsageMap<'tcx> { UsageMap { used_map: Default::default(), user_map: Default::default() } @@ -447,13 +429,9 @@ fn collect_items_rec<'tcx>( )); rustc_data_structures::stack::ensure_sufficient_stack(|| { - collect_items_of_instance( - tcx, - instance, - &mut used_items, - &mut mentioned_items, - mode, - ) + let (used, mentioned) = tcx.items_of_instance((instance, mode)); + used_items.extend(used); + mentioned_items.extend(mentioned); }); } MonoItem::GlobalAsm(item_id) => { @@ -1199,14 +1177,12 @@ fn assoc_fn_of_type<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fn_ident: Ident) -> /// Scans the MIR in order to find function calls, closures, and drop-glue. /// /// Anything that's found is added to `output`. Furthermore the "mentioned items" of the MIR are returned. -#[instrument(skip(tcx, used_items, mentioned_items), level = "debug")] +#[instrument(skip(tcx), level = "debug")] fn collect_items_of_instance<'tcx>( tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, - used_items: &mut MonoItems<'tcx>, - mentioned_items: &mut MonoItems<'tcx>, mode: CollectionMode, -) { +) -> (MonoItems<'tcx>, MonoItems<'tcx>) { let body = tcx.instance_mir(instance.def); // Naively, in "used" collection mode, all functions get added to *both* `used_items` and // `mentioned_items`. Mentioned items processing will then notice that they have already been @@ -1218,11 +1194,13 @@ fn collect_items_of_instance<'tcx>( // mentioned item. So instead we collect all pre-monomorphized `MentionedItem` that were already // added to `used_items` in a hash set, which can efficiently query in the // `body.mentioned_items` loop below without even having to monomorphize the item. + let mut used_items = Default::default(); + let mut mentioned_items = Default::default(); let mut used_mentioned_items = Default::default(); let mut collector = MirUsedCollector { tcx, body, - used_items, + used_items: &mut used_items, used_mentioned_items: &mut used_mentioned_items, instance, visiting_call_terminator: false, @@ -1239,7 +1217,7 @@ fn collect_items_of_instance<'tcx>( // them errors. for const_op in body.required_consts() { if let Some(val) = collector.eval_constant(const_op) { - collect_const_value(tcx, val, mentioned_items); + collect_const_value(tcx, val, &mut mentioned_items); } } @@ -1248,9 +1226,19 @@ fn collect_items_of_instance<'tcx>( for item in body.mentioned_items() { if !collector.used_mentioned_items.contains(&item.node) { let item_mono = collector.monomorphize(item.node); - visit_mentioned_item(tcx, &item_mono, item.span, mentioned_items); + visit_mentioned_item(tcx, &item_mono, item.span, &mut mentioned_items); } } + + (used_items, mentioned_items) +} + +fn items_of_instance<'tcx>( + tcx: TyCtxt<'tcx>, + (instance, mode): (Instance<'tcx>, CollectionMode), +) -> (&'tcx [Spanned>], &'tcx [Spanned>]) { + let (used_items, mentioned_items) = collect_items_of_instance(tcx, instance, mode); + (tcx.arena.alloc_slice(&used_items), tcx.arena.alloc_slice(&mentioned_items)) } /// `item` must be already monomorphized. @@ -1623,4 +1611,5 @@ pub(crate) fn collect_crate_mono_items<'tcx>( pub(crate) fn provide(providers: &mut Providers) { providers.hooks.should_codegen_locally = should_codegen_locally; + providers.items_of_instance = items_of_instance; } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index e2a6d392ca093..2c2e1a3c0bd24 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -254,7 +254,7 @@ where if visibility == Visibility::Hidden && can_be_internalized { internalization_candidates.insert(mono_item); } - let size_estimate = mono_item.size_estimate(cx.tcx); + let size_estimate = cx.tcx.size_estimate(mono_item); cgu.items_mut().insert(mono_item, MonoItemData { inlined: false, @@ -279,7 +279,7 @@ where inlined: true, linkage: Linkage::Internal, visibility: Visibility::Default, - size_estimate: inlined_item.size_estimate(cx.tcx), + size_estimate: cx.tcx.size_estimate(inlined_item), }); } } @@ -1274,7 +1274,7 @@ fn dump_mono_items_stats<'tcx>( .map(|(def_id, items)| { let name = with_no_trimmed_paths!(tcx.def_path_str(def_id)); let instantiation_count = items.len(); - let size_estimate = items[0].size_estimate(tcx); + let size_estimate = tcx.size_estimate(*items[0]); let total_estimate = instantiation_count * size_estimate; MonoItem { name, instantiation_count, size_estimate, total_estimate } }) From 1add34f64f431f32a93cc6084a9cb8c2c1af8c44 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 3 Nov 2024 23:32:40 -0500 Subject: [PATCH 2/2] Don't duplicate collection results --- compiler/rustc_monomorphize/src/collector.rs | 72 ++++++++++++++----- tests/ui/codegen/overflow-during-mono.rs | 2 +- tests/ui/codegen/overflow-during-mono.stderr | 8 +-- .../const-expr-generic-err.stderr | 40 +++++------ tests/ui/type_length_limit.stderr | 8 +-- 5 files changed, 84 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 65b2063f643e7..521f33a0b6cce 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -255,7 +255,44 @@ pub(crate) struct UsageMap<'tcx> { user_map: UnordMap, Vec>>, } -type MonoItems<'tcx> = Vec>>; +struct MonoItems<'tcx> { + tcx: TyCtxt<'tcx>, + // We want a set of MonoItem + Span where trying to re-insert a MonoItem with a different Span + // is ignored. Map does that, but it looks wrong. + items: UnordMap, Span>, +} + +impl<'tcx> MonoItems<'tcx> { + fn new(tcx: TyCtxt<'tcx>) -> Self { + Self { tcx, items: UnordMap::default() } + } + + fn is_empty(&self) -> bool { + self.items.is_empty() + } + + fn push(&mut self, item: Spanned>) { + // Insert only if the entry does not exist. A normal insert would stomp the first span that + // got inserted. + self.items.entry(item.node).or_insert(item.span); + } + + fn extend(&mut self, iter: impl IntoIterator>>) { + for item in iter { + self.push(item.clone()); + } + } + + fn into_iter(self) -> impl Iterator>> { + self.tcx.with_stable_hashing_context(|hcx| { + self.items.into_sorted(&hcx, true).into_iter().map(|(item, span)| respan(span, item)) + }) + } + + fn items(&self) -> Vec> { + self.tcx.with_stable_hashing_context(|hcx| self.items.keys().cloned().into_sorted(&hcx)) + } +} /// The state that is shared across the concurrent threads that are doing collection. struct SharedState<'tcx> { @@ -273,14 +310,11 @@ impl<'tcx> UsageMap<'tcx> { UsageMap { used_map: Default::default(), user_map: Default::default() } } - fn record_used<'a>( - &mut self, - user_item: MonoItem<'tcx>, - used_items: &'a [Spanned>], - ) where + fn record_used<'a>(&mut self, user_item: MonoItem<'tcx>, used_items: &'a MonoItems<'tcx>) + where 'tcx: 'a, { - let used_items: Vec<_> = used_items.iter().map(|item| item.node).collect(); + let used_items = used_items.items(); for &used_item in used_items.iter() { self.user_map.entry(used_item).or_default().push(user_item); } @@ -343,8 +377,8 @@ fn collect_items_rec<'tcx>( // harm in that, the mention visit will trigger all the queries and the results are cached. } - let mut used_items = MonoItems::new(); - let mut mentioned_items = MonoItems::new(); + let mut used_items = MonoItems::new(tcx); + let mut mentioned_items = MonoItems::new(tcx); let recursion_depth_reset; // Post-monomorphization errors MVP @@ -430,8 +464,8 @@ fn collect_items_rec<'tcx>( rustc_data_structures::stack::ensure_sufficient_stack(|| { let (used, mentioned) = tcx.items_of_instance((instance, mode)); - used_items.extend(used); - mentioned_items.extend(mentioned); + used_items.extend(used.into_iter().copied()); + mentioned_items.extend(mentioned.into_iter().copied()); }); } MonoItem::GlobalAsm(item_id) => { @@ -503,7 +537,7 @@ fn collect_items_rec<'tcx>( if mode == CollectionMode::MentionedItems { assert!(used_items.is_empty(), "'mentioned' collection should never encounter used items"); } else { - for used_item in used_items { + for used_item in used_items.into_iter() { collect_items_rec( tcx, used_item, @@ -517,7 +551,7 @@ fn collect_items_rec<'tcx>( // Walk over mentioned items *after* used items, so that if an item is both mentioned and used then // the loop above has fully collected it, so this loop will skip it. - for mentioned_item in mentioned_items { + for mentioned_item in mentioned_items.into_iter() { collect_items_rec( tcx, mentioned_item, @@ -1194,8 +1228,8 @@ fn collect_items_of_instance<'tcx>( // mentioned item. So instead we collect all pre-monomorphized `MentionedItem` that were already // added to `used_items` in a hash set, which can efficiently query in the // `body.mentioned_items` loop below without even having to monomorphize the item. - let mut used_items = Default::default(); - let mut mentioned_items = Default::default(); + let mut used_items = MonoItems::new(tcx); + let mut mentioned_items = MonoItems::new(tcx); let mut used_mentioned_items = Default::default(); let mut collector = MirUsedCollector { tcx, @@ -1238,7 +1272,11 @@ fn items_of_instance<'tcx>( (instance, mode): (Instance<'tcx>, CollectionMode), ) -> (&'tcx [Spanned>], &'tcx [Spanned>]) { let (used_items, mentioned_items) = collect_items_of_instance(tcx, instance, mode); - (tcx.arena.alloc_slice(&used_items), tcx.arena.alloc_slice(&mentioned_items)) + + let used_items = tcx.arena.alloc_from_iter(used_items.into_iter()); + let mentioned_items = tcx.arena.alloc_from_iter(mentioned_items.into_iter()); + + (used_items, mentioned_items) } /// `item` must be already monomorphized. @@ -1319,7 +1357,7 @@ fn collect_const_value<'tcx>( #[instrument(skip(tcx, mode), level = "debug")] fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionStrategy) -> Vec> { debug!("collecting roots"); - let mut roots = Vec::new(); + let mut roots = MonoItems::new(tcx); { let entry_fn = tcx.entry_fn(()); diff --git a/tests/ui/codegen/overflow-during-mono.rs b/tests/ui/codegen/overflow-during-mono.rs index 83a8b6b3ef6a2..e6f3ba19c6589 100644 --- a/tests/ui/codegen/overflow-during-mono.rs +++ b/tests/ui/codegen/overflow-during-mono.rs @@ -1,4 +1,4 @@ -//~ ERROR overflow evaluating the requirement `{closure@$DIR/overflow-during-mono.rs:13:41: 13:44}: Sized` +//~ ERROR overflow evaluating the requirement //@ build-fail #![recursion_limit = "32"] diff --git a/tests/ui/codegen/overflow-during-mono.stderr b/tests/ui/codegen/overflow-during-mono.stderr index f7a3e2df3dbaa..e4a7362f66983 100644 --- a/tests/ui/codegen/overflow-during-mono.stderr +++ b/tests/ui/codegen/overflow-during-mono.stderr @@ -1,10 +1,10 @@ -error[E0275]: overflow evaluating the requirement `{closure@$DIR/overflow-during-mono.rs:13:41: 13:44}: Sized` +error[E0275]: overflow evaluating the requirement `{closure@$DIR/overflow-during-mono.rs:14:36: 14:39}: Sized` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "64"]` attribute to your crate (`overflow_during_mono`) - = note: required for `Filter, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `Iterator` + = note: required for `Filter, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>` to implement `Iterator` = note: 31 redundant requirements hidden - = note: required for `Filter, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `Iterator` - = note: required for `Filter, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `IntoIterator` + = note: required for `Filter, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `Iterator` + = note: required for `Filter, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:14:36: 14:39}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `IntoIterator` error: aborting due to 1 previous error diff --git a/tests/ui/inline-const/const-expr-generic-err.stderr b/tests/ui/inline-const/const-expr-generic-err.stderr index dcd6b62bbfc1d..40b65f995585c 100644 --- a/tests/ui/inline-const/const-expr-generic-err.stderr +++ b/tests/ui/inline-const/const-expr-generic-err.stderr @@ -1,23 +1,3 @@ -error[E0080]: evaluation of `foo::::{constant#0}` failed - --> $DIR/const-expr-generic-err.rs:4:13 - | -LL | const { assert!(std::mem::size_of::() == 0); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: std::mem::size_of::() == 0', $DIR/const-expr-generic-err.rs:4:13 - | - = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) - -note: erroneous constant encountered - --> $DIR/const-expr-generic-err.rs:4:5 - | -LL | const { assert!(std::mem::size_of::() == 0); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -note: the above error was encountered while instantiating `fn foo::` - --> $DIR/const-expr-generic-err.rs:12:5 - | -LL | foo::(); - | ^^^^^^^^^^^^ - error[E0080]: evaluation of `bar::<0>::{constant#0}` failed --> $DIR/const-expr-generic-err.rs:8:13 | @@ -44,6 +24,26 @@ note: the above error was encountered while instantiating `fn bar::<0>` LL | bar::<0>(); | ^^^^^^^^^^ +error[E0080]: evaluation of `foo::::{constant#0}` failed + --> $DIR/const-expr-generic-err.rs:4:13 + | +LL | const { assert!(std::mem::size_of::() == 0); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: std::mem::size_of::() == 0', $DIR/const-expr-generic-err.rs:4:13 + | + = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: erroneous constant encountered + --> $DIR/const-expr-generic-err.rs:4:5 + | +LL | const { assert!(std::mem::size_of::() == 0); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: the above error was encountered while instantiating `fn foo::` + --> $DIR/const-expr-generic-err.rs:12:5 + | +LL | foo::(); + | ^^^^^^^^^^^^ + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/type_length_limit.stderr b/tests/ui/type_length_limit.stderr index 83353547d34db..e28c248e8cf47 100644 --- a/tests/ui/type_length_limit.stderr +++ b/tests/ui/type_length_limit.stderr @@ -1,3 +1,7 @@ +error: reached the type-length limit while instantiating `<{closure@rt::lang_start<()>::{closure#0}} as FnMut<()>>::call_mut` + | + = help: consider adding a `#![type_length_limit="10"]` attribute to your crate + error: reached the type-length limit while instantiating `std::mem::drop::>` --> $DIR/type_length_limit.rs:32:5 | @@ -7,9 +11,5 @@ LL | drop::>(None); = help: consider adding a `#![type_length_limit="4010"]` attribute to your crate = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt' -error: reached the type-length limit while instantiating `<{closure@rt::lang_start<()>::{closure#0}} as FnMut<()>>::call_mut` - | - = help: consider adding a `#![type_length_limit="10"]` attribute to your crate - error: aborting due to 2 previous errors