This commit is contained in:
Michael Goulet
2025-05-07 16:27:48 +00:00
parent 1f774d74b3
commit 8a21d1b495
6 changed files with 29 additions and 24 deletions

View File

@@ -123,7 +123,7 @@ where
result: Ok(candidate.result),
},
Err(NoSolution) => inspect::ProbeKind::TraitCandidate {
source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
source: CandidateSource::ParamEnv(ParamEnvSource::Global),
result: Err(NoSolution),
},
})
@@ -157,7 +157,7 @@ where
}
/// Try to reject the assumption based off of simple heuristics, such as [`ty::ClauseKind`]
/// and [`I::DefId`].
/// and `DefId`.
fn fast_reject_assumption(
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
@@ -990,12 +990,26 @@ where
}
}
/// Compute whether a param-env assumption is global or non-global after normalizing it.
///
/// This is necessary because, for example, given:
///
/// ```ignore,rust
/// where
/// T: Trait<Assoc = u32>,
/// i32: From<T::Assoc>,
/// ```
///
/// The `i32: From<T::Assoc>` bound is non-global before normalization, but is global after.
/// Since the old trait solver normalized param-envs eagerly, we want to emulate this
/// behavior lazily.
fn characterize_param_env_assumption(
&mut self,
param_env: I::ParamEnv,
assumption: I::Clause,
) -> Result<CandidateSource<I>, NoSolution> {
// FIXME:
// 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));
}
@@ -1030,7 +1044,6 @@ where
let Ok(ty) = self.ecx.structurally_normalize_ty(self.param_env, ty) else {
return ControlFlow::Break(Err(NoSolution));
};
let ty = self.ecx.eager_resolve(ty);
if let ty::Placeholder(_) = ty.kind() {
ControlFlow::Break(Ok(()))
@@ -1043,7 +1056,6 @@ where
let Ok(ct) = self.ecx.structurally_normalize_const(self.param_env, ct) else {
return ControlFlow::Break(Err(NoSolution));
};
let ct = self.ecx.eager_resolve(ct);
if let ty::ConstKind::Placeholder(_) = ct.kind() {
ControlFlow::Break(Ok(()))
@@ -1053,7 +1065,7 @@ where
}
fn visit_region(&mut self, r: I::Region) -> Self::Result {
match r.kind() {
match self.ecx.eager_resolve_region(r).kind() {
ty::ReStatic | ty::ReError(_) => ControlFlow::Continue(()),
ty::ReVar(_) | ty::RePlaceholder(_) => ControlFlow::Break(Ok(())),
ty::ReErased | ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReBound(..) => {

View File

@@ -62,9 +62,7 @@ where
goal: Goal<I, Self>,
assumption: I::Clause,
) -> Result<(), NoSolution> {
let Some(host_clause) = assumption.as_host_effect_clause() else {
panic!("fast_reject_assumption should have avoided this");
};
let host_clause = assumption.as_host_effect_clause().unwrap();
let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause);
ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;

View File

@@ -19,7 +19,6 @@ use tracing::{debug, instrument, trace};
use super::has_only_region_constraints;
use crate::coherence;
use crate::delegate::SolverDelegate;
use crate::resolve::EagerResolver;
use crate::solve::inspect::{self, ProofTreeBuilder};
use crate::solve::search_graph::SearchGraph;
use crate::solve::{
@@ -1001,11 +1000,12 @@ where
self.delegate.resolve_vars_if_possible(value)
}
pub(super) fn eager_resolve<T>(&self, value: T) -> T
where
T: TypeFoldable<I>,
{
value.fold_with(&mut EagerResolver::new(self.delegate))
pub(super) fn eager_resolve_region(&self, r: I::Region) -> I::Region {
if let ty::ReVar(vid) = r.kind() {
self.delegate.opportunistic_resolve_lt_var(vid)
} else {
r
}
}
pub(super) fn fresh_args_for_item(&mut self, def_id: I::DefId) -> I::GenericArgs {

View File

@@ -130,9 +130,7 @@ where
goal: Goal<I, Self>,
assumption: I::Clause,
) -> Result<(), NoSolution> {
let Some(projection_pred) = assumption.as_projection_clause() else {
panic!("fast_reject_assumption should have avoided this");
};
let projection_pred = assumption.as_projection_clause().unwrap();
let assumption_projection_pred = ecx.instantiate_binder_with_infer(projection_pred);
ecx.eq(goal.param_env, goal.predicate.alias, assumption_projection_pred.projection_term)?;

View File

@@ -151,9 +151,7 @@ where
goal: Goal<I, Self>,
assumption: I::Clause,
) -> Result<(), NoSolution> {
let Some(trait_clause) = assumption.as_trait_clause() else {
panic!("fast_reject_assumption should have avoided this");
};
let trait_clause = assumption.as_trait_clause().unwrap();
let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;