fix ty::UnevaluatedConst<I>>->AliasTerm<I> conversion

This commit is contained in:
Waffle Lapkin
2026-04-16 13:11:48 +02:00
parent 59be02e594
commit e8b6c9737e
14 changed files with 43 additions and 37 deletions
@@ -184,7 +184,7 @@ fn instantiate_var<R: PredicateEmittingRelation<Self>>(
relation.register_predicates([ty::PredicateKind::AliasRelate(lhs, rhs, direction)]);
} else {
let Some(source_alias) = source_term.to_alias_term() else {
let Some(source_alias) = source_term.to_alias_term(self.tcx) else {
bug!("generalized `{source_term:?} to infer, not an alias");
};
match source_alias.kind(self.tcx) {
@@ -756,7 +756,8 @@ fn consts(
// path), as doing this new No path breaks some GCE things. I expect GCE to be
// ripped out soon so this shouldn't matter soon.
StructurallyRelateAliases::No if !self.cx().features().generic_const_exprs() => {
self.generalize_alias_term(uv.into()).map(|v| v.expect_const())
self.generalize_alias_term(ty::AliasTerm::from_unevaluated_const(self.cx(), uv))
.map(|v| v.expect_const())
}
_ => {
let ty::UnevaluatedConst { def, args } = uv;
+2 -2
View File
@@ -607,14 +607,14 @@ pub fn into_arg(self) -> GenericArg<'tcx> {
}
}
pub fn to_alias_term(self) -> Option<AliasTerm<'tcx>> {
pub fn to_alias_term(self, tcx: TyCtxt<'tcx>) -> Option<AliasTerm<'tcx>> {
match self.kind() {
TermKind::Ty(ty) => match *ty.kind() {
ty::Alias(alias_ty) => Some(alias_ty.into()),
_ => None,
},
TermKind::Const(ct) => match ct.kind() {
ConstKind::Unevaluated(uv) => Some(uv.into()),
ConstKind::Unevaluated(uv) => Some(AliasTerm::from_unevaluated_const(tcx, uv)),
_ => None,
},
}
@@ -41,14 +41,14 @@ pub(super) fn compute_alias_relate_goal(
// `{type error}` if the alias still contains infer vars, so we also
// accept alias-relate goals where one of the terms is an error.
debug_assert!(
lhs.to_alias_term().is_some()
|| rhs.to_alias_term().is_some()
lhs.to_alias_term(self.cx()).is_some()
|| rhs.to_alias_term(self.cx()).is_some()
|| lhs.is_error()
|| rhs.is_error()
);
// Structurally normalize the lhs.
let lhs = if let Some(alias) = lhs.to_alias_term() {
let lhs = if let Some(alias) = lhs.to_alias_term(self.cx()) {
let term = self.next_term_infer_of_kind(lhs);
self.add_goal(
GoalSource::TypeRelating,
@@ -60,7 +60,7 @@ pub(super) fn compute_alias_relate_goal(
};
// Structurally normalize the rhs.
let rhs = if let Some(alias) = rhs.to_alias_term() {
let rhs = if let Some(alias) = rhs.to_alias_term(self.cx()) {
let term = self.next_term_infer_of_kind(rhs);
self.add_goal(
GoalSource::TypeRelating,
@@ -87,7 +87,7 @@ pub(super) fn compute_alias_relate_goal(
ty::AliasRelationDirection::Equate => ty::Invariant,
ty::AliasRelationDirection::Subtype => ty::Covariant,
};
match (lhs.to_alias_term(), rhs.to_alias_term()) {
match (lhs.to_alias_term(self.cx()), rhs.to_alias_term(self.cx())) {
(None, None) => {
self.relate(param_env, lhs, variance, rhs)?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
@@ -344,7 +344,7 @@ fn structurally_normalize_term(
param_env: I::ParamEnv,
term: I::Term,
) -> Result<I::Term, NoSolution> {
if let Some(_) = term.to_alias_term() {
if let Some(_) = term.to_alias_term(self.cx()) {
let normalized_term = self.next_term_infer_of_kind(term);
let alias_relate_goal = Goal::new(
self.cx(),
@@ -1586,7 +1586,7 @@ pub(super) fn report_projection_error(
}
};
if let Some(lhs) = lhs.to_alias_term()
if let Some(lhs) = lhs.to_alias_term(self.tcx)
&& let ty::AliasTermKind::ProjectionTy { .. }
| ty::AliasTermKind::ProjectionConst { .. } = lhs.kind(self.tcx)
&& let Some((better_type_err, expected_term)) =
@@ -1596,7 +1596,7 @@ pub(super) fn report_projection_error(
Some((lhs, self.resolve_vars_if_possible(expected_term), rhs)),
better_type_err,
)
} else if let Some(rhs) = rhs.to_alias_term()
} else if let Some(rhs) = rhs.to_alias_term(self.tcx)
&& let ty::AliasTermKind::ProjectionTy { .. }
| ty::AliasTermKind::ProjectionConst { .. } = rhs.kind(self.tcx)
&& let Some((better_type_err, expected_term)) =
@@ -107,7 +107,7 @@ fn normalize_alias_term(
let tcx = infcx.tcx;
let recursion_limit = tcx.recursion_limit();
if !recursion_limit.value_within_limit(self.depth) {
let term = alias_term.to_alias_term().unwrap();
let term = alias_term.to_alias_term(tcx).unwrap();
self.at.infcx.err_ctxt().report_overflow_error(
OverflowCause::DeeplyNormalize(term),
@@ -699,8 +699,8 @@ fn process_obligation(
// `generic_const_exprs`
.eq(
DefineOpaqueTypes::Yes,
ty::AliasTerm::from(a),
ty::AliasTerm::from(b),
ty::AliasTerm::from_unevaluated_const(tcx, a),
ty::AliasTerm::from_unevaluated_const(tcx, b),
)
{
return ProcessResult::Changed(mk_pending(
@@ -469,16 +469,20 @@ fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
// feature gate causes a parse error.
let ct = match tcx.def_kind(uv.def) {
DefKind::AssocConst { .. } => match tcx.def_kind(tcx.parent(uv.def)) {
DefKind::Trait => self.normalize_trait_projection(uv.into()).expect_const(),
DefKind::Impl { of_trait: false } => {
self.normalize_inherent_projection(uv.into()).expect_const()
}
DefKind::Trait => self
.normalize_trait_projection(ty::AliasTerm::from_unevaluated_const(tcx, uv))
.expect_const(),
DefKind::Impl { of_trait: false } => self
.normalize_inherent_projection(ty::AliasTerm::from_unevaluated_const(tcx, uv))
.expect_const(),
kind => unreachable!(
"unexpected `DefKind` for const alias' resolution's parent def: {:?}",
kind
),
},
DefKind::Const { .. } => self.normalize_free_alias(uv.into()).expect_const(),
DefKind::Const { .. } => self
.normalize_free_alias(ty::AliasTerm::from_unevaluated_const(tcx, uv))
.expect_const(),
DefKind::AnonConst => {
let ct = ct.super_fold_with(self);
super::with_replaced_escaping_bound_vars(
@@ -285,7 +285,9 @@ fn try_fold_const(
constant,
|constant| crate::traits::evaluate_const(&self.infcx, constant, self.param_env),
),
_ => self.try_fold_free_or_assoc(ty::AliasTerm::from(uv))?.expect_const(),
_ => self
.try_fold_free_or_assoc(ty::AliasTerm::from_unevaluated_const(self.cx(), uv))?
.expect_const(),
};
debug!(?constant, ?self.param_env);
constant.try_super_fold_with(self)
@@ -891,8 +891,8 @@ fn evaluate_predicate_recursively<'o>(
// `generic_const_exprs`
.eq(
DefineOpaqueTypes::Yes,
ty::AliasTerm::from(a),
ty::AliasTerm::from(b),
ty::AliasTerm::from_unevaluated_const(tcx, a),
ty::AliasTerm::from_unevaluated_const(tcx, b),
)
{
return self.evaluate_predicates_recursively(
@@ -41,7 +41,7 @@ fn structurally_normalize_term<E: 'tcx>(
if self.infcx.next_trait_solver() {
let term = term.skip_normalization();
if let None = term.to_alias_term() {
if let None = term.to_alias_term(self.infcx.tcx) {
return Ok(term);
}
@@ -1077,7 +1077,9 @@ fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result {
if matches!(tcx.def_kind(uv.def), DefKind::AssocConst { .. })
&& tcx.def_kind(tcx.parent(uv.def)) == (DefKind::Impl { of_trait: false })
{
self.add_wf_preds_for_inherent_projection(uv.into());
self.add_wf_preds_for_inherent_projection(
ty::AliasTerm::from_unevaluated_const(tcx, uv),
);
return; // Subtree is handled by above function
} else {
let obligations = self.nominal_obligations(uv.def, uv.args);
+4 -2
View File
@@ -432,14 +432,16 @@ fn is_error(self) -> bool {
}
}
fn to_alias_term(self) -> Option<ty::AliasTerm<I>> {
fn to_alias_term(self, interner: I) -> Option<ty::AliasTerm<I>> {
match self.kind() {
ty::TermKind::Ty(ty) => match ty.kind() {
ty::Alias(alias_ty) => Some(alias_ty.into()),
_ => None,
},
ty::TermKind::Const(ct) => match ct.kind() {
ty::ConstKind::Unevaluated(uv) => Some(uv.into()),
ty::ConstKind::Unevaluated(uv) => {
Some(ty::AliasTerm::from_unevaluated_const(interner, uv))
}
_ => None,
},
}
+5 -10
View File
@@ -721,6 +721,11 @@ pub fn new_from_def_id(interner: I, def_id: I::DefId, args: I::GenericArgs) -> A
Self::new_from_args(interner, kind, args)
}
pub fn from_unevaluated_const(interner: I, ct: ty::UnevaluatedConst<I>) -> Self {
let kind = interner.alias_term_kind_from_def_id(ct.def.into());
AliasTerm::new_from_args(interner, kind, ct.args)
}
pub fn expect_ty(self, interner: I) -> ty::AliasTy<I> {
let kind = match self.kind(interner) {
AliasTermKind::ProjectionTy { def_id } => AliasTyKind::Projection { def_id },
@@ -862,16 +867,6 @@ fn from(ty: ty::AliasTy<I>) -> Self {
}
}
impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> {
fn from(ct: ty::UnevaluatedConst<I>) -> Self {
AliasTerm {
args: ct.args,
kind: AliasTermKind::UnevaluatedConst { def_id: ct.def.into() },
_use_alias_term_new_instead: (),
}
}
}
/// This kind of predicate has no *direct* correspondent in the
/// syntax, but it roughly corresponds to the syntactic forms:
///