Skip to content

Commit fb35892

Browse files
Auto merge of #146096 - adwinwhite:handle_normalization_overflow_in_mono1, r=<try>
Fix normalization overflow ICEs in monomorphization
2 parents 05abce5 + 56db0a0 commit fb35892

22 files changed

+185
-1
lines changed

compiler/rustc_monomorphize/src/collector.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,33 @@ fn collect_items_rec<'tcx>(
473473
recursion_limit,
474474
));
475475

476+
// Check whether the MIR body is malformed. Usually it's due to normalization overflow.
477+
// FIXME: I assume that there are few type errors at post-analysis stage, but not
478+
// entirely sure.
479+
// Plenty of code paths later assume that everything can be normalized.
480+
// Check normalization here to provide better diagnostics.
481+
let body = tcx.instance_mir(instance.def);
482+
let normalization_failed = body.local_decls.iter().any(|local| {
483+
instance
484+
.try_instantiate_mir_and_normalize_erasing_regions(
485+
tcx,
486+
ty::TypingEnv::fully_monomorphized(),
487+
ty::EarlyBinder::bind(local.ty),
488+
)
489+
.is_err()
490+
});
491+
if normalization_failed {
492+
let def_id = instance.def_id();
493+
let def_span = tcx.def_span(def_id);
494+
let def_path_str = tcx.def_path_str(def_id);
495+
tcx.dcx().emit_fatal(RecursionLimit {
496+
span: starting_item.span,
497+
instance,
498+
def_span,
499+
def_path_str,
500+
});
501+
}
502+
476503
rustc_data_structures::stack::ensure_sufficient_stack(|| {
477504
let (used, mentioned) = tcx.items_of_instance((instance, mode));
478505
used_items.extend(used.into_iter().copied());

compiler/rustc_traits/src/normalize_erasing_regions.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,18 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<TyCtxt<'tcx>> + Par
4242
// us a test case.
4343
debug_assert_eq!(normalized_value, resolved_value);
4444
let erased = infcx.tcx.erase_regions(resolved_value);
45-
debug_assert!(!erased.has_infer(), "{erased:?}");
45+
if infcx.next_trait_solver() {
46+
debug_assert!(!erased.has_infer(), "{erased:?}");
47+
} else {
48+
// The old solver returns an ty var with the failed obligation in case of
49+
// selection error. And when the obligation is re-tried, the error should be
50+
// reported. However in case of overflow error, the obligation may be fulfilled
51+
// due to the original depth being dropped.
52+
// In conclusion, overflow results in an unconstrained ty var.
53+
if erased.has_infer() {
54+
return Err(NoSolution);
55+
}
56+
}
4657
Ok(erased)
4758
}
4859
Err(NoSolution) => Err(NoSolution),

tests/crashes/105275.rs renamed to tests/ui/codegen/normalization-overflow/recursion-issue-105275.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//@ build-fail
12
//@ known-bug: #105275
23
//@ compile-flags: -Copt-level=0
34

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
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>`
2+
--> $DIR/recursion-issue-105275.rs:7:9
3+
|
4+
LL | encode_num(n / 16, &mut writer)?;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: `encode_num` defined here
8+
--> $DIR/recursion-issue-105275.rs:5:1
9+
|
10+
LL | pub fn encode_num<Writer: ExampleWriter>(n: u32, mut writer: Writer) -> Result<(), Writer::Error> {
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 1 previous error
14+

tests/crashes/105937.rs renamed to tests/ui/codegen/normalization-overflow/recursion-issue-105937.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//@ build-fail
12
//@ known-bug: #105937
23
//@ compile-flags: -Copt-level=0
34

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
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>`
2+
--> $DIR/recursion-issue-105937.rs:7:9
3+
|
4+
LL | encode_num(n / 16, &mut writer)?;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: `encode_num` defined here
8+
--> $DIR/recursion-issue-105937.rs:5:1
9+
|
10+
LL | pub fn encode_num<Writer: ExampleWriter>(n: u32, mut writer: Writer) -> Result<(), Writer::Error> {
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 1 previous error
14+

tests/crashes/117696-2.rs renamed to tests/ui/codegen/normalization-overflow/recursion-issue-117696-2.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//@ build-fail
12
//@ known-bug: #117696
23
//@ compile-flags: -Copt-level=0
34
fn main() {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
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<()>>`
2+
--> $DIR/recursion-issue-117696-2.rs:12:9
3+
|
4+
LL | rec(&mut it);
5+
| ^^^^^^^^^^^^
6+
|
7+
note: `rec` defined here
8+
--> $DIR/recursion-issue-117696-2.rs:8:1
9+
|
10+
LL | fn rec<T: Iterator>(mut it: T) {
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 1 previous error
14+

tests/crashes/118590.rs renamed to tests/ui/codegen/normalization-overflow/recursion-issue-118590.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//@ build-fail
12
//@ known-bug: #118590
23

34
fn main() {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: reached the recursion limit while instantiating `<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<Peekable<Skip<std::iter::Empty<()>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as Iterator>::peekable`
2+
--> $DIR/recursion-issue-118590.rs:11:13
3+
|
4+
LL | recurse(nums.skip(42).peekable())
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: `peekable` defined here
8+
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
9+
10+
error: aborting due to 1 previous error
11+

0 commit comments

Comments
 (0)