Propagate certainty

This commit is contained in:
Ada Bohm
2026-03-05 10:08:57 +01:00
parent 8b83d4b4a6
commit fcddf7fa3c
3 changed files with 31 additions and 14 deletions
@@ -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<CandidateSource<I>, NoSolution> {
) -> Result<(CandidateSource<I>, 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<D, I> TypeVisitor<I> for FindParamInClause<'_, '_, D, I>
D: SolverDelegate<Interner = I>,
I: Interner,
{
type Result = ControlFlow<Result<(), NoSolution>>;
type Result = ControlFlow<Result<Certainty, NoSolution>>;
fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &ty::Binder<I, T>) -> 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")
}
@@ -1,5 +1,4 @@
//@ compile-flags: -Znext-solver
//~^ ERROR overflow normalizing the associated type `<T as Proj<'b>>::Assoc` [E0275]
// Regression test for <https://github.com/rust-lang/rust/issues/152716>.
@@ -11,6 +10,7 @@ fn foo<T>()
where
T: for<'a> Proj<'a, Assoc = for<'b> fn(<T as Proj<'b>>::Assoc)>,
(): Trait<<T as Proj<'static>>::Assoc>
//~^ ERROR overflow evaluating the requirement `(): Trait<<T as Proj<'static>>::Assoc>` [E0275]
{
}
@@ -1,4 +1,8 @@
error[E0275]: overflow normalizing the associated type `<T as Proj<'b>>::Assoc`
error[E0275]: overflow evaluating the requirement `(): Trait<<T as Proj<'static>>::Assoc>`
--> $DIR/find-param-recursion-issue-152716.rs:12:9
|
LL | (): Trait<<T as Proj<'static>>::Assoc>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`find_param_recursion_issue_152716`)