From 940cc6c1f56bf4d4075823591bec9b2a7644115b Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 6 Aug 2026 13:25:52 +0200 Subject: [PATCH 1/3] overflow FCW also trigger for overflow -> ambig --- .../src/solve/eval_ctxt/mod.rs | 16 ++++---- ...flow-to-ambig-with-constraints.next.stderr | 40 +++++++++++++++++++ .../fcw-overflow-to-ambig-with-constraints.rs | 36 +++++++++++++++++ 3 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.next.stderr create mode 100644 tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.rs 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 004d1df069d6e..32fd33cc4ba09 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 @@ -315,9 +315,9 @@ where } /// The old solver doesn't check depth requirement when looking up cache while the next solver -/// does so. Thus the next solver is more prone to overflow. -/// To mitigate breakages, we re-evaluate the overflowed goal with doubled recursion limit -/// and emit a FCW if it succeeds. +/// does so. Thus the next solver is more prone to overflow. To mitigate breakages, we re-evaluate +/// the overflowed goal with doubled recursion limit and emit a FCW if doing so prevents overflow. +/// /// See the doc comment on `RECURSION_DEPTH_EXCEEDING_LIMIT` and #159228 for more details. fn maybe_evaluate_root_goal_with_higher_recursion_limit( delegate: &D, @@ -344,7 +344,7 @@ fn maybe_evaluate_root_goal_with_higher_recursion_limit( ecx.evaluate_goal_no_fast_paths(GoalSource::Misc, goal) }); if let Ok(goal_evaluation) = &rerun_result - && goal_evaluation.certainty.is_yes() + && !goal_evaluation.certainty.is_overflow() { Ok(rerun_result) } else { @@ -358,9 +358,9 @@ fn maybe_evaluate_root_goal_with_higher_recursion_limit( } /// The old solver doesn't check depth requirement when looking up cache while the next solver -/// does so. Thus the next solver is more prone to overflow. -/// To mitigate breakages, we re-evaluate the overflowed goal with doubled recursion limit -/// and emit a FCW if it succeeds. +/// does so. Thus the next solver is more prone to overflow. To mitigate breakages, we re-evaluate +/// the overflowed goal with doubled recursion limit and emit a FCW if doing so prevents overflow. +/// /// See the doc comment on `RECURSION_DEPTH_EXCEEDING_LIMIT` and #159228 for more details. fn maybe_evaluate_root_goal_for_proof_tree_with_higher_recursion_limit( delegate: &D, @@ -393,7 +393,7 @@ fn maybe_evaluate_root_goal_for_proof_tree_with_higher_recursion_limit( delegate.cx().recursion_limit() * 2, ); if let Ok(response) = &new_goal_evaluation.result - && response.value.certainty.is_yes() + && !response.value.certainty.is_overflow() { Ok((new_result, new_goal_evaluation)) } else { diff --git a/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.next.stderr b/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.next.stderr new file mode 100644 index 0000000000000..e94b95c67dc65 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.next.stderr @@ -0,0 +1,40 @@ +warning: overflow evaluating the requirement `u32: Constrain<_, _, W>, _>, _>>` + --> $DIR/fcw-overflow-to-ambig-with-constraints.rs:29:5 + | +LL | fun_times(); + | ^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "16"]` attribute to your crate (`fcw_overflow_to_ambig_with_constraints`) + = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved + = note: this lint is attached to the whole crate and can't be disabled on a per-function basis + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #159228 + = note: `#[warn(recursion_depth_exceeding_limit)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: overflow evaluating the requirement `u32: Constrain>, _>, _>>` + --> $DIR/fcw-overflow-to-ambig-with-constraints.rs:29:5 + | +LL | fun_times(); + | ^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "16"]` attribute to your crate (`fcw_overflow_to_ambig_with_constraints`) + = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved + = note: this lint is attached to the whole crate and can't be disabled on a per-function basis + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #159228 + +warning: overflow evaluating the requirement `u32: Constrain>, _>, _>>` + --> $DIR/fcw-overflow-to-ambig-with-constraints.rs:29:5 + | +LL | fun_times(); + | ^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "16"]` attribute to your crate (`fcw_overflow_to_ambig_with_constraints`) + = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved + = note: this lint is attached to the whole crate and can't be disabled on a per-function basis + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #159228 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +warning: 3 warnings emitted + diff --git a/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.rs b/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.rs new file mode 100644 index 0000000000000..9c51f3480c09b --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.rs @@ -0,0 +1,36 @@ +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +//@ check-pass + +// Regression test for `calimero-store` + +#![recursion_limit = "8"] +struct W(T, U); +trait Count {} +impl Count for W {} +impl Count for () {} +// Old solver is able to use cache entries from lower recursion depths, +// new one correctly tracks their required depth, so it needs more than 8 steps. +type Four = W>>>; + +trait Constrain {} +impl Constrain for u32 {} + +trait Equal {} +impl Equal for T {} + +fn fun_times() +where + u32: Constrain>>>, + T: Equal, +{} + +fn main() { + fun_times(); + //[next]~^ WARN overflow evaluating the requirement `u32: Constrain<_, _, W>, _>, _>>` + //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //[next]~| WARN overflow evaluating the requirement `u32: Constrain>, _>, _>>` + //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //[next]~| WARN overflow evaluating the requirement `u32: Constrain>, _>, _>>` + //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +} From 07b049019b98399c2094f2981b56cdccee1ed955 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 13 Aug 2026 12:50:34 +0200 Subject: [PATCH 2/3] only emit a single `recursion_depth_exceeding_limit` --- compiler/rustc_errors/src/lib.rs | 34 +++++-- .../overflow-discards-constraints.rs | 2 - .../overflow-discards-constraints.stderr | 14 +-- .../overflow/fcw-on-auto-trait.next.stderr | 15 +-- .../next-solver/overflow/fcw-on-auto-trait.rs | 2 - .../overflow/fcw-on-normalization.next.stderr | 91 +------------------ .../overflow/fcw-on-normalization.rs | 15 --- ...flow-to-ambig-with-constraints.next.stderr | 27 +----- .../fcw-overflow-to-ambig-with-constraints.rs | 4 - 9 files changed, 31 insertions(+), 173 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 08b019917fa9f..fefa3321f68fd 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -25,7 +25,7 @@ use std::num::NonZero; use std::ops::DerefMut; use std::path::{Path, PathBuf}; use std::thread::ThreadId; -use std::{assert_matches, fmt, panic}; +use std::{assert_matches, fmt, mem, panic}; use Level::*; // Used by external projects such as `rust-gpu`. @@ -339,6 +339,15 @@ struct DiagCtxtInner { /// twice. emitted_diagnostics: FxHashSet, + /// We only want to emit `recursion_depth_exceeding_limit` once per + /// crate. Otherwise crates like `calimero-store` emit more than + /// a thousand warnings. + /// + /// We only check this in `TRACK_DIAGNOSTIC` meaning that the diagnostics + /// still get tracked by the query system, even if they don't get emitted + /// to users. + emitted_recursion_depth_exceeding_limit: bool, + /// Stashed diagnostics emitted in one stage of the compiler that may be /// stolen and emitted/cancelled by other stages (e.g. to improve them and /// add more information). All stashed diagnostics must be emitted with @@ -530,6 +539,7 @@ impl DiagCtxt { taught_diagnostics, emitted_diagnostic_codes, emitted_diagnostics, + emitted_recursion_depth_exceeding_limit, stashed_diagnostics, future_breakage_diagnostics, fulfilled_expectations, @@ -550,6 +560,7 @@ impl DiagCtxt { *taught_diagnostics = Default::default(); *emitted_diagnostic_codes = Default::default(); *emitted_diagnostics = Default::default(); + *emitted_recursion_depth_exceeding_limit = false; *stashed_diagnostics = Default::default(); *future_breakage_diagnostics = Default::default(); *fulfilled_expectations = Default::default(); @@ -882,7 +893,7 @@ impl<'a> DiagCtxtHandle<'a> { pub fn emit_future_breakage_report(&self) { let inner = &mut *self.inner.borrow_mut(); - let diags = std::mem::take(&mut inner.future_breakage_diagnostics); + let diags = mem::take(&mut inner.future_breakage_diagnostics); if !diags.is_empty() { inner.emitter.emit_future_breakage_report(diags); } @@ -922,7 +933,7 @@ impl<'a> DiagCtxtHandle<'a> { /// [`DiagCtxtInner`] and indicate that the linked expectation has been fulfilled. #[must_use] pub fn steal_fulfilled_expectation_ids(&self) -> FxIndexSet { - std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations) + mem::take(&mut self.inner.borrow_mut().fulfilled_expectations) } /// Trigger an ICE if there are any delayed bugs and no hard errors. @@ -1198,6 +1209,7 @@ impl DiagCtxtInner { taught_diagnostics: Default::default(), emitted_diagnostic_codes: Default::default(), emitted_diagnostics: Default::default(), + emitted_recursion_depth_exceeding_limit: false, stashed_diagnostics: Default::default(), future_breakage_diagnostics: Vec::new(), fulfilled_expectations: Default::default(), @@ -1210,7 +1222,7 @@ impl DiagCtxtInner { fn emit_stashed_diagnostics(&mut self) -> Option { let mut guar = None; let has_errors = !self.err_guars.is_empty(); - for (_, stashed_diagnostics) in std::mem::take(&mut self.stashed_diagnostics).into_iter() { + for (_, stashed_diagnostics) in mem::take(&mut self.stashed_diagnostics).into_iter() { for (_, (diag, _guar, _thread)) in stashed_diagnostics { if !diag.is_error() { // Unless they're forced, don't flush stashed warnings when @@ -1337,10 +1349,19 @@ impl DiagCtxtInner { let is_error = diagnostic.is_error(); let is_lint = diagnostic.is_lint.is_some(); + // We only emit the first occurance of `recursion_depth_exceeding_limit`. + let silence_recursion_depth_exceeded_limit = + diagnostic.is_lint.as_ref().is_some_and(|lint| { + lint.name.eq_ignore_ascii_case( + rustc_lint_defs::builtin::RECURSION_DEPTH_EXCEEDING_LIMIT.name, + ) && mem::replace(&mut self.emitted_recursion_depth_exceeding_limit, true) + }); // Only emit the diagnostic if we've been asked to deduplicate or // haven't already emitted an equivalent diagnostic. - if !(self.flags.deduplicate_diagnostics && already_emitted) { + if !silence_recursion_depth_exceeded_limit + && !(self.flags.deduplicate_diagnostics && already_emitted) + { debug!(?diagnostic); debug!(?self.emitted_diagnostics); @@ -1463,8 +1484,7 @@ impl DiagCtxtInner { return; } - let bugs: Vec<_> = - std::mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect(); + let bugs: Vec<_> = mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect(); let backtrace = std::env::var_os("RUST_BACKTRACE").as_deref() != Some(OsStr::new("0")); let decorate = backtrace || self.ice_file.is_none(); diff --git a/tests/ui/traits/next-solver/overflow-discards-constraints.rs b/tests/ui/traits/next-solver/overflow-discards-constraints.rs index a5432f40a8659..1097268002eb9 100644 --- a/tests/ui/traits/next-solver/overflow-discards-constraints.rs +++ b/tests/ui/traits/next-solver/overflow-discards-constraints.rs @@ -69,7 +69,5 @@ fn main() { foo(); // register a `(): Trait` obligation //~^ WARN: overflow evaluating the requirement `(): Trait<_>` [recursion_depth_exceeding_limit] //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - //~| WARN: overflow evaluating the requirement `(): Trait` [recursion_depth_exceeding_limit] - //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/traits/next-solver/overflow-discards-constraints.stderr b/tests/ui/traits/next-solver/overflow-discards-constraints.stderr index 5705b0a97e58d..ed25f58c51263 100644 --- a/tests/ui/traits/next-solver/overflow-discards-constraints.stderr +++ b/tests/ui/traits/next-solver/overflow-discards-constraints.stderr @@ -11,17 +11,5 @@ LL | foo(); // register a `(): Trait` obligation = note: for more information, see issue #159228 = note: `#[warn(recursion_depth_exceeding_limit)]` (part of `#[warn(future_incompatible)]`) on by default -warning: overflow evaluating the requirement `(): Trait` - --> $DIR/overflow-discards-constraints.rs:69:5 - | -LL | foo(); // register a `(): Trait` obligation - | ^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "12"]` attribute to your crate (`overflow_discards_constraints`) - = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved - = note: this lint is attached to the whole crate and can't be disabled on a per-function basis - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #159228 - -warning: 2 warnings emitted +warning: 1 warning emitted diff --git a/tests/ui/traits/next-solver/overflow/fcw-on-auto-trait.next.stderr b/tests/ui/traits/next-solver/overflow/fcw-on-auto-trait.next.stderr index d5a74c9dcd1b1..9cb61f3258702 100644 --- a/tests/ui/traits/next-solver/overflow/fcw-on-auto-trait.next.stderr +++ b/tests/ui/traits/next-solver/overflow/fcw-on-auto-trait.next.stderr @@ -11,18 +11,5 @@ LL | require_sync::>>>>>>(); = note: for more information, see issue #159228 = note: `#[warn(recursion_depth_exceeding_limit)]` (part of `#[warn(future_incompatible)]`) on by default -warning: overflow evaluating the requirement `Foo>>>>>: Sync` - --> $DIR/fcw-on-auto-trait.rs:22:5 - | -LL | require_sync::>>>>>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "16"]` attribute to your crate (`fcw_on_auto_trait`) - = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved - = note: this lint is attached to the whole crate and can't be disabled on a per-function basis - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #159228 - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -warning: 2 warnings emitted +warning: 1 warning emitted diff --git a/tests/ui/traits/next-solver/overflow/fcw-on-auto-trait.rs b/tests/ui/traits/next-solver/overflow/fcw-on-auto-trait.rs index 8f243a728e54b..73c0a5c153893 100644 --- a/tests/ui/traits/next-solver/overflow/fcw-on-auto-trait.rs +++ b/tests/ui/traits/next-solver/overflow/fcw-on-auto-trait.rs @@ -22,6 +22,4 @@ fn main() { require_sync::>>>>>>(); //[next]~^ WARN: overflow evaluating the requirement `Foo>>>>>: Sync` [recursion_depth_exceeding_limit] //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - //[next]~| WARN: overflow evaluating the requirement `Foo>>>>>: Sync` [recursion_depth_exceeding_limit] - //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/traits/next-solver/overflow/fcw-on-normalization.next.stderr b/tests/ui/traits/next-solver/overflow/fcw-on-normalization.next.stderr index 6ac95d6f597d8..217ed84727276 100644 --- a/tests/ui/traits/next-solver/overflow/fcw-on-normalization.next.stderr +++ b/tests/ui/traits/next-solver/overflow/fcw-on-normalization.next.stderr @@ -11,94 +11,5 @@ LL | let b: >>>>>>>>> as HasAssoc>::Assoc = loop {}; = note: for more information, see issue #159228 = note: `#[warn(recursion_depth_exceeding_limit)]` (part of `#[warn(future_incompatible)]`) on by default -warning: overflow evaluating the requirement `>>>>>> as HasAssoc>::Assoc == _` - --> $DIR/fcw-on-normalization.rs:40:12 - | -LL | let b: >>>>>>>>> as HasAssoc>::Assoc = loop {}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "16"]` attribute to your crate (`fcw_on_normalization`) - = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved - = note: this lint is attached to the whole crate and can't be disabled on a per-function basis - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #159228 - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -warning: overflow evaluating the requirement `W>>>>>>>>>: HasAssoc` - --> $DIR/fcw-on-normalization.rs:40:12 - | -LL | let b: >>>>>>>>> as HasAssoc>::Assoc = loop {}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "16"]` attribute to your crate (`fcw_on_normalization`) - = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved - = note: this lint is attached to the whole crate and can't be disabled on a per-function basis - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #159228 - -warning: overflow evaluating the requirement `>>>>> as HasAssoc>::Assoc well-formed` - --> $DIR/fcw-on-normalization.rs:40:12 - | -LL | let b: >>>>>>>>> as HasAssoc>::Assoc = loop {}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "16"]` attribute to your crate (`fcw_on_normalization`) - = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved - = note: this lint is attached to the whole crate and can't be disabled on a per-function basis - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #159228 - -warning: overflow evaluating the requirement `>>>>>> as HasAssoc>::Assoc == _` - --> $DIR/fcw-on-normalization.rs:40:12 - | -LL | let b: >>>>>>>>> as HasAssoc>::Assoc = loop {}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "16"]` attribute to your crate (`fcw_on_normalization`) - = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved - = note: this lint is attached to the whole crate and can't be disabled on a per-function basis - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #159228 - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -warning: overflow evaluating the requirement `>>>>> as HasAssoc>::Assoc well-formed` - --> $DIR/fcw-on-normalization.rs:40:12 - | -LL | let b: >>>>>>>>> as HasAssoc>::Assoc = loop {}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "16"]` attribute to your crate (`fcw_on_normalization`) - = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved - = note: this lint is attached to the whole crate and can't be disabled on a per-function basis - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #159228 - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -warning: overflow evaluating the requirement `>>>>>> as HasAssoc>::Assoc == _` - --> $DIR/fcw-on-normalization.rs:40:12 - | -LL | let b: >>>>>>>>> as HasAssoc>::Assoc = loop {}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "16"]` attribute to your crate (`fcw_on_normalization`) - = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved - = note: this lint is attached to the whole crate and can't be disabled on a per-function basis - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #159228 - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -warning: overflow evaluating the requirement `>>>>> as HasAssoc>::Assoc well-formed` - --> $DIR/fcw-on-normalization.rs:40:12 - | -LL | let b: >>>>>>>>> as HasAssoc>::Assoc = loop {}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "16"]` attribute to your crate (`fcw_on_normalization`) - = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved - = note: this lint is attached to the whole crate and can't be disabled on a per-function basis - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #159228 - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -warning: 8 warnings emitted +warning: 1 warning emitted diff --git a/tests/ui/traits/next-solver/overflow/fcw-on-normalization.rs b/tests/ui/traits/next-solver/overflow/fcw-on-normalization.rs index 12d1664e834d0..01ea77719f4e3 100644 --- a/tests/ui/traits/next-solver/overflow/fcw-on-normalization.rs +++ b/tests/ui/traits/next-solver/overflow/fcw-on-normalization.rs @@ -40,21 +40,6 @@ fn foo() { let b: >>>>>>>>> as HasAssoc>::Assoc = loop {}; //[next]~^ WARN: overflow evaluating the requirement `>>>>>> as HasAssoc>::Assoc == _` [recursion_depth_exceeding_limit] //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - //[next]~| WARN: overflow evaluating the requirement `>>>>>> as HasAssoc>::Assoc == _` [recursion_depth_exceeding_limit] - //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - //[next]~| WARN: overflow evaluating the requirement `W>>>>>>>>>: HasAssoc` [recursion_depth_exceeding_limit] - //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - //[next]~| WARN: overflow evaluating the requirement `>>>>> as HasAssoc>::Assoc well-formed` [recursion_depth_exceeding_limit] - //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - //[next]~| WARN: overflow evaluating the requirement `>>>>>> as HasAssoc>::Assoc == _` [recursion_depth_exceeding_limit] - //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - //[next]~| WARN: overflow evaluating the requirement `>>>>> as HasAssoc>::Assoc well-formed` [recursion_depth_exceeding_limit] - //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - //[next]~| WARN: overflow evaluating the requirement `>>>>>> as HasAssoc>::Assoc == _` [recursion_depth_exceeding_limit] - //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - //[next]~| WARN: overflow evaluating the requirement `>>>>> as HasAssoc>::Assoc well-formed` [recursion_depth_exceeding_limit] - //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - // Force normalization when looking up methods and the self_ty is normalized to infer. b.anyone_can_call(); } diff --git a/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.next.stderr b/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.next.stderr index e94b95c67dc65..507132eface89 100644 --- a/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.next.stderr +++ b/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.next.stderr @@ -11,30 +11,5 @@ LL | fun_times(); = note: for more information, see issue #159228 = note: `#[warn(recursion_depth_exceeding_limit)]` (part of `#[warn(future_incompatible)]`) on by default -warning: overflow evaluating the requirement `u32: Constrain>, _>, _>>` - --> $DIR/fcw-overflow-to-ambig-with-constraints.rs:29:5 - | -LL | fun_times(); - | ^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "16"]` attribute to your crate (`fcw_overflow_to_ambig_with_constraints`) - = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved - = note: this lint is attached to the whole crate and can't be disabled on a per-function basis - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #159228 - -warning: overflow evaluating the requirement `u32: Constrain>, _>, _>>` - --> $DIR/fcw-overflow-to-ambig-with-constraints.rs:29:5 - | -LL | fun_times(); - | ^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "16"]` attribute to your crate (`fcw_overflow_to_ambig_with_constraints`) - = help: or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved - = note: this lint is attached to the whole crate and can't be disabled on a per-function basis - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #159228 - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -warning: 3 warnings emitted +warning: 1 warning emitted diff --git a/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.rs b/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.rs index 9c51f3480c09b..6ef671d7dd471 100644 --- a/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.rs +++ b/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.rs @@ -29,8 +29,4 @@ fn main() { fun_times(); //[next]~^ WARN overflow evaluating the requirement `u32: Constrain<_, _, W>, _>, _>>` //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - //[next]~| WARN overflow evaluating the requirement `u32: Constrain>, _>, _>>` - //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - //[next]~| WARN overflow evaluating the requirement `u32: Constrain>, _>, _>>` - //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } From cdda9237becde9c3600957463175f4f0985262d7 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 13 Aug 2026 13:10:54 +0200 Subject: [PATCH 3/3] move fcw to `SolverDelegate`, resolve infer vars --- .../src/ty/context/impl_interner.rs | 43 ++---------------- .../rustc_next_trait_solver/src/delegate.rs | 6 +++ .../src/solve/eval_ctxt/mod.rs | 4 +- .../src/solve/delegate.rs | 44 ++++++++++++++++++- compiler/rustc_type_ir/src/interner.rs | 2 - .../overflow-discards-constraints.rs | 2 +- .../overflow-discards-constraints.stderr | 2 +- .../overflow/fcw-on-normalization.next.stderr | 2 +- .../overflow/fcw-on-normalization.rs | 2 +- ...flow-to-ambig-with-constraints.next.stderr | 2 +- .../fcw-overflow-to-ambig-with-constraints.rs | 2 +- 11 files changed, 59 insertions(+), 52 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index 983b4afefdb5f..1af290e1f3b31 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -3,13 +3,12 @@ use std::ops::ControlFlow; use std::{debug_assert_matches, fmt}; -use rustc_data_structures::Limit; use rustc_data_structures::intern::Interned; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; -use rustc_hir::def::{CtorKind, DefKind, Namespace}; -use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; -use rustc_hir::{CRATE_HIR_ID, LangItem}; +use rustc_hir::LangItem; +use rustc_hir::def::{CtorKind, DefKind}; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTraitLangItem}; use rustc_type_ir::{ @@ -23,7 +22,6 @@ use crate::traits::cache::WithDepNode; use crate::traits::solve::{ self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, QueryResult, inspect, }; -use crate::ty::print::{FmtPrinter, Print}; use crate::ty::{ self, BoundRegion, Clause, Const, List, ParamTy, Pattern, PolyExistentialPredicate, Predicate, Region, RegionKind, Ty, TyCtxt, @@ -682,41 +680,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.evaluate_root_goal_for_proof_tree_raw((canonical_goal, root_depth)) } - fn emit_next_solver_overflow_fcw(self, predicate: ty::Predicate<'tcx>, span: Span) { - self.emit_node_span_lint( - rustc_session::lint::builtin::RECURSION_DEPTH_EXCEEDING_LIMIT, - CRATE_HIR_ID, - span, - rustc_errors::DiagDecorator(|diag| { - // FIXME: share this with overflow error in fulfillment instead of duplicating. - let pred_str = { - let s = predicate.to_string(); - if s.len() > 50 { - let mut p: FmtPrinter<'_, '_> = - FmtPrinter::new_with_limit(self, Namespace::TypeNS, Limit(6)); - predicate.print(&mut p).unwrap(); - p.into_buffer() - } else { - s - } - }; - diag.primary_message(format!( - "overflow evaluating the requirement `{pred_str}`", - )); - diag.help(format!( - "consider increasing the recursion limit by adding a \ - `#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)", - self.recursion_limit() * 2, - self.crate_name(LOCAL_CRATE), - )); - diag.help( - "or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved", - ); - diag.note("this lint is attached to the whole crate and can't be disabled on a per-function basis"); - }), - ) - } - fn item_name(self, id: DefId) -> Symbol { self.opt_item_name(id).unwrap_or_else(|| { bug!("item_name: no name for {:?}", self.def_path(id)); diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 7b66667486fc9..e8ef60e2fe3de 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -90,4 +90,10 @@ pub trait SolverDelegate: Deref + Sized { dst: ::Ty, assume: ::Const, ) -> Result; + + fn emit_next_solver_overflow_fcw( + &self, + predicate: ::Predicate, + span: ::Span, + ); } 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 32fd33cc4ba09..a3af79e18e0d8 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 @@ -352,7 +352,7 @@ fn maybe_evaluate_root_goal_with_higher_recursion_limit( } }); if let Ok(rerun_result) = rerun_result { - delegate.cx().emit_next_solver_overflow_fcw(predicate, span); + delegate.emit_next_solver_overflow_fcw(predicate, span); *initial_result = rerun_result; } } @@ -402,7 +402,7 @@ fn maybe_evaluate_root_goal_for_proof_tree_with_higher_recursion_limit( }); if let Ok(rerun_result) = rerun_result { let predicate: I::Predicate = goal_evaluation.uncanonicalized_goal.predicate; - delegate.cx().emit_next_solver_overflow_fcw(predicate, span); + delegate.emit_next_solver_overflow_fcw(predicate, span); *initial_result = rerun_result; } } diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index bb1e6c168c47b..d79c128d3e208 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -1,9 +1,11 @@ use std::collections::hash_map::Entry; use std::ops::Deref; +use rustc_data_structures::Limit; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir::LangItem; -use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; +use rustc_hir::def::Namespace; +use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE}; +use rustc_hir::{CRATE_HIR_ID, LangItem}; use rustc_infer::infer::canonical::query_response::make_query_region_constraints; use rustc_infer::infer::canonical::{ Canonical, CanonicalExt as _, CanonicalQueryInput, CanonicalVarKind, CanonicalVarValues, @@ -15,6 +17,7 @@ use rustc_infer::traits::solve::{ }; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::Certainty; +use rustc_middle::ty::print::{FmtPrinter, Print}; use rustc_middle::ty::{ self, MayBeErased, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, @@ -472,4 +475,41 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< rustc_transmute::Answer::No(_) | rustc_transmute::Answer::If(_) => Err(NoSolution), } } + + fn emit_next_solver_overflow_fcw(&self, predicate: ty::Predicate<'tcx>, span: Span) { + let tcx = self.tcx; + let predicate = self.resolve_vars_if_possible(predicate); + tcx.emit_node_span_lint( + rustc_session::lint::builtin::RECURSION_DEPTH_EXCEEDING_LIMIT, + CRATE_HIR_ID, + span, + rustc_errors::DiagDecorator(|diag| { + // FIXME: share this with overflow error in fulfillment instead of duplicating. + let pred_str = { + let s = predicate.to_string(); + if s.len() > 50 { + let mut p: FmtPrinter<'_, '_> = + FmtPrinter::new_with_limit(tcx, Namespace::TypeNS, Limit(6)); + predicate.print(&mut p).unwrap(); + p.into_buffer() + } else { + s + } + }; + diag.primary_message(format!( + "overflow evaluating the requirement `{pred_str}`", + )); + diag.help(format!( + "consider increasing the recursion limit by adding a \ + `#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)", + tcx.recursion_limit() * 2, + tcx.crate_name(LOCAL_CRATE), + )); + diag.help( + "or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved", + ); + diag.note("this lint is attached to the whole crate and can't be disabled on a per-function basis"); + }), + ) + } } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 1fa698a4faeaf..2728a56853f88 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -470,8 +470,6 @@ pub trait Interner: root_depth: usize, ) -> (QueryResult, Self::Probe); - fn emit_next_solver_overflow_fcw(self, predicate: Self::Predicate, span: Self::Span); - fn item_name(self, item_index: Self::DefId) -> Self::Symbol; fn get_anon_re_bounds_lifetime(self, idx: usize, var_idx: usize) -> Option>; diff --git a/tests/ui/traits/next-solver/overflow-discards-constraints.rs b/tests/ui/traits/next-solver/overflow-discards-constraints.rs index 1097268002eb9..810d756625b01 100644 --- a/tests/ui/traits/next-solver/overflow-discards-constraints.rs +++ b/tests/ui/traits/next-solver/overflow-discards-constraints.rs @@ -67,7 +67,7 @@ fn foo() fn main() { foo(); // register a `(): Trait` obligation - //~^ WARN: overflow evaluating the requirement `(): Trait<_>` [recursion_depth_exceeding_limit] + //~^ WARN: overflow evaluating the requirement `(): Trait` [recursion_depth_exceeding_limit] //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/traits/next-solver/overflow-discards-constraints.stderr b/tests/ui/traits/next-solver/overflow-discards-constraints.stderr index ed25f58c51263..68c1e88181f17 100644 --- a/tests/ui/traits/next-solver/overflow-discards-constraints.stderr +++ b/tests/ui/traits/next-solver/overflow-discards-constraints.stderr @@ -1,4 +1,4 @@ -warning: overflow evaluating the requirement `(): Trait<_>` +warning: overflow evaluating the requirement `(): Trait` --> $DIR/overflow-discards-constraints.rs:69:5 | LL | foo(); // register a `(): Trait` obligation diff --git a/tests/ui/traits/next-solver/overflow/fcw-on-normalization.next.stderr b/tests/ui/traits/next-solver/overflow/fcw-on-normalization.next.stderr index 217ed84727276..0726f81a0f7be 100644 --- a/tests/ui/traits/next-solver/overflow/fcw-on-normalization.next.stderr +++ b/tests/ui/traits/next-solver/overflow/fcw-on-normalization.next.stderr @@ -1,4 +1,4 @@ -warning: overflow evaluating the requirement `>>>>>> as HasAssoc>::Assoc == _` +warning: overflow evaluating the requirement `>>>>>> as HasAssoc>::Assoc == ()` --> $DIR/fcw-on-normalization.rs:40:12 | LL | let b: >>>>>>>>> as HasAssoc>::Assoc = loop {}; diff --git a/tests/ui/traits/next-solver/overflow/fcw-on-normalization.rs b/tests/ui/traits/next-solver/overflow/fcw-on-normalization.rs index 01ea77719f4e3..737f492dd7173 100644 --- a/tests/ui/traits/next-solver/overflow/fcw-on-normalization.rs +++ b/tests/ui/traits/next-solver/overflow/fcw-on-normalization.rs @@ -38,7 +38,7 @@ fn foo() { a.anyone_can_call(); let b: >>>>>>>>> as HasAssoc>::Assoc = loop {}; - //[next]~^ WARN: overflow evaluating the requirement `>>>>>> as HasAssoc>::Assoc == _` [recursion_depth_exceeding_limit] + //[next]~^ WARN: overflow evaluating the requirement `>>>>>> as HasAssoc>::Assoc == ()` [recursion_depth_exceeding_limit] //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! // Force normalization when looking up methods and the self_ty is normalized to infer. b.anyone_can_call(); diff --git a/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.next.stderr b/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.next.stderr index 507132eface89..56d9de921a03d 100644 --- a/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.next.stderr +++ b/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.next.stderr @@ -1,4 +1,4 @@ -warning: overflow evaluating the requirement `u32: Constrain<_, _, W>, _>, _>>` +warning: overflow evaluating the requirement `u32: Constrain>, _>, _>>` --> $DIR/fcw-overflow-to-ambig-with-constraints.rs:29:5 | LL | fun_times(); diff --git a/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.rs b/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.rs index 6ef671d7dd471..440e1fd4525bd 100644 --- a/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.rs +++ b/tests/ui/traits/next-solver/overflow/fcw-overflow-to-ambig-with-constraints.rs @@ -27,6 +27,6 @@ where fn main() { fun_times(); - //[next]~^ WARN overflow evaluating the requirement `u32: Constrain<_, _, W>, _>, _>>` + //[next]~^ WARN overflow evaluating the requirement `u32: Constrain>, _>, _>>` //[next]~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! }