diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 6a836442c3295..423d914cc0dd8 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -473,6 +473,33 @@ fn collect_items_rec<'tcx>( recursion_limit, )); + // Check whether the MIR body is malformed. Usually it's due to normalization overflow. + // FIXME: I assume that there are few type errors at post-analysis stage, but not + // entirely sure. + // Plenty of code paths later assume that everything can be normalized. + // Check normalization here to provide better diagnostics. + let body = tcx.instance_mir(instance.def); + let normalization_failed = body.local_decls.iter().any(|local| { + instance + .try_instantiate_mir_and_normalize_erasing_regions( + tcx, + ty::TypingEnv::fully_monomorphized(), + ty::EarlyBinder::bind(local.ty), + ) + .is_err() + }); + if normalization_failed { + let def_id = instance.def_id(); + let def_span = tcx.def_span(def_id); + let def_path_str = tcx.def_path_str(def_id); + tcx.dcx().emit_fatal(RecursionLimit { + span: starting_item.span, + instance, + def_span, + def_path_str, + }); + } + rustc_data_structures::stack::ensure_sufficient_stack(|| { let (used, mentioned) = tcx.items_of_instance((instance, mode)); used_items.extend(used.into_iter().copied()); diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index c1b848a2e79da..b93b6503290b9 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -42,7 +42,18 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable> + Par // us a test case. debug_assert_eq!(normalized_value, resolved_value); let erased = infcx.tcx.erase_regions(resolved_value); - debug_assert!(!erased.has_infer(), "{erased:?}"); + if infcx.next_trait_solver() { + debug_assert!(!erased.has_infer(), "{erased:?}"); + } else { + // The old solver returns an ty var with the failed obligation in case of + // selection error. And when the obligation is re-tried, the error should be + // reported. However in case of overflow error, the obligation may be fulfilled + // due to the original depth being dropped. + // In conclusion, overflow results in an unconstrained ty var. + if erased.has_infer() { + return Err(NoSolution); + } + } Ok(erased) } Err(NoSolution) => Err(NoSolution), diff --git a/tests/crashes/105275.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-105275.rs similarity index 97% rename from tests/crashes/105275.rs rename to tests/ui/codegen/normalization-overflow/recursion-issue-105275.rs index a97f36d19872c..6a9599618a927 100644 --- a/tests/crashes/105275.rs +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-105275.rs @@ -1,3 +1,4 @@ +//@ build-fail //@ known-bug: #105275 //@ compile-flags: -Copt-level=0 diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-105275.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-105275.stderr new file mode 100644 index 0000000000000..41509f06d68de --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-105275.stderr @@ -0,0 +1,14 @@ +error: reached the recursion limit while instantiating `encode_num::<&mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut Error>` + --> $DIR/recursion-issue-105275.rs:7:9 + | +LL | encode_num(n / 16, &mut writer)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: `encode_num` defined here + --> $DIR/recursion-issue-105275.rs:5:1 + | +LL | pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/crashes/105937.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-105937.rs similarity index 97% rename from tests/crashes/105937.rs rename to tests/ui/codegen/normalization-overflow/recursion-issue-105937.rs index ffd1a493e46d5..861e7a2da3d19 100644 --- a/tests/crashes/105937.rs +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-105937.rs @@ -1,3 +1,4 @@ +//@ build-fail //@ known-bug: #105937 //@ compile-flags: -Copt-level=0 diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-105937.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-105937.stderr new file mode 100644 index 0000000000000..27a491c37ac5b --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-105937.stderr @@ -0,0 +1,14 @@ +error: reached the recursion limit while instantiating `encode_num::<&mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut Error>` + --> $DIR/recursion-issue-105937.rs:7:9 + | +LL | encode_num(n / 16, &mut writer)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: `encode_num` defined here + --> $DIR/recursion-issue-105937.rs:5:1 + | +LL | pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/crashes/117696-2.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-117696-2.rs similarity index 93% rename from tests/crashes/117696-2.rs rename to tests/ui/codegen/normalization-overflow/recursion-issue-117696-2.rs index 9c2a68d3a915c..c64792adc60cb 100644 --- a/tests/crashes/117696-2.rs +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-117696-2.rs @@ -1,3 +1,4 @@ +//@ build-fail //@ known-bug: #117696 //@ compile-flags: -Copt-level=0 fn main() { diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-117696-2.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-117696-2.stderr new file mode 100644 index 0000000000000..0e3696f3259fc --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-117696-2.stderr @@ -0,0 +1,14 @@ +error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut std::option::IntoIter<()>>` + --> $DIR/recursion-issue-117696-2.rs:12:9 + | +LL | rec(&mut it); + | ^^^^^^^^^^^^ + | +note: `rec` defined here + --> $DIR/recursion-issue-117696-2.rs:8:1 + | +LL | fn rec(mut it: T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/crashes/118590.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-118590.rs similarity index 92% rename from tests/crashes/118590.rs rename to tests/ui/codegen/normalization-overflow/recursion-issue-118590.rs index 829c16582dc92..d5332f8a39348 100644 --- a/tests/crashes/118590.rs +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-118590.rs @@ -1,3 +1,4 @@ +//@ build-fail //@ known-bug: #118590 fn main() { diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-118590.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-118590.stderr new file mode 100644 index 0000000000000..943586cadd832 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-118590.stderr @@ -0,0 +1,11 @@ +error: reached the recursion limit while instantiating `>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as Iterator>::peekable` + --> $DIR/recursion-issue-118590.rs:11:13 + | +LL | recurse(nums.skip(42).peekable()) + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: `peekable` defined here + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to 1 previous error + diff --git a/tests/crashes/122823.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-122823.rs similarity index 99% rename from tests/crashes/122823.rs rename to tests/ui/codegen/normalization-overflow/recursion-issue-122823.rs index ec22b331ad929..f59a716ebc2c2 100644 --- a/tests/crashes/122823.rs +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-122823.rs @@ -1,3 +1,4 @@ +//@ build-fail //@ known-bug: #122823 //@ compile-flags: -Copt-level=0 // ignore-tidy-linelength diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-122823.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-122823.stderr new file mode 100644 index 0000000000000..38d4916e6a645 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-122823.stderr @@ -0,0 +1,11 @@ +error: reached the recursion limit while instantiating `>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as Iterator>::peekable` + --> $DIR/recursion-issue-122823.rs:44:38 + | +LL | packets: decode_packets(&mut itr.take(0).peekable()), + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: `peekable` defined here + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to 1 previous error + diff --git a/tests/crashes/131342.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-131342.rs similarity index 95% rename from tests/crashes/131342.rs rename to tests/ui/codegen/normalization-overflow/recursion-issue-131342.rs index f4404092917a4..61ca6063eca76 100644 --- a/tests/crashes/131342.rs +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-131342.rs @@ -1,3 +1,4 @@ +//@ build-fail //@ known-bug: #131342 fn main() { diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-131342.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-131342.stderr new file mode 100644 index 0000000000000..fbfd1cf56d5de --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-131342.stderr @@ -0,0 +1,11 @@ +error: reached the recursion limit while instantiating `<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut std::vec::IntoIter>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as Iterator>::peekable` + --> $DIR/recursion-issue-131342.rs:10:22 + | +LL | let mut peeker = items.peekable(); + | ^^^^^^^^^^^^^^^^ + | +note: `peekable` defined here + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to 1 previous error + diff --git a/tests/crashes/139659.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-139659.rs similarity index 97% rename from tests/crashes/139659.rs rename to tests/ui/codegen/normalization-overflow/recursion-issue-139659.rs index 7fc33f7e6a7cf..9ea4dea2dbae8 100644 --- a/tests/crashes/139659.rs +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-139659.rs @@ -1,3 +1,4 @@ +//@ build-fail //@ known-bug: #139659 //@compile-flags: -Cdebuginfo=2 -Copt-level=0 --crate-type lib trait Trait { diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-139659.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-139659.stderr new file mode 100644 index 0000000000000..5e1e4fe18f842 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-139659.stderr @@ -0,0 +1,10 @@ +error: reached the recursion limit while instantiating `recurse` + | +note: `recurse` defined here + --> $DIR/recursion-issue-139659.rs:27:1 + | +LL | pub fn recurse() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/crashes/92004.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-92004.rs similarity index 99% rename from tests/crashes/92004.rs rename to tests/ui/codegen/normalization-overflow/recursion-issue-92004.rs index bc2ca2a7ba389..fd0ee8c3a0d84 100644 --- a/tests/crashes/92004.rs +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-92004.rs @@ -1,3 +1,4 @@ +//@ build-fail //@ known-bug: #102310 //@ compile-flags: -Copt-level=0 //@ edition:2021 diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-92004.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-92004.stderr new file mode 100644 index 0000000000000..49e48f28a8786 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-92004.stderr @@ -0,0 +1,11 @@ +error: reached the recursion limit while instantiating `>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as Iterator>::peekable` + --> $DIR/recursion-issue-92004.rs:45:38 + | +LL | packets: decode_packets(&mut itr.take(0).peekable()), + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: `peekable` defined here + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to 1 previous error + diff --git a/tests/crashes/92470.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-92470.rs similarity index 96% rename from tests/crashes/92470.rs rename to tests/ui/codegen/normalization-overflow/recursion-issue-92470.rs index a3c518f5ec62f..19ce821b2b1c4 100644 --- a/tests/crashes/92470.rs +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-92470.rs @@ -1,3 +1,4 @@ +//@ build-fail //@ known-bug: #92470 fn main() { encode(&mut EncoderImpl); diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-92470.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-92470.stderr new file mode 100644 index 0000000000000..198ab33d0a719 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-92470.stderr @@ -0,0 +1,26 @@ +warning: function cannot return without recursing + --> $DIR/recursion-issue-92470.rs:13:1 + | +LL | fn encode(mut encoder: E) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing +LL | encoder.writer(); +LL | encode(&mut encoder); + | -------------------- recursive call site + | + = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default + +error: reached the recursion limit while instantiating `encode::<&mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut EncoderImpl>` + --> $DIR/recursion-issue-92470.rs:15:5 + | +LL | encode(&mut encoder); + | ^^^^^^^^^^^^^^^^^^^^ + | +note: `encode` defined here + --> $DIR/recursion-issue-92470.rs:13:1 + | +LL | fn encode(mut encoder: E) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/crashes/95134.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-95134.rs similarity index 97% rename from tests/crashes/95134.rs rename to tests/ui/codegen/normalization-overflow/recursion-issue-95134.rs index bcd88b1076fd9..1537073a7f8e4 100644 --- a/tests/crashes/95134.rs +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-95134.rs @@ -1,3 +1,4 @@ +//@ build-fail //@ known-bug: #95134 //@ compile-flags: -Copt-level=0 diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-95134.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-95134.stderr new file mode 100644 index 0000000000000..4f9fc8f10d8b4 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-95134.stderr @@ -0,0 +1,14 @@ +error: reached the recursion limit while instantiating `encode_num::<&mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut EmptyWriter>` + --> $DIR/recursion-issue-95134.rs:7:9 + | +LL | encode_num(n / 16, &mut writer)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: `encode_num` defined here + --> $DIR/recursion-issue-95134.rs:5:1 + | +LL | pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error +