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