about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2024-09-20 19:46:40 +0200
committerGitHub <noreply@github.com>2024-09-20 19:46:40 +0200
commit7adf4c2b6f8246d29abe3617f2d9d875ce91e9cc (patch)
tree0d46bc00c69f22c7730c971fb293bb100c5b3c98
parentdf2b730e01f5fa6f7f27b0a6761457f91b4778d3 (diff)
parenta6aeba83beac8173bcc1eb819441e9bdc54d0561 (diff)
downloadrust-7adf4c2b6f8246d29abe3617f2d9d875ce91e9cc.tar.gz
rust-7adf4c2b6f8246d29abe3617f2d9d875ce91e9cc.zip
Rollup merge of #130617 - lcnr:nalgebra-hang-3, r=compiler-errors
bail if there are too many non-region infer vars in the query response

A minimal fix for the hang in nalgebra. If the query response would result in too many distinct non-region inference variables, simply overwrite the result with overflow. This should either happen if the result already has too many distinct type inference variables, or if evaluating the query encountered a lot of ambiguous associated types. In both cases it's straightforward to wait until the aliases are no longer ambiguous and then try again.

r? `@compiler-errors`
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs11
-rw-r--r--tests/ui/traits/coherence-alias-hang.rs2
-rw-r--r--tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr1
-rw-r--r--tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs3
-rw-r--r--tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr11
5 files changed, 27 insertions, 1 deletions
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
index 5acfec3dee3..4d743c05190 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
@@ -157,6 +157,17 @@ where
             },
         );
 
+        // HACK: We bail with overflow if the response would have too many non-region
+        // inference variables. This tends to only happen if we encounter a lot of
+        // ambiguous alias types which get replaced with fresh inference variables
+        // during generalization. This prevents a hang in nalgebra.
+        let num_non_region_vars = canonical.variables.iter().filter(|c| !c.is_region()).count();
+        if num_non_region_vars > self.cx().recursion_limit() {
+            return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow {
+                suggest_increasing_limit: true,
+            }));
+        }
+
         Ok(canonical)
     }
 
diff --git a/tests/ui/traits/coherence-alias-hang.rs b/tests/ui/traits/coherence-alias-hang.rs
index 37b80739589..c2b4d2e42d2 100644
--- a/tests/ui/traits/coherence-alias-hang.rs
+++ b/tests/ui/traits/coherence-alias-hang.rs
@@ -1,4 +1,6 @@
 //@ check-pass
+//@ revisions: current next
+//[next]@ compile-flags: -Znext-solver
 
 // Regression test for nalgebra hang <https://github.com/rust-lang/rust/issues/130056>.
 
diff --git a/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
index 8d7d8cee08a..150100f2c53 100644
--- a/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
+++ b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
@@ -4,6 +4,7 @@ error[E0275]: overflow evaluating the requirement `W<_>: Trait`
 LL |     impls::<W<_>>();
    |             ^^^^
    |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`fixpoint_exponential_growth`)
 note: required by a bound in `impls`
   --> $DIR/fixpoint-exponential-growth.rs:30:13
    |
diff --git a/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs
index 1b80287d9da..86d428cc0f0 100644
--- a/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs
+++ b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs
@@ -1,6 +1,7 @@
+//~ ERROR overflow evaluating the requirement `Self: Trait`
+//~^ ERROR overflow evaluating the requirement `Self well-formed`
 // This is a non-regression test for issue #115351, where a recursion limit of 0 caused an ICE.
 //@ compile-flags: -Znext-solver --crate-type=lib
-//@ check-pass
 
 #![recursion_limit = "0"]
 trait Trait {}
diff --git a/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr
new file mode 100644
index 00000000000..2eed7e8f723
--- /dev/null
+++ b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr
@@ -0,0 +1,11 @@
+error[E0275]: overflow evaluating the requirement `Self: Trait`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
+
+error[E0275]: overflow evaluating the requirement `Self well-formed`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0275`.