mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-30 06:43:20 +03:00
Propagate certainty
This commit is contained in:
@@ -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`)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user