Unify normalization of terms in deeply normalize
This commit is contained in:
@@ -823,6 +823,13 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
ty::Region::new_var(self.tcx, region_var)
|
||||
}
|
||||
|
||||
pub fn next_term_var_of_kind(&self, term: ty::Term<'tcx>, span: Span) -> ty::Term<'tcx> {
|
||||
match term.kind() {
|
||||
ty::TermKind::Ty(_) => self.next_ty_var(span).into(),
|
||||
ty::TermKind::Const(_) => self.next_const_var(span).into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the universe that the region `r` was created in. For
|
||||
/// most regions (e.g., `'static`, named regions from the user,
|
||||
/// etc) this is the root universe U0. For inference variables or
|
||||
|
||||
@@ -206,10 +206,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
|
||||
let infcx = self.goal.infcx;
|
||||
match goal.predicate.kind().no_bound_vars() {
|
||||
Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => {
|
||||
let unconstrained_term = match term.kind() {
|
||||
ty::TermKind::Ty(_) => infcx.next_ty_var(span).into(),
|
||||
ty::TermKind::Const(_) => infcx.next_const_var(span).into(),
|
||||
};
|
||||
let unconstrained_term = infcx.next_term_var_of_kind(term, span);
|
||||
let goal =
|
||||
goal.with(infcx.tcx, ty::NormalizesTo { alias, term: unconstrained_term });
|
||||
// We have to use a `probe` here as evaluating a `NormalizesTo` can constrain the
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use std::assert_matches::assert_matches;
|
||||
use std::fmt::Debug;
|
||||
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
@@ -96,66 +95,18 @@ impl<'tcx, E> NormalizationFolder<'_, 'tcx, E>
|
||||
where
|
||||
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
|
||||
{
|
||||
fn normalize_alias_ty(&mut self, alias_ty: Ty<'tcx>) -> Result<Ty<'tcx>, Vec<E>> {
|
||||
assert_matches!(alias_ty.kind(), ty::Alias(..));
|
||||
|
||||
let infcx = self.at.infcx;
|
||||
let tcx = infcx.tcx;
|
||||
let recursion_limit = tcx.recursion_limit();
|
||||
if !recursion_limit.value_within_limit(self.depth) {
|
||||
let ty::Alias(_, data) = *alias_ty.kind() else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
self.at.infcx.err_ctxt().report_overflow_error(
|
||||
OverflowCause::DeeplyNormalize(data.into()),
|
||||
self.at.cause.span,
|
||||
true,
|
||||
|_| {},
|
||||
);
|
||||
}
|
||||
|
||||
self.depth += 1;
|
||||
|
||||
let new_infer_ty = infcx.next_ty_var(self.at.cause.span);
|
||||
let obligation = Obligation::new(
|
||||
tcx,
|
||||
self.at.cause.clone(),
|
||||
self.at.param_env,
|
||||
ty::PredicateKind::AliasRelate(
|
||||
alias_ty.into(),
|
||||
new_infer_ty.into(),
|
||||
ty::AliasRelationDirection::Equate,
|
||||
),
|
||||
);
|
||||
|
||||
self.fulfill_cx.register_predicate_obligation(infcx, obligation);
|
||||
self.select_all_and_stall_coroutine_predicates()?;
|
||||
|
||||
// Alias is guaranteed to be fully structurally resolved,
|
||||
// so we can super fold here.
|
||||
let ty = infcx.resolve_vars_if_possible(new_infer_ty);
|
||||
let result = ty.try_super_fold_with(self)?;
|
||||
self.depth -= 1;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn normalize_unevaluated_const(
|
||||
fn normalize_alias_term(
|
||||
&mut self,
|
||||
alias_ct: ty::Const<'tcx>,
|
||||
) -> Result<ty::Const<'tcx>, Vec<E>> {
|
||||
assert_matches!(alias_ct.kind(), ty::ConstKind::Unevaluated(..));
|
||||
|
||||
alias_term: ty::Term<'tcx>,
|
||||
) -> Result<ty::Term<'tcx>, Vec<E>> {
|
||||
let infcx = self.at.infcx;
|
||||
let tcx = infcx.tcx;
|
||||
let recursion_limit = tcx.recursion_limit();
|
||||
if !recursion_limit.value_within_limit(self.depth) {
|
||||
let ty::ConstKind::Unevaluated(uv) = alias_ct.kind() else {
|
||||
unreachable!();
|
||||
};
|
||||
let term = alias_term.to_alias_term().unwrap();
|
||||
|
||||
self.at.infcx.err_ctxt().report_overflow_error(
|
||||
OverflowCause::DeeplyNormalize(uv.into()),
|
||||
OverflowCause::DeeplyNormalize(term),
|
||||
self.at.cause.span,
|
||||
true,
|
||||
|_| {},
|
||||
@@ -164,14 +115,14 @@ where
|
||||
|
||||
self.depth += 1;
|
||||
|
||||
let new_infer_ct = infcx.next_const_var(self.at.cause.span);
|
||||
let infer_term = infcx.next_term_var_of_kind(alias_term, self.at.cause.span);
|
||||
let obligation = Obligation::new(
|
||||
tcx,
|
||||
self.at.cause.clone(),
|
||||
self.at.param_env,
|
||||
ty::PredicateKind::AliasRelate(
|
||||
alias_ct.into(),
|
||||
new_infer_ct.into(),
|
||||
alias_term.into(),
|
||||
infer_term.into(),
|
||||
ty::AliasRelationDirection::Equate,
|
||||
),
|
||||
);
|
||||
@@ -181,8 +132,13 @@ where
|
||||
|
||||
// Alias is guaranteed to be fully structurally resolved,
|
||||
// so we can super fold here.
|
||||
let ct = infcx.resolve_vars_if_possible(new_infer_ct);
|
||||
let result = ct.try_super_fold_with(self)?;
|
||||
let term = infcx.resolve_vars_if_possible(infer_term);
|
||||
// super-folding the `term` will directly fold the `Ty` or `Const` so
|
||||
// we have to match on the term and super-fold them manually.
|
||||
let result = match term.kind() {
|
||||
ty::TermKind::Ty(ty) => ty.try_super_fold_with(self)?.into(),
|
||||
ty::TermKind::Const(ct) => ct.try_super_fold_with(self)?.into(),
|
||||
};
|
||||
self.depth -= 1;
|
||||
Ok(result)
|
||||
}
|
||||
@@ -242,7 +198,8 @@ where
|
||||
if ty.has_escaping_bound_vars() {
|
||||
let (ty, mapped_regions, mapped_types, mapped_consts) =
|
||||
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, ty);
|
||||
let result = ensure_sufficient_stack(|| self.normalize_alias_ty(ty))?;
|
||||
let result =
|
||||
ensure_sufficient_stack(|| self.normalize_alias_term(ty.into()))?.expect_type();
|
||||
Ok(PlaceholderReplacer::replace_placeholders(
|
||||
infcx,
|
||||
mapped_regions,
|
||||
@@ -252,7 +209,7 @@ where
|
||||
result,
|
||||
))
|
||||
} else {
|
||||
ensure_sufficient_stack(|| self.normalize_alias_ty(ty))
|
||||
Ok(ensure_sufficient_stack(|| self.normalize_alias_term(ty.into()))?.expect_type())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,7 +226,8 @@ where
|
||||
if ct.has_escaping_bound_vars() {
|
||||
let (ct, mapped_regions, mapped_types, mapped_consts) =
|
||||
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, ct);
|
||||
let result = ensure_sufficient_stack(|| self.normalize_unevaluated_const(ct))?;
|
||||
let result =
|
||||
ensure_sufficient_stack(|| self.normalize_alias_term(ct.into()))?.expect_const();
|
||||
Ok(PlaceholderReplacer::replace_placeholders(
|
||||
infcx,
|
||||
mapped_regions,
|
||||
@@ -279,7 +237,7 @@ where
|
||||
result,
|
||||
))
|
||||
} else {
|
||||
ensure_sufficient_stack(|| self.normalize_unevaluated_const(ct))
|
||||
Ok(ensure_sufficient_stack(|| self.normalize_alias_term(ct.into()))?.expect_const())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,10 +39,7 @@ impl<'tcx> At<'_, 'tcx> {
|
||||
return Ok(term);
|
||||
}
|
||||
|
||||
let new_infer = match term.kind() {
|
||||
ty::TermKind::Ty(_) => self.infcx.next_ty_var(self.cause.span).into(),
|
||||
ty::TermKind::Const(_) => self.infcx.next_const_var(self.cause.span).into(),
|
||||
};
|
||||
let new_infer = self.infcx.next_term_var_of_kind(term, self.cause.span);
|
||||
|
||||
// We simply emit an `alias-eq` goal here, since that will take care of
|
||||
// normalizing the LHS of the projection until it is a rigid projection
|
||||
|
||||
Reference in New Issue
Block a user