From e8b6c9737e915362a3138ece2e6fbfee863918af Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 16 Apr 2026 13:11:48 +0200 Subject: [PATCH] fix `ty::UnevaluatedConst>`->`AliasTerm` conversion --- .../rustc_infer/src/infer/relate/generalize.rs | 5 +++-- compiler/rustc_middle/src/ty/mod.rs | 4 ++-- .../src/solve/alias_relate.rs | 10 +++++----- compiler/rustc_next_trait_solver/src/solve/mod.rs | 2 +- .../error_reporting/traits/fulfillment_errors.rs | 4 ++-- .../rustc_trait_selection/src/solve/normalize.rs | 2 +- .../rustc_trait_selection/src/traits/fulfill.rs | 4 ++-- .../rustc_trait_selection/src/traits/normalize.rs | 14 +++++++++----- .../src/traits/query/normalize.rs | 4 +++- .../src/traits/select/mod.rs | 4 ++-- .../src/traits/structural_normalize.rs | 2 +- compiler/rustc_trait_selection/src/traits/wf.rs | 4 +++- compiler/rustc_type_ir/src/inherent.rs | 6 ++++-- compiler/rustc_type_ir/src/predicate.rs | 15 +++++---------- 14 files changed, 43 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 8a17d837b29b..5ec56b3e9dc4 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -184,7 +184,7 @@ fn instantiate_var>( 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; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index bad3782057bc..b935f996a464 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -607,14 +607,14 @@ pub fn into_arg(self) -> GenericArg<'tcx> { } } - pub fn to_alias_term(self) -> Option> { + pub fn to_alias_term(self, tcx: TyCtxt<'tcx>) -> Option> { 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, }, } diff --git a/compiler/rustc_next_trait_solver/src/solve/alias_relate.rs b/compiler/rustc_next_trait_solver/src/solve/alias_relate.rs index f7bd46009432..7c79dba61a6d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/alias_relate.rs +++ b/compiler/rustc_next_trait_solver/src/solve/alias_relate.rs @@ -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) diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index d37b328920ce..793d45f22d39 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -344,7 +344,7 @@ fn structurally_normalize_term( param_env: I::ParamEnv, term: I::Term, ) -> Result { - 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(), diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 36c80f6eb411..de4a382800b2 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -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)) = diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 7d4bf731454e..7a25b3886606 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -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), diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 88cb18e5d367..11ff9911469e 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -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( diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index d5d96f63020d..55f1f861921e 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -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( diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index fa1087591985..21d437a4a72c 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -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) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 83711be4d9f0..28b9ce24178d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -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( diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs index 03edfeb06d8c..fe00e9b4f842 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs @@ -41,7 +41,7 @@ fn structurally_normalize_term( 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); } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index cf69b7d53979..66a2fcaa562d 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -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); diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index a336313e90b8..a8757e045d17 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -432,14 +432,16 @@ fn is_error(self) -> bool { } } - fn to_alias_term(self) -> Option> { + fn to_alias_term(self, interner: I) -> Option> { 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, }, } diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index e70a802bcfbe..0545fbfda6e4 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -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) -> 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 { let kind = match self.kind(interner) { AliasTermKind::ProjectionTy { def_id } => AliasTyKind::Projection { def_id }, @@ -862,16 +867,6 @@ fn from(ty: ty::AliasTy) -> Self { } } -impl From> for AliasTerm { - fn from(ct: ty::UnevaluatedConst) -> 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: ///