Replace escaping bound vars in ty/ct visiting, not binder visiting
This commit is contained in:
parent
6fa6d0e097
commit
da8d529820
2 changed files with 44 additions and 12 deletions
|
|
@ -1014,7 +1014,11 @@ where
|
|||
return Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal));
|
||||
}
|
||||
|
||||
match assumption.visit_with(&mut FindParamInClause { ecx: self, param_env }) {
|
||||
match assumption.visit_with(&mut FindParamInClause {
|
||||
ecx: self,
|
||||
param_env,
|
||||
universes: vec![],
|
||||
}) {
|
||||
ControlFlow::Break(Err(NoSolution)) => Err(NoSolution),
|
||||
ControlFlow::Break(Ok(())) => Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)),
|
||||
ControlFlow::Continue(()) => Ok(CandidateSource::ParamEnv(ParamEnvSource::Global)),
|
||||
|
|
@ -1025,6 +1029,7 @@ where
|
|||
struct FindParamInClause<'a, 'b, D: SolverDelegate<Interner = I>, I: Interner> {
|
||||
ecx: &'a mut EvalCtxt<'b, D>,
|
||||
param_env: I::ParamEnv,
|
||||
universes: Vec<Option<ty::UniverseIndex>>,
|
||||
}
|
||||
|
||||
impl<D, I> TypeVisitor<I> for FindParamInClause<'_, '_, D, I>
|
||||
|
|
@ -1035,30 +1040,41 @@ where
|
|||
type Result = ControlFlow<Result<(), NoSolution>>;
|
||||
|
||||
fn visit_binder<T: TypeFoldable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
|
||||
self.ecx.enter_forall(t.clone(), |ecx, v| {
|
||||
v.visit_with(&mut FindParamInClause { ecx, param_env: self.param_env })
|
||||
})
|
||||
self.universes.push(None);
|
||||
t.super_visit_with(self)?;
|
||||
self.universes.pop();
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: I::Ty) -> Self::Result {
|
||||
let ty = self.ecx.replace_bound_vars(ty, &mut self.universes);
|
||||
let Ok(ty) = self.ecx.structurally_normalize_ty(self.param_env, ty) else {
|
||||
return ControlFlow::Break(Err(NoSolution));
|
||||
};
|
||||
|
||||
if let ty::Placeholder(_) = ty.kind() {
|
||||
ControlFlow::Break(Ok(()))
|
||||
if let ty::Placeholder(p) = ty.kind() {
|
||||
if p.universe() == ty::UniverseIndex::ROOT {
|
||||
ControlFlow::Break(Ok(()))
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
} else {
|
||||
ty.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, ct: I::Const) -> Self::Result {
|
||||
let ct = self.ecx.replace_bound_vars(ct, &mut self.universes);
|
||||
let Ok(ct) = self.ecx.structurally_normalize_const(self.param_env, ct) else {
|
||||
return ControlFlow::Break(Err(NoSolution));
|
||||
};
|
||||
|
||||
if let ty::ConstKind::Placeholder(_) = ct.kind() {
|
||||
ControlFlow::Break(Ok(()))
|
||||
if let ty::ConstKind::Placeholder(p) = ct.kind() {
|
||||
if p.universe() == ty::UniverseIndex::ROOT {
|
||||
ControlFlow::Break(Ok(()))
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
} else {
|
||||
ct.super_visit_with(self)
|
||||
}
|
||||
|
|
@ -1066,10 +1082,17 @@ where
|
|||
|
||||
fn visit_region(&mut self, r: I::Region) -> Self::Result {
|
||||
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(..) => {
|
||||
unreachable!()
|
||||
ty::ReStatic | ty::ReError(_) | ty::ReBound(..) => ControlFlow::Continue(()),
|
||||
ty::RePlaceholder(p) => {
|
||||
if p.universe() == ty::UniverseIndex::ROOT {
|
||||
ControlFlow::Break(Ok(()))
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
ty::ReVar(_) => ControlFlow::Break(Ok(())),
|
||||
ty::ReErased | ty::ReEarlyParam(_) | ty::ReLateParam(_) => {
|
||||
unreachable!("unexpected region in param-env clause")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ use tracing::{debug, instrument, trace};
|
|||
use super::has_only_region_constraints;
|
||||
use crate::coherence;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::placeholder::BoundVarReplacer;
|
||||
use crate::solve::inspect::{self, ProofTreeBuilder};
|
||||
use crate::solve::search_graph::SearchGraph;
|
||||
use crate::solve::{
|
||||
|
|
@ -1232,6 +1233,14 @@ where
|
|||
) -> Result<Certainty, NoSolution> {
|
||||
self.delegate.is_transmutable(dst, src, assume)
|
||||
}
|
||||
|
||||
pub(super) fn replace_bound_vars<T: TypeFoldable<I>>(
|
||||
&self,
|
||||
t: T,
|
||||
universes: &mut Vec<Option<ty::UniverseIndex>>,
|
||||
) -> T {
|
||||
BoundVarReplacer::replace_bound_vars(&**self.delegate, universes, t).0
|
||||
}
|
||||
}
|
||||
|
||||
/// Eagerly replace aliases with inference variables, emitting `AliasRelate`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue