about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-04-08 20:54:58 +1000
committerGitHub <noreply@github.com>2025-04-08 20:54:58 +1000
commit2b1afcbd1accd9e73c94029d3c420fa26b29676c (patch)
tree57f0355d037f6fea9e3581e6ff9acaa80ee97d1b /compiler
parentc6c179662d5a6fc0520e05b5c0682dcfc7333f77 (diff)
parent268c56e14455d8889b818c4ea55470b94649aebc (diff)
downloadrust-2b1afcbd1accd9e73c94029d3c420fa26b29676c.tar.gz
rust-2b1afcbd1accd9e73c94029d3c420fa26b29676c.zip
Rollup merge of #138676 - compiler-errors:overflow-implied-bounds, r=lcnr
Implement overflow for infinite implied lifetime bounds

Not a great error message, but better than a hang

Fixes #138665
Fixes #102966
Fixes #115407

r? lcnr
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs21
1 files changed, 17 insertions, 4 deletions
diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
index a0faa5e8429..780c27d4595 100644
--- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
@@ -24,8 +24,8 @@ pub(super) fn infer_predicates(
 
     // If new predicates were added then we need to re-calculate
     // all crates since there could be new implied predicates.
-    loop {
-        let mut predicates_added = false;
+    for i in 0.. {
+        let mut predicates_added = vec![];
 
         // Visit all the crates and infer predicates
         for id in tcx.hir_free_items() {
@@ -83,14 +83,27 @@ pub(super) fn infer_predicates(
                 .get(&item_did.to_def_id())
                 .map_or(0, |p| p.as_ref().skip_binder().len());
             if item_required_predicates.len() > item_predicates_len {
-                predicates_added = true;
+                predicates_added.push(item_did);
                 global_inferred_outlives
                     .insert(item_did.to_def_id(), ty::EarlyBinder::bind(item_required_predicates));
             }
         }
 
-        if !predicates_added {
+        if predicates_added.is_empty() {
+            // We've reached a fixed point.
             break;
+        } else if !tcx.recursion_limit().value_within_limit(i) {
+            let msg = if let &[id] = &predicates_added[..] {
+                format!("overflow computing implied lifetime bounds for `{}`", tcx.def_path_str(id),)
+            } else {
+                "overflow computing implied lifetime bounds".to_string()
+            };
+            tcx.dcx()
+                .struct_span_fatal(
+                    predicates_added.iter().map(|id| tcx.def_span(*id)).collect::<Vec<_>>(),
+                    msg,
+                )
+                .emit();
         }
     }