From fcddf7fa3cd4c9cfa8afa9f1aba830cea87971b0 Mon Sep 17 00:00:00 2001 From: Ada Bohm Date: Thu, 5 Mar 2026 10:08:57 +0100 Subject: [PATCH] Propagate certainty --- .../src/solve/assembly/mod.rs | 37 +++++++++++++------ .../find-param-recursion-issue-152716.rs | 2 +- .../find-param-recursion-issue-152716.stderr | 6 ++- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index bf59f7cab8e4..bb0f16e153da 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -9,6 +9,7 @@ use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::SolverTraitLangItem; use rustc_type_ir::search_graph::CandidateHeadUsages; +use rustc_type_ir::solve::Certainty::Maybe; use rustc_type_ir::solve::{AliasBoundKind, SizedTraitKind}; use rustc_type_ir::{ self as ty, Interner, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, @@ -138,8 +139,10 @@ fn probe_and_consider_param_env_candidate( .enter_single_candidate(|ecx| { Self::match_assumption(ecx, goal, assumption, |ecx| { ecx.try_evaluate_added_goals()?; - source.set(ecx.characterize_param_env_assumption(goal.param_env, assumption)?); - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + let (src, certainty) = + ecx.characterize_param_env_assumption(goal.param_env, assumption)?; + source.set(src); + ecx.evaluate_added_goals_and_make_canonical_response(certainty) }) }); @@ -1222,11 +1225,11 @@ fn characterize_param_env_assumption( &mut self, param_env: I::ParamEnv, assumption: I::Clause, - ) -> Result, NoSolution> { + ) -> Result<(CandidateSource, Certainty), NoSolution> { // FIXME: This should be fixed, but it also requires changing the behavior // in the old solver which is currently relied on. if assumption.has_bound_vars() { - return Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)); + return Ok((CandidateSource::ParamEnv(ParamEnvSource::NonGlobal), Certainty::Yes)); } match assumption.visit_with(&mut FindParamInClause { @@ -1236,8 +1239,12 @@ fn characterize_param_env_assumption( recursion_depth: 0, }) { ControlFlow::Break(Err(NoSolution)) => Err(NoSolution), - ControlFlow::Break(Ok(())) => Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)), - ControlFlow::Continue(()) => Ok(CandidateSource::ParamEnv(ParamEnvSource::Global)), + ControlFlow::Break(Ok(certainty)) => { + Ok((CandidateSource::ParamEnv(ParamEnvSource::NonGlobal), certainty)) + } + ControlFlow::Continue(()) => { + Ok((CandidateSource::ParamEnv(ParamEnvSource::Global), Certainty::Yes)) + } } } } @@ -1254,7 +1261,7 @@ impl TypeVisitor for FindParamInClause<'_, '_, D, I> D: SolverDelegate, I: Interner, { - type Result = ControlFlow>; + type Result = ControlFlow>; fn visit_binder>(&mut self, t: &ty::Binder) -> Self::Result { self.universes.push(None); @@ -1271,14 +1278,20 @@ fn visit_ty(&mut self, ty: I::Ty) -> Self::Result { if let ty::Placeholder(p) = ty.kind() { if p.universe() == ty::UniverseIndex::ROOT { - ControlFlow::Break(Ok(())) + ControlFlow::Break(Ok(Certainty::Yes)) } else { ControlFlow::Continue(()) } } else if ty.has_type_flags(TypeFlags::HAS_PLACEHOLDER | TypeFlags::HAS_RE_INFER) { self.recursion_depth += 1; if self.recursion_depth > self.ecx.cx().recursion_limit() { - return ControlFlow::Break(Err(NoSolution)); + return ControlFlow::Break(Ok(Maybe { + cause: MaybeCause::Overflow { + suggest_increasing_limit: true, + keep_constraints: false, + }, + opaque_types_jank: OpaqueTypesJank::AllGood, + })); } let result = ty.super_visit_with(self); self.recursion_depth -= 1; @@ -1296,7 +1309,7 @@ fn visit_const(&mut self, ct: I::Const) -> Self::Result { if let ty::ConstKind::Placeholder(p) = ct.kind() { if p.universe() == ty::UniverseIndex::ROOT { - ControlFlow::Break(Ok(())) + ControlFlow::Break(Ok(Certainty::Yes)) } else { ControlFlow::Continue(()) } @@ -1312,12 +1325,12 @@ fn visit_region(&mut self, r: I::Region) -> Self::Result { ty::ReStatic | ty::ReError(_) | ty::ReBound(..) => ControlFlow::Continue(()), ty::RePlaceholder(p) => { if p.universe() == ty::UniverseIndex::ROOT { - ControlFlow::Break(Ok(())) + ControlFlow::Break(Ok(Certainty::Yes)) } else { ControlFlow::Continue(()) } } - ty::ReVar(_) => ControlFlow::Break(Ok(())), + ty::ReVar(_) => ControlFlow::Break(Ok(Certainty::Yes)), ty::ReErased | ty::ReEarlyParam(_) | ty::ReLateParam(_) => { unreachable!("unexpected region in param-env clause") } 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 410781e955d7..e9635f709a99 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,5 +1,4 @@ //@ compile-flags: -Znext-solver -//~^ ERROR overflow normalizing the associated type `>::Assoc` [E0275] // Regression test for . @@ -11,6 +10,7 @@ fn foo() where T: for<'a> Proj<'a, Assoc = for<'b> fn(>::Assoc)>, (): Trait<>::Assoc> + //~^ ERROR overflow evaluating the requirement `(): Trait<>::Assoc>` [E0275] { } 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 index 9886e303eaf7..3aca6cfc9c5a 100644 --- a/tests/ui/traits/next-solver/find-param-recursion-issue-152716.stderr +++ b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.stderr @@ -1,4 +1,8 @@ -error[E0275]: overflow normalizing the associated type `>::Assoc` +error[E0275]: overflow evaluating the requirement `(): Trait<>::Assoc>` + --> $DIR/find-param-recursion-issue-152716.rs:12:9 + | +LL | (): Trait<>::Assoc> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`find_param_recursion_issue_152716`)