From 6ff55ac6a0bbc0917e51967b343a295d50b69d80 Mon Sep 17 00:00:00 2001 From: naganohara-yoshino Date: Wed, 27 May 2026 04:59:10 +0800 Subject: [PATCH 1/3] Avoid mono collection hangs from recursive type growth --- compiler/rustc_middle/src/ty/instance.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 18 ++++++++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 6a04357827360..52dcd88a6c25c 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -400,7 +400,7 @@ impl<'tcx> ShimKind<'tcx> { } } -fn type_length<'tcx>(item: impl TypeVisitable>) -> usize { +pub fn type_length<'tcx>(item: impl TypeVisitable>) -> usize { struct Visitor<'tcx> { type_length: usize, cache: FxHashMap, usize>, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 4c14858101bf1..3e5cdf16437bf 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -84,7 +84,7 @@ pub use self::context::{ CtxtInterners, CurrentGcx, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed, tls, }; pub use self::fold::*; -pub use self::instance::{Instance, InstanceKind, ReifyReason, ShimKind}; +pub use self::instance::{Instance, InstanceKind, ReifyReason, ShimKind, type_length}; pub(crate) use self::list::RawList; pub use self::list::{List, ListWithCachedTypeInfo}; pub use self::opaque_types::OpaqueTypeKey; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 631d28d6cef00..6d92ca386a46b 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -227,7 +227,7 @@ use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion}; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{ self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, ShimKind, Ty, TyCtxt, - TypeFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, Unnormalized, VtblEntry, + TypeFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, Unnormalized, VtblEntry, type_length, }; use rustc_middle::util::Providers; use rustc_middle::{bug, span_bug}; @@ -664,10 +664,20 @@ fn check_recursion_limit<'tcx>( recursion_depth }; + // Rust code can create exponentially-long types using only a + // polynomial recursion depth. Start checking the type length before + // the depth limit is reached, to avoid hanging on enormous instance + // arguments. + let type_length_check_depth = (recursion_limit / 8).0.max(4); + let recursive_type_growth_limit_reached = recursion_depth >= type_length_check_depth + && !tcx.type_length_limit().value_within_limit(type_length(instance.args)); + // Code that needs to instantiate the same function recursively - // more than the recursion limit is assumed to be causing an - // infinite expansion. - if !recursion_limit.value_within_limit(adjusted_recursion_depth) { + // more than the recursion limit, or with type arguments that exceed the + // type length limit, is assumed to be causing an infinite expansion. + if !recursion_limit.value_within_limit(adjusted_recursion_depth) + || recursive_type_growth_limit_reached + { let def_span = tcx.def_span(def_id); let def_path_str = tcx.def_path_str(def_id); tcx.dcx().emit_fatal(RecursionLimit { span, instance, def_span, def_path_str }); From 725c0bcdbeb842b5c592224b07515a81a06e3d50 Mon Sep 17 00:00:00 2001 From: naganohara-yoshino Date: Wed, 27 May 2026 07:45:54 +0800 Subject: [PATCH 2/3] Update recursive monomorphization related UI tests --- compiler/rustc_monomorphize/src/collector.rs | 3 ++- tests/ui/codegen/overflow-during-mono.rs | 3 ++- tests/ui/codegen/overflow-during-mono.stderr | 11 +++----- ...inite-instantiation-via-nested-closures.rs | 19 ++++++-------- ...e-instantiation-via-nested-closures.stderr | 12 ++++----- tests/ui/recursion/issue-83150.rs | 2 +- tests/ui/recursion/issue-83150.stderr | 18 +++++++------ ...recursive-mono-type-growth-issue-156272.rs | 22 ++++++++++++++++ ...rsive-mono-type-growth-issue-156272.stderr | 16 ++++++++++++ .../traits/issue-91949-hangs-on-recursion.rs | 2 +- .../issue-91949-hangs-on-recursion.stderr | 25 ++++++++++--------- 11 files changed, 85 insertions(+), 48 deletions(-) create mode 100644 tests/ui/recursion/recursive-mono-type-growth-issue-156272.rs create mode 100644 tests/ui/recursion/recursive-mono-type-growth-issue-156272.stderr diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 6d92ca386a46b..d9a4ca2cd0f68 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -227,7 +227,8 @@ use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion}; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{ self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, ShimKind, Ty, TyCtxt, - TypeFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, Unnormalized, VtblEntry, type_length, + TypeFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, Unnormalized, VtblEntry, + type_length, }; use rustc_middle::util::Providers; use rustc_middle::{bug, span_bug}; diff --git a/tests/ui/codegen/overflow-during-mono.rs b/tests/ui/codegen/overflow-during-mono.rs index 3aafe05ba0537..96b148dcb5a79 100644 --- a/tests/ui/codegen/overflow-during-mono.rs +++ b/tests/ui/codegen/overflow-during-mono.rs @@ -1,7 +1,8 @@ -//~ ERROR overflow evaluating the requirement `for<'a> {closure@$DIR/overflow-during-mono.rs:14:41: 14:44}: FnMut(&'a _)` //@ build-fail //@ compile-flags: -Zwrite-long-types-to-disk=yes +//~? ERROR reached the recursion limit while instantiating + #![recursion_limit = "32"] fn quicksort, I: IntoIterator, T: Ord>( diff --git a/tests/ui/codegen/overflow-during-mono.stderr b/tests/ui/codegen/overflow-during-mono.stderr index 4d631e255afe5..95acb5e664f28 100644 --- a/tests/ui/codegen/overflow-during-mono.stderr +++ b/tests/ui/codegen/overflow-during-mono.stderr @@ -1,13 +1,10 @@ -error[E0275]: overflow evaluating the requirement `for<'a> {closure@$DIR/overflow-during-mono.rs:14:41: 14:44}: FnMut(&'a _)` +error: reached the recursion limit while instantiating `, _> as Iterator>::try_fold::<(), _, _>` + --> $SRC_DIR/core/src/iter/adapters/filter.rs:LL:COL | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "64"]` attribute to your crate (`overflow_during_mono`) - = note: required for `Filter, {closure@overflow-during-mono.rs:14:41}>` to implement `Iterator` - = note: 31 redundant requirements hidden - = note: required for `Filter, _>, _>, _>, _>, _>` to implement `Iterator` - = note: required for `Filter, _>, _>, _>, _>, _>` to implement `IntoIterator` +note: ` as Iterator>::try_fold` defined here + --> $SRC_DIR/core/src/iter/adapters/filter.rs:LL:COL = note: the full name for the type has been written to '$TEST_BUILD_DIR/overflow-during-mono.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/recursion/infinite-instantiation-via-nested-closures.rs b/tests/ui/recursion/infinite-instantiation-via-nested-closures.rs index 6961d9a4dfde8..33e88427c7e6e 100644 --- a/tests/ui/recursion/infinite-instantiation-via-nested-closures.rs +++ b/tests/ui/recursion/infinite-instantiation-via-nested-closures.rs @@ -2,13 +2,12 @@ //@ build-fail #![allow(unused)] - #![recursion_limit = "20"] #![type_length_limit = "20000000"] #![crate_type = "rlib"] #[derive(Clone)] -struct A (B); +struct A(B); impl A { pub fn matches(&self, f: &F) { @@ -26,34 +25,30 @@ enum B { impl B { pub fn matches(&self, f: &F) { match self { - &B::Variant2(ref factor) => { - factor.matches(&|| ()) - } - _ => unreachable!("") + &B::Variant2(ref factor) => factor.matches(&|| ()), + _ => unreachable!(""), } } } #[derive(Clone)] -struct C (D); +struct C(D); impl C { pub fn matches(&self, f: &F) { let &C(ref base) = self; - base.matches(&|| { - C(base.clone()).matches(f) - }) + base.matches(&|| C(base.clone()).matches(f)) + //~^ ERROR reached the recursion limit while instantiating } } #[derive(Clone)] -struct D (Box); +struct D(Box); impl D { pub fn matches(&self, f: &F) { let &D(ref a) = self; a.matches(f) - //~^ ERROR reached the recursion limit while instantiating } } diff --git a/tests/ui/recursion/infinite-instantiation-via-nested-closures.stderr b/tests/ui/recursion/infinite-instantiation-via-nested-closures.stderr index c4171e23b5917..f691ec2fc48d2 100644 --- a/tests/ui/recursion/infinite-instantiation-via-nested-closures.stderr +++ b/tests/ui/recursion/infinite-instantiation-via-nested-closures.stderr @@ -1,11 +1,11 @@ -error: reached the recursion limit while instantiating `A::matches::<{closure@$DIR/infinite-instantiation-via-nested-closures.rs:43:23: 43:25}>` - --> $DIR/infinite-instantiation-via-nested-closures.rs:55:9 +error: reached the recursion limit while instantiating `D::matches::<{closure@$DIR/infinite-instantiation-via-nested-closures.rs:40:23: 40:25}>` + --> $DIR/infinite-instantiation-via-nested-closures.rs:40:9 | -LL | a.matches(f) - | ^^^^^^^^^^^^ +LL | base.matches(&|| C(base.clone()).matches(f)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: `A::matches` defined here - --> $DIR/infinite-instantiation-via-nested-closures.rs:14:5 +note: `D::matches` defined here + --> $DIR/infinite-instantiation-via-nested-closures.rs:49:5 | LL | pub fn matches(&self, f: &F) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/recursion/issue-83150.rs b/tests/ui/recursion/issue-83150.rs index 9194ce1ab17a8..a8b297640b6f4 100644 --- a/tests/ui/recursion/issue-83150.rs +++ b/tests/ui/recursion/issue-83150.rs @@ -1,4 +1,3 @@ -//~ ERROR overflow evaluating the requirement `Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: Iterator` //@ build-fail //@ compile-flags: -Copt-level=0 -Zwrite-long-types-to-disk=yes @@ -10,4 +9,5 @@ fn main() { fn func>(iter: &mut T) { //~^ WARN function cannot return without recursing func(&mut iter.map(|x| x + 1)) + //~^ ERROR reached the recursion limit while instantiating } diff --git a/tests/ui/recursion/issue-83150.stderr b/tests/ui/recursion/issue-83150.stderr index 9ec187f055018..f0d123584acad 100644 --- a/tests/ui/recursion/issue-83150.stderr +++ b/tests/ui/recursion/issue-83150.stderr @@ -1,5 +1,5 @@ warning: function cannot return without recursing - --> $DIR/issue-83150.rs:10:1 + --> $DIR/issue-83150.rs:9:1 | LL | fn func>(iter: &mut T) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing @@ -10,15 +10,19 @@ LL | func(&mut iter.map(|x| x + 1)) = help: a `loop` may express intention better if this is on purpose = note: `#[warn(unconditional_recursion)]` on by default -error[E0275]: overflow evaluating the requirement `Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: Iterator` +error: reached the recursion limit while instantiating `func::, _>, _>, _>, _>>` + --> $DIR/issue-83150.rs:11:5 | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`) - = note: required for `&mut Map<&mut Range, {closure@issue-83150.rs:12:24}>` to implement `Iterator` - = note: 65 redundant requirements hidden - = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<_, _>, _>, _>, _>, _>` to implement `Iterator` +LL | func(&mut iter.map(|x| x + 1)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: `func` defined here + --> $DIR/issue-83150.rs:9:1 + | +LL | fn func>(iter: &mut T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: the full name for the type has been written to '$TEST_BUILD_DIR/issue-83150.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error; 1 warning emitted -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/recursion/recursive-mono-type-growth-issue-156272.rs b/tests/ui/recursion/recursive-mono-type-growth-issue-156272.rs new file mode 100644 index 0000000000000..4716ad7e43cfb --- /dev/null +++ b/tests/ui/recursion/recursive-mono-type-growth-issue-156272.rs @@ -0,0 +1,22 @@ +//@ build-fail +//@ compile-flags: -Zwrite-long-types-to-disk=yes + +#![allow(dead_code)] + +enum Foo { + Fst, + Snd(Box Foo<(A, A)>>), +} + +fn recursive(x: Foo) { + match x { + Foo::Fst => (), + Foo::Snd(f) => recursive(f()), + //~^ ERROR reached the recursion limit while instantiating + } +} + +fn main() { + let p0: Foo<()> = Foo::Fst; + recursive(p0); +} diff --git a/tests/ui/recursion/recursive-mono-type-growth-issue-156272.stderr b/tests/ui/recursion/recursive-mono-type-growth-issue-156272.stderr new file mode 100644 index 0000000000000..67d5ae35f693b --- /dev/null +++ b/tests/ui/recursion/recursive-mono-type-growth-issue-156272.stderr @@ -0,0 +1,16 @@ +error: reached the recursion limit while instantiating `recursive::<(((((((((((_, _), _), _), _), _), _), _), _), _), _), _)>` + --> $DIR/recursive-mono-type-growth-issue-156272.rs:14:24 + | +LL | Foo::Snd(f) => recursive(f()), + | ^^^^^^^^^^^^^^ + | +note: `recursive` defined here + --> $DIR/recursive-mono-type-growth-issue-156272.rs:11:1 + | +LL | fn recursive(x: Foo) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: the full name for the type has been written to '$TEST_BUILD_DIR/recursive-mono-type-growth-issue-156272.long-type-$LONG_TYPE_HASH.txt' + = note: consider using `--verbose` to print the full type name to the console + +error: aborting due to 1 previous error + diff --git a/tests/ui/traits/issue-91949-hangs-on-recursion.rs b/tests/ui/traits/issue-91949-hangs-on-recursion.rs index 434cf00fc4b4b..cc1adbb8ea7e2 100644 --- a/tests/ui/traits/issue-91949-hangs-on-recursion.rs +++ b/tests/ui/traits/issue-91949-hangs-on-recursion.rs @@ -1,4 +1,3 @@ -//~ ERROR overflow evaluating the requirement ` as Iterator>::Item == ()` //@ build-fail //@ compile-flags: -Zinline-mir=no -Zwrite-long-types-to-disk=yes @@ -24,6 +23,7 @@ where T: Iterator, { recurse(IteratorOfWrapped(elements).map(|t| t.0)) + //~^ ERROR reached the recursion limit while instantiating } fn main() { diff --git a/tests/ui/traits/issue-91949-hangs-on-recursion.stderr b/tests/ui/traits/issue-91949-hangs-on-recursion.stderr index 3eff2944b472f..66cac5a880542 100644 --- a/tests/ui/traits/issue-91949-hangs-on-recursion.stderr +++ b/tests/ui/traits/issue-91949-hangs-on-recursion.stderr @@ -1,5 +1,5 @@ warning: function cannot return without recursing - --> $DIR/issue-91949-hangs-on-recursion.rs:21:1 + --> $DIR/issue-91949-hangs-on-recursion.rs:20:1 | LL | / fn recurse(elements: T) -> Vec LL | | @@ -13,21 +13,22 @@ LL | recurse(IteratorOfWrapped(elements).map(|t| t.0)) = help: a `loop` may express intention better if this is on purpose = note: `#[warn(unconditional_recursion)]` on by default -error[E0275]: overflow evaluating the requirement ` as Iterator>::Item == ()` +error: reached the recursion limit while instantiating `recurse::>, _>>` + --> $DIR/issue-91949-hangs-on-recursion.rs:25:5 | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "512"]` attribute to your crate (`issue_91949_hangs_on_recursion`) -note: required for `IteratorOfWrapped<(), std::iter::Empty<()>>` to implement `Iterator` - --> $DIR/issue-91949-hangs-on-recursion.rs:14:32 +LL | recurse(IteratorOfWrapped(elements).map(|t| t.0)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -LL | impl> Iterator for IteratorOfWrapped { - | -------- ^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | unsatisfied trait bound introduced here - = note: 256 redundant requirements hidden - = note: required for `IteratorOfWrapped<(), Map>, _>>` to implement `Iterator` +note: `recurse` defined here + --> $DIR/issue-91949-hangs-on-recursion.rs:20:1 + | +LL | / fn recurse(elements: T) -> Vec +LL | | +LL | | where +LL | | T: Iterator, + | |___________________________^ = note: the full name for the type has been written to '$TEST_BUILD_DIR/issue-91949-hangs-on-recursion.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error; 1 warning emitted -For more information about this error, try `rustc --explain E0275`. From c09dfb50f04d9a9c4986f2694357eebca5600fd8 Mon Sep 17 00:00:00 2001 From: naganohara-yoshino Date: Tue, 2 Jun 2026 12:00:04 +0800 Subject: [PATCH 3/3] Improve type length check algorithm --- compiler/rustc_monomorphize/src/collector.rs | 42 +++++++++++++------ tests/ui/codegen/overflow-during-mono.rs | 3 +- tests/ui/codegen/overflow-during-mono.stderr | 16 +++++-- ...inite-instantiation-via-nested-closures.rs | 2 +- ...e-instantiation-via-nested-closures.stderr | 12 +++--- 5 files changed, 50 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index d9a4ca2cd0f68..7392af8d58e57 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -357,6 +357,7 @@ fn collect_items_root<'tcx>( starting_item: Spanned>, state: &SharedState<'tcx>, recursion_limit: Limit, + type_length_limit: Limit, ) { if !state.visited.lock().insert(starting_item.node) { // We've been here already, no need to search again. @@ -370,6 +371,7 @@ fn collect_items_root<'tcx>( &mut recursion_depths, recursion_limit, CollectionMode::UsedItems, + type_length_limit, ); } @@ -378,7 +380,10 @@ fn collect_items_root<'tcx>( /// /// `mode` determined whether we are scanning for [used items][CollectionMode::UsedItems] /// or [mentioned items][CollectionMode::MentionedItems]. -#[instrument(skip(tcx, state, recursion_depths, recursion_limit), level = "debug")] +#[instrument( + skip(tcx, state, recursion_depths, recursion_limit, type_length_limit), + level = "debug" +)] fn collect_items_rec<'tcx>( tcx: TyCtxt<'tcx>, starting_item: Spanned>, @@ -386,6 +391,7 @@ fn collect_items_rec<'tcx>( recursion_depths: &mut DefIdMap, recursion_limit: Limit, mode: CollectionMode, + type_length_limit: Limit, ) { let mut used_items = MonoItems::new(); let mut mentioned_items = MonoItems::new(); @@ -463,13 +469,14 @@ fn collect_items_rec<'tcx>( // Sanity check whether this ended up being collected accidentally debug_assert!(tcx.should_codegen_locally(instance)); - // Keep track of the monomorphization recursion depth + // Check for recursive monomorphization before collecting uses recursion_depth_reset = Some(check_recursion_limit( tcx, instance, starting_item.span, recursion_depths, recursion_limit, + type_length_limit, )); rustc_data_structures::stack::ensure_sufficient_stack(|| { @@ -595,6 +602,7 @@ fn collect_items_rec<'tcx>( recursion_depths, recursion_limit, CollectionMode::UsedItems, + type_length_limit, ); } } @@ -609,6 +617,7 @@ fn collect_items_rec<'tcx>( recursion_depths, recursion_limit, CollectionMode::MentionedItems, + type_length_limit, ); } @@ -652,6 +661,7 @@ fn check_recursion_limit<'tcx>( span: Span, recursion_depths: &mut DefIdMap, recursion_limit: Limit, + type_length_limit: Limit, ) -> (DefId, usize) { let def_id = instance.def_id(); let recursion_depth = recursion_depths.get(&def_id).cloned().unwrap_or(0); @@ -665,17 +675,17 @@ fn check_recursion_limit<'tcx>( recursion_depth }; - // Rust code can create exponentially-long types using only a - // polynomial recursion depth. Start checking the type length before - // the depth limit is reached, to avoid hanging on enormous instance - // arguments. - let type_length_check_depth = (recursion_limit / 8).0.max(4); + // Recursive monomorphization can grow instance args exponentially with polynomial + // recursion depth. Start checking type lengths around `ilog2(type_length_limit.0)` + // to avoid hanging on enormous instance arguments. + let type_length_check_depth = type_length_limit.0.checked_ilog2().unwrap_or(0).max(4) as usize; let recursive_type_growth_limit_reached = recursion_depth >= type_length_check_depth - && !tcx.type_length_limit().value_within_limit(type_length(instance.args)); + && !type_length_limit.value_within_limit(type_length(instance.args)); - // Code that needs to instantiate the same function recursively - // more than the recursion limit, or with type arguments that exceed the - // type length limit, is assumed to be causing an infinite expansion. + // Code that needs to instantiate the same function recursively more + // than the recursion limit is assumed to be causing an infinite + // expansion. Bail out earlier if recursive instantiations have already + // produced instance args exceeding the type length limit. if !recursion_limit.value_within_limit(adjusted_recursion_depth) || recursive_type_growth_limit_reached { @@ -1848,9 +1858,17 @@ pub(crate) fn collect_crate_mono_items<'tcx>( }; let recursion_limit = tcx.recursion_limit(); + let type_length_limit = tcx.type_length_limit(); + tcx.sess.time("monomorphization_collector_graph_walk", || { par_for_each_in(roots, |root| { - collect_items_root(tcx, dummy_spanned(*root), &state, recursion_limit); + collect_items_root( + tcx, + dummy_spanned(*root), + &state, + recursion_limit, + type_length_limit, + ); }); }); diff --git a/tests/ui/codegen/overflow-during-mono.rs b/tests/ui/codegen/overflow-during-mono.rs index 96b148dcb5a79..b5447178111f9 100644 --- a/tests/ui/codegen/overflow-during-mono.rs +++ b/tests/ui/codegen/overflow-during-mono.rs @@ -1,8 +1,6 @@ //@ build-fail //@ compile-flags: -Zwrite-long-types-to-disk=yes -//~? ERROR reached the recursion limit while instantiating - #![recursion_limit = "32"] fn quicksort, I: IntoIterator, T: Ord>( @@ -16,6 +14,7 @@ fn quicksort, I: IntoIterator, T: let greater = i.filter(|y| &x <= y); let mut v = quicksort(less); + //~^ ERROR reached the recursion limit while instantiating let u = quicksort(greater); v.push(x); v.extend(u); diff --git a/tests/ui/codegen/overflow-during-mono.stderr b/tests/ui/codegen/overflow-during-mono.stderr index 95acb5e664f28..430acb10e12fc 100644 --- a/tests/ui/codegen/overflow-during-mono.stderr +++ b/tests/ui/codegen/overflow-during-mono.stderr @@ -1,8 +1,16 @@ -error: reached the recursion limit while instantiating `, _> as Iterator>::try_fold::<(), _, _>` - --> $SRC_DIR/core/src/iter/adapters/filter.rs:LL:COL +error: reached the recursion limit while instantiating `quicksort::, _>, _>, _>, _, i32>` + --> $DIR/overflow-during-mono.rs:16:25 | -note: ` as Iterator>::try_fold` defined here - --> $SRC_DIR/core/src/iter/adapters/filter.rs:LL:COL +LL | let mut v = quicksort(less); + | ^^^^^^^^^^^^^^^ + | +note: `quicksort` defined here + --> $DIR/overflow-during-mono.rs:6:1 + | +LL | / fn quicksort, I: IntoIterator, T: Ord>( +LL | | i: I, +LL | | ) -> Vec { + | |___________^ = note: the full name for the type has been written to '$TEST_BUILD_DIR/overflow-during-mono.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/recursion/infinite-instantiation-via-nested-closures.rs b/tests/ui/recursion/infinite-instantiation-via-nested-closures.rs index 33e88427c7e6e..db78f48a1e677 100644 --- a/tests/ui/recursion/infinite-instantiation-via-nested-closures.rs +++ b/tests/ui/recursion/infinite-instantiation-via-nested-closures.rs @@ -38,7 +38,6 @@ impl C { pub fn matches(&self, f: &F) { let &C(ref base) = self; base.matches(&|| C(base.clone()).matches(f)) - //~^ ERROR reached the recursion limit while instantiating } } @@ -49,6 +48,7 @@ impl D { pub fn matches(&self, f: &F) { let &D(ref a) = self; a.matches(f) + //~^ ERROR reached the recursion limit while instantiating } } diff --git a/tests/ui/recursion/infinite-instantiation-via-nested-closures.stderr b/tests/ui/recursion/infinite-instantiation-via-nested-closures.stderr index f691ec2fc48d2..9ee3b07510e74 100644 --- a/tests/ui/recursion/infinite-instantiation-via-nested-closures.stderr +++ b/tests/ui/recursion/infinite-instantiation-via-nested-closures.stderr @@ -1,11 +1,11 @@ -error: reached the recursion limit while instantiating `D::matches::<{closure@$DIR/infinite-instantiation-via-nested-closures.rs:40:23: 40:25}>` - --> $DIR/infinite-instantiation-via-nested-closures.rs:40:9 +error: reached the recursion limit while instantiating `A::matches::<{closure@$DIR/infinite-instantiation-via-nested-closures.rs:40:23: 40:25}>` + --> $DIR/infinite-instantiation-via-nested-closures.rs:50:9 | -LL | base.matches(&|| C(base.clone()).matches(f)) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | a.matches(f) + | ^^^^^^^^^^^^ | -note: `D::matches` defined here - --> $DIR/infinite-instantiation-via-nested-closures.rs:49:5 +note: `A::matches` defined here + --> $DIR/infinite-instantiation-via-nested-closures.rs:13:5 | LL | pub fn matches(&self, f: &F) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^