From 622fd6a3f80ff4398db552ed138243c845347298 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 22 Sep 2026 13:46:48 +0200 Subject: [PATCH] treat inductive cycles as ambig --- .../src/solve/eval_ctxt/mod.rs | 5 ++- .../src/solve/search_graph.rs | 34 +++++++------------ .../placeholder-assumptions-issue-157840.rs | 2 +- ...laceholder-assumptions-issue-157840.stderr | 11 ++---- ...aram-recursion-issue-152716.current.stderr | 15 ++++++++ ...d-param-recursion-issue-152716.next.stderr | 9 +++++ .../find-param-recursion-issue-152716.rs | 7 ++-- .../find-param-recursion-issue-152716.stderr | 14 -------- ...ursive-self-normalization-2.current.stderr | 9 +++++ ...recursive-self-normalization-2.next.stderr | 15 ++++++++ .../recursive-self-normalization-2.rs | 7 ++-- .../recursive-self-normalization-2.stderr | 19 ----------- ...e-self-normalization-simple.current.stderr | 9 +++++ ...sive-self-normalization-simple.next.stderr | 9 +++++ .../recursive-self-normalization-simple.rs | 19 +++++++++++ ...ecursive-self-normalization.current.stderr | 9 +++++ .../recursive-self-normalization.next.stderr | 9 +++++ .../overflow/recursive-self-normalization.rs | 6 ++-- .../recursive-self-normalization.stderr | 19 ----------- 19 files changed, 138 insertions(+), 89 deletions(-) create mode 100644 tests/ui/traits/next-solver/find-param-recursion-issue-152716.current.stderr create mode 100644 tests/ui/traits/next-solver/find-param-recursion-issue-152716.next.stderr delete mode 100644 tests/ui/traits/next-solver/find-param-recursion-issue-152716.stderr create mode 100644 tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.current.stderr create mode 100644 tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.next.stderr delete mode 100644 tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr create mode 100644 tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.current.stderr create mode 100644 tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.next.stderr create mode 100644 tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.rs create mode 100644 tests/ui/traits/next-solver/overflow/recursive-self-normalization.current.stderr create mode 100644 tests/ui/traits/next-solver/overflow/recursive-self-normalization.next.stderr delete mode 100644 tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 3a4875c1d0951..e5b8c8759f9bc 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -460,7 +460,10 @@ where // Relating types is always unproductive. If we were to map proof trees to // corecursive functions as explained in #136824, relating types never // introduces a constructor which could cause the recursion to be guarded. - GoalSource::TypeRelating => PathKind::Inductive, + // + // FIXME(-Znext-solver=coinductive): For now we treat all inductive cycles as + // `Unknown`. See the comment in `fn initial_provisional_result`. + GoalSource::TypeRelating => PathKind::Unknown, // These goal sources are likely unproductive and can be changed to // `PathKind::Inductive`. Keeping them as unknown until we're confident // about this and have an example where it is necessary. diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs index e147a139a65e1..ecd175d694d7d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs +++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs @@ -1,9 +1,9 @@ use std::convert::Infallible; use std::marker::PhantomData; +use rustc_type_ir::Interner; use rustc_type_ir::search_graph::{self, PathKind}; use rustc_type_ir::solve::{AccessedOpaques, Certainty, NoSolution, QueryResult, RerunResultExt}; -use rustc_type_ir::{Interner, MayBeErased, TypingMode}; use crate::canonical::response_no_constraints_raw; use crate::delegate::SolverDelegate; @@ -52,29 +52,21 @@ where PathKind::Unknown | PathKind::ForcedAmbiguity => { response_no_constraints(cx, input, Certainty::overflow(false)) } - // Even though we know these cycles to be unproductive, we still return - // overflow during coherence. This is both as we are not 100% confident in - // the implementation yet and any incorrect errors would be unsound there. + // Even though we know some cycles to be unproductive, we still treat them + // as unknown for now. This is both as we are not 100% confident in the + // implementation yet and any incorrect errors would be unsound there. + // // The affected cases are also fairly artificial and not necessarily desirable // so keeping this as ambiguity is fine for now. // - // See `tests/ui/traits/next-solver/cycles/unproductive-in-coherence.rs` for an - // example where this would matter. We likely should change these cycles to `NoSolution` - // even in coherence once this is a bit more settled. - PathKind::Inductive => match input.typing_mode.0 { - TypingMode::Coherence => { - response_no_constraints(cx, input, Certainty::overflow(false)) - } - TypingMode::Typeck { .. } - | TypingMode::PostTypeckUntilBorrowck { .. } - | TypingMode::Reflection - | TypingMode::PostBorrowck { .. } - | TypingMode::PostAnalysis - | TypingMode::Codegen - | TypingMode::ErasedNotCoherence(MayBeErased) => { - (Err(NoSolution), AccessedOpaques::default()) - } - }, + // See `tests/ui/traits/next-solver/cycles/unproductive-in-coherence.rs` and + // `tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.rs` + // for examples where this would matter. + // + // FIXME(-Znext-solver=coinductive): Long term, we probably do want to + // return `NoSolution` here. This should happen separately from the + // stabilization of the new solver. + PathKind::Inductive => unreachable!(), } } diff --git a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs index f449e02baadb8..8b0b92b8a7842 100644 --- a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs +++ b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs @@ -10,7 +10,7 @@ fn foo<'a, T>() where T: Proj<'a, Assoc = fn(::Assoc)>, (): Trait<>::Assoc>, - //~^ ERROR the trait bound `(): Trait fn(>::Assoc))>` is not satisfied + //~^ ERROR overflow evaluating the requirement `(): Trait<>::Assoc>` { } diff --git a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.stderr b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.stderr index 5e8e131addd28..9d1c8c4a10d02 100644 --- a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.stderr +++ b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.stderr @@ -1,14 +1,9 @@ -error[E0277]: the trait bound `(): Trait fn(>::Assoc))>` is not satisfied +error[E0275]: overflow evaluating the requirement `(): Trait<>::Assoc>` --> $DIR/placeholder-assumptions-issue-157840.rs:12:9 | LL | (): Trait<>::Assoc>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait fn(>::Assoc))>` is not implemented for `()` - | -help: consider extending the `where` clause, but there might be an alternative better way to express this requirement - | -LL | (): Trait<>::Assoc>, (): Trait fn(>::Assoc))> - | +++++++++++++++++++++++++++++++++++++++++++++++++ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/find-param-recursion-issue-152716.current.stderr b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.current.stderr new file mode 100644 index 0000000000000..2c9694cdd419a --- /dev/null +++ b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.current.stderr @@ -0,0 +1,15 @@ +error[E0275]: overflow evaluating the requirement `for<'b> T: Proj<'b>` + --> $DIR/find-param-recursion-issue-152716.rs:15:1 + | +LL | / fn foo() +LL | | +LL | | where +LL | | T: for<'a> Proj<'a, Assoc = for<'b> fn(>::Assoc)>, +LL | | (): Trait<>::Assoc> + | |__________________________________________^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`find_param_recursion_issue_152716`) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/find-param-recursion-issue-152716.next.stderr b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.next.stderr new file mode 100644 index 0000000000000..c722813ddd663 --- /dev/null +++ b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.next.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `(): Trait<>::Assoc>` + --> $DIR/find-param-recursion-issue-152716.rs:19:9 + | +LL | (): Trait<>::Assoc> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/find-param-recursion-issue-152716.rs b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.rs index 4d088073c3ba6..fb1ac0d8d0298 100644 --- a/tests/ui/traits/next-solver/find-param-recursion-issue-152716.rs +++ b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.rs @@ -1,4 +1,6 @@ -//@ compile-flags: -Znext-solver +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver // Regression test for . // @@ -11,10 +13,11 @@ trait Proj<'a> { type Assoc; } fn foo() +//[current]~^ ERROR: overflow evaluating the requirement `for<'b> T: Proj<'b>` where T: for<'a> Proj<'a, Assoc = for<'b> fn(>::Assoc)>, (): Trait<>::Assoc> - //~^ ERROR: the trait bound `(): Trait fn(>::Assoc))>` is not satisfied + //[next]~^ ERROR: overflow evaluating the requirement `(): Trait<>::Assoc>` { } diff --git a/tests/ui/traits/next-solver/find-param-recursion-issue-152716.stderr b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.stderr deleted file mode 100644 index 1408890184a90..0000000000000 --- a/tests/ui/traits/next-solver/find-param-recursion-issue-152716.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0277]: the trait bound `(): Trait fn(>::Assoc))>` is not satisfied - --> $DIR/find-param-recursion-issue-152716.rs:16:9 - | -LL | (): Trait<>::Assoc> - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait fn(>::Assoc))>` is not implemented for `()` - | -help: consider extending the `where` clause, but there might be an alternative better way to express this requirement - | -LL | (): Trait<>::Assoc>, (): Trait fn(>::Assoc))> - | +++++++++++++++++++++++++++++++++++++++++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.current.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.current.stderr new file mode 100644 index 0000000000000..230871107a6cf --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.current.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `::Assoc1 == _` + --> $DIR/recursive-self-normalization-2.rs:16:1 + | +LL | fn test::Assoc2> + Foo2::Assoc1>>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.next.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.next.stderr new file mode 100644 index 0000000000000..ea8b5cd51a309 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.next.stderr @@ -0,0 +1,15 @@ +error[E0275]: overflow evaluating the requirement `::Assoc1 == _` + --> $DIR/recursive-self-normalization-2.rs:16:1 + | +LL | fn test::Assoc2> + Foo2::Assoc1>>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0275]: overflow evaluating the requirement `::Assoc2 == _` + --> $DIR/recursive-self-normalization-2.rs:16:1 + | +LL | fn test::Assoc2> + Foo2::Assoc1>>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs index 8dc27c0da605a..0e08a6b4d7e03 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs @@ -1,4 +1,6 @@ -//@ compile-flags: -Znext-solver +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver trait Foo1 { type Assoc1; @@ -12,8 +14,9 @@ trait Bar {} fn needs_bar() {} fn test::Assoc2> + Foo2::Assoc1>>() { + //~^ ERROR overflow evaluating the requirement `::Assoc1 == _` + //[next]~| ERROR overflow evaluating the requirement `::Assoc2 == _` needs_bar::(); - //~^ ERROR: the trait bound `::Assoc1: Bar` is not satisfied } fn main() {} diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr deleted file mode 100644 index 6f5111a6193ca..0000000000000 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0277]: the trait bound `::Assoc1: Bar` is not satisfied - --> $DIR/recursive-self-normalization-2.rs:15:17 - | -LL | needs_bar::(); - | ^^^^^^^^^ the trait `Bar` is not implemented for `::Assoc1` - | -note: required by a bound in `needs_bar` - --> $DIR/recursive-self-normalization-2.rs:12:17 - | -LL | fn needs_bar() {} - | ^^^ required by this bound in `needs_bar` -help: consider further restricting the associated type - | -LL | fn test::Assoc2> + Foo2::Assoc1>>() where ::Assoc1: Bar { - | ++++++++++++++++++++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.current.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.current.stderr new file mode 100644 index 0000000000000..4b9be86b9e5a5 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.current.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `::Assoc == _` + --> $DIR/recursive-self-normalization-simple.rs:15:1 + | +LL | fn test::Assoc>>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.next.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.next.stderr new file mode 100644 index 0000000000000..4b9be86b9e5a5 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.next.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `::Assoc == _` + --> $DIR/recursive-self-normalization-simple.rs:15:1 + | +LL | fn test::Assoc>>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.rs new file mode 100644 index 0000000000000..b511dc4a732e3 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.rs @@ -0,0 +1,19 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// A variant of `recursive-self-normalization.rs` which passes if +// we treat inductive cycles as `NoSolution` in the trait solver. + +trait Foo { + type Assoc; +} + +trait Bar {} +fn needs_bar() {} + +fn test::Assoc>>() { + //~^ ERROR overflow evaluating the requirement `::Assoc == _` +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.current.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.current.stderr new file mode 100644 index 0000000000000..6569be7347911 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.current.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `::Assoc == _` + --> $DIR/recursive-self-normalization.rs:12:1 + | +LL | fn test::Assoc>>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.next.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.next.stderr new file mode 100644 index 0000000000000..6569be7347911 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.next.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `::Assoc == _` + --> $DIR/recursive-self-normalization.rs:12:1 + | +LL | fn test::Assoc>>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs index f441ac499f99c..a25d028bd1b52 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs @@ -1,4 +1,6 @@ -//@ compile-flags: -Znext-solver +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver trait Foo { type Assoc; @@ -8,8 +10,8 @@ trait Bar {} fn needs_bar() {} fn test::Assoc>>() { + //~^ ERROR overflow evaluating the requirement `::Assoc == _` needs_bar::(); - //~^ ERROR the trait bound `::Assoc: Bar` is not satisfied } fn main() {} diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr deleted file mode 100644 index c551823468741..0000000000000 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0277]: the trait bound `::Assoc: Bar` is not satisfied - --> $DIR/recursive-self-normalization.rs:11:17 - | -LL | needs_bar::(); - | ^^^^^^^^ the trait `Bar` is not implemented for `::Assoc` - | -note: required by a bound in `needs_bar` - --> $DIR/recursive-self-normalization.rs:8:17 - | -LL | fn needs_bar() {} - | ^^^ required by this bound in `needs_bar` -help: consider further restricting the associated type - | -LL | fn test::Assoc>>() where ::Assoc: Bar { - | ++++++++++++++++++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`.