about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-05-13 10:00:38 -0400
committerMichael Goulet <michael@errs.io>2024-05-13 11:59:42 -0400
commit3bcdf3058ef3eaef5042661cf8301acfbcddce65 (patch)
tree3f91249a55f4a965a51ca35dce52e63b55aa398b /compiler/rustc_trait_selection
parentecbe3fd550fccd2cba17ea7e86539bf3e0bfc618 (diff)
downloadrust-3bcdf3058ef3eaef5042661cf8301acfbcddce65.tar.gz
rust-3bcdf3058ef3eaef5042661cf8301acfbcddce65.zip
split out AliasTy -> AliasTerm
Diffstat (limited to 'compiler/rustc_trait_selection')
-rw-r--r--compiler/rustc_trait_selection/src/solve/alias_relate.rs6
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs8
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs10
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalize.rs11
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs35
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs14
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs24
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs46
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/normalize.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs151
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs41
20 files changed, 202 insertions, 194 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/alias_relate.rs b/compiler/rustc_trait_selection/src/solve/alias_relate.rs
index e079809aecc..65cc0a45857 100644
--- a/compiler/rustc_trait_selection/src/solve/alias_relate.rs
+++ b/compiler/rustc_trait_selection/src/solve/alias_relate.rs
@@ -29,7 +29,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         let Goal { param_env, predicate: (lhs, rhs, direction) } = goal;
 
         // Structurally normalize the lhs.
-        let lhs = if let Some(alias) = lhs.to_alias_ty(self.tcx()) {
+        let lhs = if let Some(alias) = lhs.to_alias_term() {
             let term = self.next_term_infer_of_kind(lhs);
             self.add_normalizes_to_goal(goal.with(tcx, ty::NormalizesTo { alias, term }));
             term
@@ -38,7 +38,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         };
 
         // Structurally normalize the rhs.
-        let rhs = if let Some(alias) = rhs.to_alias_ty(self.tcx()) {
+        let rhs = if let Some(alias) = rhs.to_alias_term() {
             let term = self.next_term_infer_of_kind(rhs);
             self.add_normalizes_to_goal(goal.with(tcx, ty::NormalizesTo { alias, term }));
             term
@@ -56,7 +56,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             ty::AliasRelationDirection::Equate => ty::Variance::Invariant,
             ty::AliasRelationDirection::Subtype => ty::Variance::Covariant,
         };
-        match (lhs.to_alias_ty(tcx), rhs.to_alias_ty(tcx)) {
+        match (lhs.to_alias_term(), rhs.to_alias_term()) {
             (None, None) => {
                 self.relate(param_env, lhs, variance, rhs)?;
                 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
index eeaef028cdb..1474f8a679b 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
@@ -698,7 +698,7 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>(
                 old_ty,
                 None,
                 "{} has two generic parameters: {} and {}",
-                proj.projection_ty,
+                proj.projection_term,
                 proj.term,
                 old_ty.unwrap()
             );
@@ -739,7 +739,11 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceProjectionWith<'_, 'tcx> {
             // FIXME: Technically this equate could be fallible...
             self.nested.extend(
                 self.ecx
-                    .eq_and_get_goals(self.param_env, alias_ty, proj.projection_ty)
+                    .eq_and_get_goals(
+                        self.param_env,
+                        alias_ty,
+                        proj.projection_term.expect_ty(self.ecx.tcx()),
+                    )
                     .expect("expected to be able to unify goal projection with dyn's projection"),
             );
             proj.term.ty().unwrap()
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index 8614c17cabf..06c30bb82cf 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -747,7 +747,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     pub(super) fn relate_rigid_alias_non_alias(
         &mut self,
         param_env: ty::ParamEnv<'tcx>,
-        alias: ty::AliasTy<'tcx>,
+        alias: ty::AliasTerm<'tcx>,
         variance: ty::Variance,
         term: ty::Term<'tcx>,
     ) -> Result<(), NoSolution> {
@@ -764,13 +764,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             // Alternatively we could modify `Equate` for this case by adding another
             // variant to `StructurallyRelateAliases`.
             let identity_args = self.fresh_args_for_item(alias.def_id);
-            let rigid_ctor = ty::AliasTy::new(tcx, alias.def_id, identity_args);
-            let ctor_ty = rigid_ctor.to_ty(tcx);
+            let rigid_ctor = ty::AliasTerm::new(tcx, alias.def_id, identity_args);
+            let ctor_term = rigid_ctor.to_term(tcx);
             let InferOk { value: (), obligations } = self
                 .infcx
                 .at(&ObligationCause::dummy(), param_env)
-                .trace(term, ctor_ty.into())
-                .eq_structurally_relating_aliases(term, ctor_ty.into())?;
+                .trace(term, ctor_term)
+                .eq_structurally_relating_aliases(term, ctor_term)?;
             debug_assert!(obligations.is_empty());
             self.relate(param_env, alias, variance, rigid_ctor)
         } else {
diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs
index 1ac1827bf1c..5d5161e092e 100644
--- a/compiler/rustc_trait_selection/src/solve/normalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalize.rs
@@ -7,7 +7,7 @@ use rustc_infer::infer::InferCtxt;
 use rustc_infer::traits::TraitEngineExt;
 use rustc_infer::traits::{FulfillmentError, Obligation, TraitEngine};
 use rustc_middle::traits::ObligationCause;
-use rustc_middle::ty::{self, AliasTy, Ty, TyCtxt, UniverseIndex};
+use rustc_middle::ty::{self, Ty, TyCtxt, UniverseIndex};
 use rustc_middle::ty::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
 
@@ -63,7 +63,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
             };
 
             self.at.infcx.err_ctxt().report_overflow_error(
-                OverflowCause::DeeplyNormalize(data),
+                OverflowCause::DeeplyNormalize(data.into()),
                 self.at.cause.span,
                 true,
                 |_| {},
@@ -108,7 +108,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
         let recursion_limit = tcx.recursion_limit();
         if !recursion_limit.value_within_limit(self.depth) {
             self.at.infcx.err_ctxt().report_overflow_error(
-                OverflowCause::DeeplyNormalize(ty::AliasTy::new(tcx, uv.def, uv.args)),
+                OverflowCause::DeeplyNormalize(uv.into()),
                 self.at.cause.span,
                 true,
                 |_| {},
@@ -122,10 +122,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
             tcx,
             self.at.cause.clone(),
             self.at.param_env,
-            ty::NormalizesTo {
-                alias: AliasTy::new(tcx, uv.def, uv.args),
-                term: new_infer_ct.into(),
-            },
+            ty::NormalizesTo { alias: uv.into(), term: new_infer_ct.into() },
         );
 
         let result = if infcx.predicate_may_hold(&obligation) {
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs
index 439f9eec831..353bdb9caff 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs
@@ -15,7 +15,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
     ) -> QueryResult<'tcx> {
         let tcx = self.tcx();
-        let inherent = goal.predicate.alias;
+        let inherent = goal.predicate.alias.expect_ty(tcx);
 
         let impl_def_id = tcx.parent(inherent.def_id);
         let impl_args = self.fresh_args_for_item(impl_def_id);
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
index 8d5c5d2a063..9dd76e55235 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
@@ -40,19 +40,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             Ok(res) => Ok(res),
             Err(NoSolution) => {
                 let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
-                if alias.opt_kind(self.tcx()).is_some() {
-                    self.relate_rigid_alias_non_alias(
-                        param_env,
-                        alias,
-                        ty::Variance::Invariant,
-                        term,
-                    )?;
-                    self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
-                } else {
-                    // FIXME(generic_const_exprs): we currently do not support rigid
-                    // unevaluated constants.
-                    Err(NoSolution)
-                }
+                self.relate_rigid_alias_non_alias(param_env, alias, ty::Variance::Invariant, term)?;
+                self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
             }
         }
     }
@@ -132,7 +121,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
                     ecx.eq(
                         goal.param_env,
                         goal.predicate.alias,
-                        assumption_projection_pred.projection_ty,
+                        assumption_projection_pred.projection_term,
                     )?;
 
                     ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term);
@@ -373,7 +362,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
 
         let pred = tupled_inputs_and_output
             .map_bound(|(inputs, output)| ty::ProjectionPredicate {
-                projection_ty: ty::AliasTy::new(
+                projection_term: ty::AliasTerm::new(
                     tcx,
                     goal.predicate.def_id(),
                     [goal.predicate.self_ty(), inputs],
@@ -425,9 +414,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
                      output_coroutine_ty,
                      coroutine_return_ty,
                  }| {
-                    let (projection_ty, term) = match tcx.item_name(goal.predicate.def_id()) {
+                    let (projection_term, term) = match tcx.item_name(goal.predicate.def_id()) {
                         sym::CallOnceFuture => (
-                            ty::AliasTy::new(
+                            ty::AliasTerm::new(
                                 tcx,
                                 goal.predicate.def_id(),
                                 [goal.predicate.self_ty(), tupled_inputs_ty],
@@ -435,7 +424,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
                             output_coroutine_ty.into(),
                         ),
                         sym::CallRefFuture => (
-                            ty::AliasTy::new(
+                            ty::AliasTerm::new(
                                 tcx,
                                 goal.predicate.def_id(),
                                 [
@@ -447,7 +436,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
                             output_coroutine_ty.into(),
                         ),
                         sym::Output => (
-                            ty::AliasTy::new(
+                            ty::AliasTerm::new(
                                 tcx,
                                 goal.predicate.def_id(),
                                 [
@@ -459,7 +448,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
                         ),
                         name => bug!("no such associated type: {name}"),
                     };
-                    ty::ProjectionPredicate { projection_ty, term }
+                    ty::ProjectionPredicate { projection_term, term }
                 },
             )
             .to_predicate(tcx);
@@ -636,7 +625,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
             CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             ty::ProjectionPredicate {
-                projection_ty: ty::AliasTy::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]),
+                projection_term: ty::AliasTerm::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]),
                 term,
             }
             .to_predicate(tcx),
@@ -668,7 +657,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
             CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             ty::ProjectionPredicate {
-                projection_ty: ty::AliasTy::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]),
+                projection_term: ty::AliasTerm::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]),
                 term,
             }
             .to_predicate(tcx),
@@ -752,7 +741,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
             CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             ty::ProjectionPredicate {
-                projection_ty: ty::AliasTy::new(
+                projection_term: ty::AliasTerm::new(
                     ecx.tcx(),
                     goal.predicate.def_id(),
                     [self_ty, coroutine.resume_ty()],
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index 74b3db71e78..0f1be1072a8 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -11,19 +11,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         goal: Goal<'tcx, ProjectionPredicate<'tcx>>,
     ) -> QueryResult<'tcx> {
         let tcx = self.tcx();
-        let projection_term = match goal.predicate.term.unpack() {
-            ty::TermKind::Ty(_) => goal.predicate.projection_ty.to_ty(tcx).into(),
-            ty::TermKind::Const(_) => ty::Const::new_unevaluated(
-                tcx,
-                ty::UnevaluatedConst::new(
-                    goal.predicate.projection_ty.def_id,
-                    goal.predicate.projection_ty.args,
-                ),
-                tcx.type_of(goal.predicate.projection_ty.def_id)
-                    .instantiate(tcx, goal.predicate.projection_ty.args),
-            )
-            .into(),
-        };
+        let projection_term = goal.predicate.projection_term.to_term(tcx);
         let goal = goal.with(
             tcx,
             ty::PredicateKind::AliasRelate(
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 053de2c673b..60562acfe93 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -540,11 +540,11 @@ impl<'tcx> AutoTraitFinder<'tcx> {
         finished_map
     }
 
-    fn is_param_no_infer(&self, args: GenericArgsRef<'_>) -> bool {
+    fn is_param_no_infer(&self, args: GenericArgsRef<'tcx>) -> bool {
         self.is_of_param(args.type_at(0)) && !args.types().any(|t| t.has_infer_types())
     }
 
-    pub fn is_of_param(&self, ty: Ty<'_>) -> bool {
+    pub fn is_of_param(&self, ty: Ty<'tcx>) -> bool {
         match ty.kind() {
             ty::Param(_) => true,
             ty::Alias(ty::Projection, p) => self.is_of_param(p.self_ty()),
@@ -552,9 +552,9 @@ impl<'tcx> AutoTraitFinder<'tcx> {
         }
     }
 
-    fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool {
+    fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'tcx>) -> bool {
         if let Some(ty) = p.term().skip_binder().ty() {
-            matches!(ty.kind(), ty::Alias(ty::Projection, proj) if proj == &p.skip_binder().projection_ty)
+            matches!(ty.kind(), ty::Alias(ty::Projection, proj) if proj == &p.skip_binder().projection_term.expect_ty(self.tcx))
         } else {
             false
         }
@@ -612,7 +612,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
                     // an inference variable.
                     // Additionally, we check if we've seen this predicate before,
                     // to avoid rendering duplicate bounds to the user.
-                    if self.is_param_no_infer(p.skip_binder().projection_ty.args)
+                    if self.is_param_no_infer(p.skip_binder().projection_term.args)
                         && !p.term().skip_binder().has_infer_types()
                         && is_new_pred
                     {
@@ -684,7 +684,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
                     // and turn them into an explicit negative impl for our type.
                     debug!("Projecting and unifying projection predicate {:?}", predicate);
 
-                    match project::poly_project_and_unify_type(selcx, &obligation.with(self.tcx, p))
+                    match project::poly_project_and_unify_term(selcx, &obligation.with(self.tcx, p))
                     {
                         ProjectAndUnifyResult::MismatchedProjectionTypes(e) => {
                             debug!(
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 59725ce9de0..9069456b6e7 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -1095,11 +1095,11 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
             Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr))) => tr.trait_ref,
             Some(ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)))
                 if matches!(
-                    infcx.tcx.def_kind(proj.projection_ty.def_id),
+                    infcx.tcx.def_kind(proj.projection_term.def_id),
                     DefKind::AssocTy | DefKind::AssocConst
                 ) =>
             {
-                proj.projection_ty.trait_ref(infcx.tcx)
+                proj.projection_term.trait_ref(infcx.tcx)
             }
             _ => return,
         };
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index ea1752a6e98..efa7c3959c3 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1104,9 +1104,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                             .iter()
                             .find_map(|pred| {
                                 if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
-                        && Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
+                        && Some(proj.projection_term.def_id) == self.tcx.lang_items().fn_once_output()
                         // args tuple will always be args[1]
-                        && let ty::Tuple(args) = proj.projection_ty.args.type_at(1).kind()
+                        && let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind()
                                 {
                                     Some((
                                         DefIdOrName::DefId(def_id),
@@ -1148,10 +1148,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                         };
                         param_env.caller_bounds().iter().find_map(|pred| {
                             if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
-                        && Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
-                        && proj.projection_ty.self_ty() == found
+                        && Some(proj.projection_term.def_id) == self.tcx.lang_items().fn_once_output()
+                        && proj.projection_term.self_ty() == found
                         // args tuple will always be args[1]
-                        && let ty::Tuple(args) = proj.projection_ty.args.type_at(1).kind()
+                        && let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind()
                             {
                                 Some((
                                     name,
@@ -3845,11 +3845,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     && let Some(found) = failed_pred.skip_binder().term.ty()
                 {
                     type_diffs = vec![Sorts(ty::error::ExpectedFound {
-                        expected: Ty::new_alias(
-                            self.tcx,
-                            ty::Projection,
-                            where_pred.skip_binder().projection_ty,
-                        ),
+                        expected: where_pred
+                            .skip_binder()
+                            .projection_term
+                            .expect_ty(self.tcx)
+                            .to_ty(self.tcx),
                         found,
                     })];
                 }
@@ -4274,7 +4274,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             // This corresponds to `<ExprTy as Iterator>::Item = _`.
             let projection = ty::Binder::dummy(ty::PredicateKind::Clause(
                 ty::ClauseKind::Projection(ty::ProjectionPredicate {
-                    projection_ty: ty::AliasTy::new(self.tcx, proj.def_id, args),
+                    projection_term: ty::AliasTerm::new(self.tcx, proj.def_id, args),
                     term: ty.into(),
                 }),
             ));
@@ -4971,7 +4971,7 @@ fn point_at_assoc_type_restriction<G: EmissionGuarantee>(
     let ty::ClauseKind::Projection(proj) = clause else {
         return;
     };
-    let name = tcx.item_name(proj.projection_ty.def_id);
+    let name = tcx.item_name(proj.projection_term.def_id);
     let mut predicates = generics.predicates.iter().peekable();
     let mut prev: Option<&hir::WhereBoundPredicate<'_>> = None;
     while let Some(pred) = predicates.next() {
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 08ffe37b8b4..8f6e997e3b7 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -62,7 +62,7 @@ use super::{
 pub use rustc_infer::traits::error_reporting::*;
 
 pub enum OverflowCause<'tcx> {
-    DeeplyNormalize(ty::AliasTy<'tcx>),
+    DeeplyNormalize(ty::AliasTerm<'tcx>),
     TraitSolver(ty::Predicate<'tcx>),
 }
 
@@ -246,10 +246,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         }
 
         let mut err = match cause {
-            OverflowCause::DeeplyNormalize(alias_ty) => {
-                let alias_ty = self.resolve_vars_if_possible(alias_ty);
-                let kind = alias_ty.opt_kind(self.tcx).map_or("alias", |k| k.descr());
-                let alias_str = with_short_path(self.tcx, alias_ty);
+            OverflowCause::DeeplyNormalize(alias_term) => {
+                let alias_term = self.resolve_vars_if_possible(alias_term);
+                let kind = alias_term.kind(self.tcx).descr();
+                let alias_str = with_short_path(self.tcx, alias_term);
                 struct_span_code_err!(
                     self.dcx(),
                     span,
@@ -1468,7 +1468,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         );
 
         let param_env = ty::ParamEnv::empty();
-        self.can_eq(param_env, goal.projection_ty, assumption.projection_ty)
+        self.can_eq(param_env, goal.projection_term, assumption.projection_term)
             && self.can_eq(param_env, goal.term, assumption.term)
     }
 
@@ -1583,23 +1583,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     infer::BoundRegionConversionTime::HigherRankedType,
                     bound_predicate.rebind(data),
                 );
-                let unnormalized_term = match data.term.unpack() {
-                    ty::TermKind::Ty(_) => Ty::new_projection(
-                        self.tcx,
-                        data.projection_ty.def_id,
-                        data.projection_ty.args,
-                    )
-                    .into(),
-                    ty::TermKind::Const(ct) => ty::Const::new_unevaluated(
-                        self.tcx,
-                        ty::UnevaluatedConst {
-                            def: data.projection_ty.def_id,
-                            args: data.projection_ty.args,
-                        },
-                        ct.ty(),
-                    )
-                    .into(),
-                };
+                let unnormalized_term = data.projection_term.to_term(self.tcx);
                 // FIXME(-Znext-solver): For diagnostic purposes, it would be nice
                 // to deeply normalize this type.
                 let normalized_term =
@@ -1664,13 +1648,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     return None;
                 };
 
-                let trait_assoc_item = self.tcx.opt_associated_item(proj.projection_ty.def_id)?;
+                let trait_assoc_item = self.tcx.opt_associated_item(proj.projection_term.def_id)?;
                 let trait_assoc_ident = trait_assoc_item.ident(self.tcx);
 
                 let mut associated_items = vec![];
                 self.tcx.for_each_relevant_impl(
-                    self.tcx.trait_of_item(proj.projection_ty.def_id)?,
-                    proj.projection_ty.self_ty(),
+                    self.tcx.trait_of_item(proj.projection_term.def_id)?,
+                    proj.projection_term.self_ty(),
                     |impl_def_id| {
                         associated_items.extend(
                             self.tcx
@@ -1739,11 +1723,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         normalized_ty: ty::Term<'tcx>,
         expected_ty: ty::Term<'tcx>,
     ) -> Option<String> {
-        let trait_def_id = pred.projection_ty.trait_def_id(self.tcx);
-        let self_ty = pred.projection_ty.self_ty();
+        let trait_def_id = pred.projection_term.trait_def_id(self.tcx);
+        let self_ty = pred.projection_term.self_ty();
 
         with_forced_trimmed_paths! {
-            if Some(pred.projection_ty.def_id) == self.tcx.lang_items().fn_once_output() {
+            if Some(pred.projection_term.def_id) == self.tcx.lang_items().fn_once_output() {
                 let fn_kind = self_ty.prefix_string(self.tcx);
                 let item = match self_ty.kind() {
                     ty::FnDef(def, _) => self.tcx.item_name(*def).to_string(),
@@ -2622,14 +2606,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 }
 
                 if let Err(guar) =
-                    self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_ty.def_id))
+                    self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_term.def_id))
                 {
                     // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
                     // other `Foo` impls are incoherent.
                     return guar;
                 }
                 let arg = data
-                    .projection_ty
+                    .projection_term
                     .args
                     .iter()
                     .chain(Some(data.term.into_arg()))
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index e3497c646db..dc32db09034 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -770,13 +770,13 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
             }
         }
 
-        match project::poly_project_and_unify_type(&mut self.selcx, &project_obligation) {
+        match project::poly_project_and_unify_term(&mut self.selcx, &project_obligation) {
             ProjectAndUnifyResult::Holds(os) => ProcessResult::Changed(mk_pending(os)),
             ProjectAndUnifyResult::FailedNormalization => {
                 stalled_on.clear();
                 stalled_on.extend(args_infer_vars(
                     &self.selcx,
-                    project_obligation.predicate.map_bound(|pred| pred.projection_ty.args),
+                    project_obligation.predicate.map_bound(|pred| pred.projection_term.args),
                 ));
                 ProcessResult::Unchanged
             }
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 56f8b4b9cdb..2325e45467e 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -51,7 +51,7 @@ pub use self::object_safety::hir_ty_lowering_object_safety_violations;
 pub use self::object_safety::is_vtable_safe_method;
 pub use self::object_safety::object_safety_violations_for_assoc_item;
 pub use self::object_safety::ObjectSafetyViolation;
-pub use self::project::{normalize_inherent_projection, normalize_projection_type};
+pub use self::project::{normalize_inherent_projection, normalize_projection_ty};
 pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
 pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
 pub use self::specialize::specialization_graph::FutureCompatOverlapError;
diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs
index 43f4fa8e81c..d10aee2d4e2 100644
--- a/compiler/rustc_trait_selection/src/traits/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/normalize.rs
@@ -213,7 +213,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
                         let recursion_limit = self.interner().recursion_limit();
                         if !recursion_limit.value_within_limit(self.depth) {
                             self.selcx.infcx.err_ctxt().report_overflow_error(
-                                OverflowCause::DeeplyNormalize(data),
+                                OverflowCause::DeeplyNormalize(data.into()),
                                 self.cause.span,
                                 true,
                                 |_| {},
@@ -238,7 +238,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
                 // register an obligation to *later* project, since we know
                 // there won't be bound vars there.
                 let data = data.fold_with(self);
-                let normalized_ty = project::normalize_projection_type(
+                let normalized_ty = project::normalize_projection_ty(
                     self.selcx,
                     self.param_env,
                     data,
@@ -273,10 +273,10 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
                 let (data, mapped_regions, mapped_types, mapped_consts) =
                     BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
                 let data = data.fold_with(self);
-                let normalized_ty = project::opt_normalize_projection_type(
+                let normalized_ty = project::opt_normalize_projection_term(
                     self.selcx,
                     self.param_env,
-                    data,
+                    data.into(),
                     self.cause.clone(),
                     self.depth,
                     self.obligations,
@@ -309,7 +309,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
                 let recursion_limit = self.interner().recursion_limit();
                 if !recursion_limit.value_within_limit(self.depth) {
                     self.selcx.infcx.err_ctxt().report_overflow_error(
-                        OverflowCause::DeeplyNormalize(data),
+                        OverflowCause::DeeplyNormalize(data.into()),
                         self.cause.span,
                         false,
                         |diag| {
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 75e43bc8f5d..41080b3d9d3 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -305,7 +305,7 @@ fn predicate_references_self<'tcx>(
             //
             // This is ALT2 in issue #56288, see that for discussion of the
             // possible alternatives.
-            data.projection_ty.args[1..].iter().any(has_self_ty).then_some(sp)
+            data.projection_term.args[1..].iter().any(has_self_ty).then_some(sp)
         }
         ty::ClauseKind::ConstArgHasType(_ct, ty) => has_self_ty(&ty.into()).then_some(sp),
 
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index f092f42dacf..20b5a81bb0e 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -12,7 +12,7 @@ use super::PredicateObligation;
 use super::Selection;
 use super::SelectionContext;
 use super::SelectionError;
-use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
+use super::{Normalized, NormalizedTerm, ProjectionCacheEntry, ProjectionCacheKey};
 use rustc_infer::traits::ObligationCauseCode;
 use rustc_middle::traits::BuiltinImplSource;
 use rustc_middle::traits::ImplSource;
@@ -43,7 +43,7 @@ pub type PolyProjectionObligation<'tcx> = Obligation<'tcx, ty::PolyProjectionPre
 
 pub type ProjectionObligation<'tcx> = Obligation<'tcx, ty::ProjectionPredicate<'tcx>>;
 
-pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::AliasTy<'tcx>>;
+pub type ProjectionTermObligation<'tcx> = Obligation<'tcx, ty::AliasTerm<'tcx>>;
 
 pub(super) struct InProgress;
 
@@ -181,7 +181,7 @@ pub(super) enum ProjectAndUnifyResult<'tcx> {
 /// If successful, this may result in additional obligations. Also returns
 /// the projection cache key used to track these additional obligations.
 #[instrument(level = "debug", skip(selcx))]
-pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
+pub(super) fn poly_project_and_unify_term<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &PolyProjectionObligation<'tcx>,
 ) -> ProjectAndUnifyResult<'tcx> {
@@ -192,7 +192,7 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
         let new_universe = infcx.universe();
 
         let placeholder_obligation = obligation.with(infcx.tcx, placeholder_predicate);
-        match project_and_unify_type(selcx, &placeholder_obligation) {
+        match project_and_unify_term(selcx, &placeholder_obligation) {
             ProjectAndUnifyResult::MismatchedProjectionTypes(e) => Err(e),
             ProjectAndUnifyResult::Holds(obligations)
                 if old_universe != new_universe
@@ -234,17 +234,17 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
 ///
 /// See [poly_project_and_unify_type] for an explanation of the return value.
 #[instrument(level = "debug", skip(selcx))]
-fn project_and_unify_type<'cx, 'tcx>(
+fn project_and_unify_term<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionObligation<'tcx>,
 ) -> ProjectAndUnifyResult<'tcx> {
     let mut obligations = vec![];
 
     let infcx = selcx.infcx;
-    let normalized = match opt_normalize_projection_type(
+    let normalized = match opt_normalize_projection_term(
         selcx,
         obligation.param_env,
-        obligation.predicate.projection_ty,
+        obligation.predicate.projection_term,
         obligation.cause.clone(),
         obligation.recursion_depth,
         &mut obligations,
@@ -290,7 +290,7 @@ fn project_and_unify_type<'cx, 'tcx>(
 /// there are unresolved type variables in the projection, we will
 /// instantiate it with a fresh type variable `$X` and generate a new
 /// obligation `<T as Trait>::Item == $X` for later.
-pub fn normalize_projection_type<'a, 'b, 'tcx>(
+pub fn normalize_projection_ty<'a, 'b, 'tcx>(
     selcx: &'a mut SelectionContext<'b, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     projection_ty: ty::AliasTy<'tcx>,
@@ -298,10 +298,10 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>(
     depth: usize,
     obligations: &mut Vec<PredicateObligation<'tcx>>,
 ) -> Term<'tcx> {
-    opt_normalize_projection_type(
+    opt_normalize_projection_term(
         selcx,
         param_env,
-        projection_ty,
+        projection_ty.into(),
         cause.clone(),
         depth,
         obligations,
@@ -313,7 +313,10 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>(
         // and a deferred predicate to resolve this when more type
         // information is available.
 
-        selcx.infcx.infer_projection(param_env, projection_ty, cause, depth + 1, obligations).into()
+        selcx
+            .infcx
+            .projection_ty_to_infer(param_env, projection_ty, cause, depth + 1, obligations)
+            .into()
     })
 }
 
@@ -328,10 +331,10 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>(
 /// function takes an obligations vector and appends to it directly, which is
 /// slightly uglier but avoids the need for an extra short-lived allocation.
 #[instrument(level = "debug", skip(selcx, param_env, cause, obligations))]
-pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>(
+pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>(
     selcx: &'a mut SelectionContext<'b, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
-    projection_ty: ty::AliasTy<'tcx>,
+    projection_term: ty::AliasTerm<'tcx>,
     cause: ObligationCause<'tcx>,
     depth: usize,
     obligations: &mut Vec<PredicateObligation<'tcx>>,
@@ -343,8 +346,8 @@ pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>(
     // mode, which could lead to using incorrect cache results.
     let use_cache = !selcx.is_intercrate();
 
-    let projection_ty = infcx.resolve_vars_if_possible(projection_ty);
-    let cache_key = ProjectionCacheKey::new(projection_ty, param_env);
+    let projection_term = infcx.resolve_vars_if_possible(projection_term);
+    let cache_key = ProjectionCacheKey::new(projection_term, param_env);
 
     // FIXME(#20304) For now, I am caching here, which is good, but it
     // means we don't capture the type variables that are created in
@@ -410,14 +413,14 @@ pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>(
         }
         Err(ProjectionCacheEntry::Error) => {
             debug!("opt_normalize_projection_type: found error");
-            let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth);
+            let result = normalize_to_error(selcx, param_env, projection_term, cause, depth);
             obligations.extend(result.obligations);
             return Ok(Some(result.value.into()));
         }
     }
 
     let obligation =
-        Obligation::with_depth(selcx.tcx(), cause.clone(), depth, param_env, projection_ty);
+        Obligation::with_depth(selcx.tcx(), cause.clone(), depth, param_env, projection_term);
 
     match project(selcx, &obligation) {
         Ok(Projected::Progress(Progress {
@@ -480,7 +483,7 @@ pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>(
             if use_cache {
                 infcx.inner.borrow_mut().projection_cache().error(cache_key);
             }
-            let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth);
+            let result = normalize_to_error(selcx, param_env, projection_term, cause, depth);
             obligations.extend(result.obligations);
             Ok(Some(result.value.into()))
         }
@@ -509,19 +512,33 @@ pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>(
 fn normalize_to_error<'a, 'tcx>(
     selcx: &SelectionContext<'a, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
-    projection_ty: ty::AliasTy<'tcx>,
+    projection_term: ty::AliasTerm<'tcx>,
     cause: ObligationCause<'tcx>,
     depth: usize,
-) -> NormalizedTy<'tcx> {
-    let trait_ref = ty::Binder::dummy(projection_ty.trait_ref(selcx.tcx()));
+) -> NormalizedTerm<'tcx> {
+    let trait_ref = ty::Binder::dummy(projection_term.trait_ref(selcx.tcx()));
+    let new_value = match projection_term.kind(selcx.tcx()) {
+        ty::AliasTermKind::ProjectionTy
+        | ty::AliasTermKind::InherentTy
+        | ty::AliasTermKind::OpaqueTy
+        | ty::AliasTermKind::WeakTy => selcx.infcx.next_ty_var(cause.span).into(),
+        ty::AliasTermKind::UnevaluatedConst => selcx
+            .infcx
+            .next_const_var(
+                selcx
+                    .tcx()
+                    .type_of(projection_term.def_id)
+                    .instantiate(selcx.tcx(), projection_term.args),
+                cause.span,
+            )
+            .into(),
+    };
     let trait_obligation = Obligation {
         cause,
         recursion_depth: depth,
         param_env,
         predicate: trait_ref.to_predicate(selcx.tcx()),
     };
-    let tcx = selcx.infcx.tcx;
-    let new_value = selcx.infcx.next_ty_var(tcx.def_span(projection_ty.def_id));
     Normalized { value: new_value, obligations: vec![trait_obligation] }
 }
 
@@ -675,7 +692,7 @@ impl<'tcx> Progress<'tcx> {
 #[instrument(level = "info", skip(selcx))]
 fn project<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
 ) -> Result<Projected<'tcx>, ProjectionError<'tcx>> {
     if !selcx.tcx().recursion_limit().value_within_limit(obligation.recursion_depth) {
         // This should really be an immediate error, but some existing code
@@ -750,7 +767,7 @@ fn project<'cx, 'tcx>(
 /// there that can answer this question.
 fn assemble_candidates_from_param_env<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     candidate_set: &mut ProjectionCandidateSet<'tcx>,
 ) {
     assemble_candidates_from_predicates(
@@ -775,7 +792,7 @@ fn assemble_candidates_from_param_env<'cx, 'tcx>(
 /// Here, for example, we could conclude that the result is `i32`.
 fn assemble_candidates_from_trait_def<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     candidate_set: &mut ProjectionCandidateSet<'tcx>,
 ) {
     debug!("assemble_candidates_from_trait_def(..)");
@@ -833,7 +850,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
 /// `dyn Iterator<Item = ()>: Iterator` again.
 fn assemble_candidates_from_object_ty<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     candidate_set: &mut ProjectionCandidateSet<'tcx>,
 ) {
     debug!("assemble_candidates_from_object_ty(..)");
@@ -877,7 +894,7 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
 )]
 fn assemble_candidates_from_predicates<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     candidate_set: &mut ProjectionCandidateSet<'tcx>,
     ctor: fn(ty::PolyProjectionPredicate<'tcx>) -> ProjectionCandidate<'tcx>,
     env_predicates: impl Iterator<Item = ty::Clause<'tcx>>,
@@ -925,7 +942,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
 #[instrument(level = "debug", skip(selcx, obligation, candidate_set))]
 fn assemble_candidates_from_impls<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     candidate_set: &mut ProjectionCandidateSet<'tcx>,
 ) {
     // If we are resolving `<T as TraitRef<...>>::Item == Type`,
@@ -1253,7 +1270,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
 
 fn confirm_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     candidate: ProjectionCandidate<'tcx>,
 ) -> Progress<'tcx> {
     debug!(?obligation, ?candidate, "confirm_candidate");
@@ -1285,7 +1302,7 @@ fn confirm_candidate<'cx, 'tcx>(
 
 fn confirm_select_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     impl_source: Selection<'tcx>,
 ) -> Progress<'tcx> {
     match impl_source {
@@ -1333,7 +1350,7 @@ fn confirm_select_candidate<'cx, 'tcx>(
 
 fn confirm_coroutine_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
     let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
@@ -1377,7 +1394,7 @@ fn confirm_coroutine_candidate<'cx, 'tcx>(
     };
 
     let predicate = ty::ProjectionPredicate {
-        projection_ty: ty::AliasTy::new(tcx, obligation.predicate.def_id, trait_ref.args),
+        projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args),
         term: ty.into(),
     };
 
@@ -1388,7 +1405,7 @@ fn confirm_coroutine_candidate<'cx, 'tcx>(
 
 fn confirm_future_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
     let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
@@ -1421,7 +1438,7 @@ fn confirm_future_candidate<'cx, 'tcx>(
     debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Output);
 
     let predicate = ty::ProjectionPredicate {
-        projection_ty: ty::AliasTy::new(tcx, obligation.predicate.def_id, trait_ref.args),
+        projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args),
         term: return_ty.into(),
     };
 
@@ -1432,7 +1449,7 @@ fn confirm_future_candidate<'cx, 'tcx>(
 
 fn confirm_iterator_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
     let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
@@ -1463,7 +1480,7 @@ fn confirm_iterator_candidate<'cx, 'tcx>(
     debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Item);
 
     let predicate = ty::ProjectionPredicate {
-        projection_ty: ty::AliasTy::new(tcx, obligation.predicate.def_id, trait_ref.args),
+        projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args),
         term: yield_ty.into(),
     };
 
@@ -1474,7 +1491,7 @@ fn confirm_iterator_candidate<'cx, 'tcx>(
 
 fn confirm_async_iterator_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
     let ty::Coroutine(_, args) = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
@@ -1513,7 +1530,7 @@ fn confirm_async_iterator_candidate<'cx, 'tcx>(
     let item_ty = args.type_at(0);
 
     let predicate = ty::ProjectionPredicate {
-        projection_ty: ty::AliasTy::new(tcx, obligation.predicate.def_id, trait_ref.args),
+        projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args),
         term: item_ty.into(),
     };
 
@@ -1524,7 +1541,7 @@ fn confirm_async_iterator_candidate<'cx, 'tcx>(
 
 fn confirm_builtin_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     data: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
     let tcx = selcx.tcx();
@@ -1582,8 +1599,10 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
         bug!("unexpected builtin trait with associated type: {:?}", obligation.predicate);
     };
 
-    let predicate =
-        ty::ProjectionPredicate { projection_ty: ty::AliasTy::new(tcx, item_def_id, args), term };
+    let predicate = ty::ProjectionPredicate {
+        projection_term: ty::AliasTerm::new(tcx, item_def_id, args),
+        term,
+    };
 
     confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
         .with_addl_obligations(obligations)
@@ -1592,7 +1611,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
 
 fn confirm_fn_pointer_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
     let tcx = selcx.tcx();
@@ -1628,7 +1647,7 @@ fn confirm_fn_pointer_candidate<'cx, 'tcx>(
 
 fn confirm_closure_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
     let tcx = selcx.tcx();
@@ -1727,7 +1746,7 @@ fn confirm_closure_candidate<'cx, 'tcx>(
 
 fn confirm_callable_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     fn_sig: ty::PolyFnSig<'tcx>,
     flag: util::TupleArgumentsFlag,
     fn_host_effect: ty::Const<'tcx>,
@@ -1748,7 +1767,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
         fn_host_effect,
     )
     .map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate {
-        projection_ty: ty::AliasTy::new(tcx, fn_once_output_def_id, trait_ref.args),
+        projection_term: ty::AliasTerm::new(tcx, fn_once_output_def_id, trait_ref.args),
         term: ret_type.into(),
     });
 
@@ -1757,7 +1776,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
 
 fn confirm_async_closure_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
     let tcx = selcx.tcx();
@@ -1836,13 +1855,13 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
                 sym::Output => sig.return_ty,
                 name => bug!("no such associated type: {name}"),
             };
-            let projection_ty = match item_name {
-                sym::CallOnceFuture | sym::Output => ty::AliasTy::new(
+            let projection_term = match item_name {
+                sym::CallOnceFuture | sym::Output => ty::AliasTerm::new(
                     tcx,
                     obligation.predicate.def_id,
                     [self_ty, sig.tupled_inputs_ty],
                 ),
-                sym::CallRefFuture => ty::AliasTy::new(
+                sym::CallRefFuture => ty::AliasTerm::new(
                     tcx,
                     obligation.predicate.def_id,
                     [ty::GenericArg::from(self_ty), sig.tupled_inputs_ty.into(), env_region.into()],
@@ -1851,7 +1870,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
             };
 
             args.coroutine_closure_sig()
-                .rebind(ty::ProjectionPredicate { projection_ty, term: term.into() })
+                .rebind(ty::ProjectionPredicate { projection_term, term: term.into() })
         }
         ty::FnDef(..) | ty::FnPtr(..) => {
             let bound_sig = self_ty.fn_sig(tcx);
@@ -1871,13 +1890,13 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
                 }
                 name => bug!("no such associated type: {name}"),
             };
-            let projection_ty = match item_name {
-                sym::CallOnceFuture | sym::Output => ty::AliasTy::new(
+            let projection_term = match item_name {
+                sym::CallOnceFuture | sym::Output => ty::AliasTerm::new(
                     tcx,
                     obligation.predicate.def_id,
                     [self_ty, Ty::new_tup(tcx, sig.inputs())],
                 ),
-                sym::CallRefFuture => ty::AliasTy::new(
+                sym::CallRefFuture => ty::AliasTerm::new(
                     tcx,
                     obligation.predicate.def_id,
                     [
@@ -1889,7 +1908,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
                 name => bug!("no such associated type: {name}"),
             };
 
-            bound_sig.rebind(ty::ProjectionPredicate { projection_ty, term: term.into() })
+            bound_sig.rebind(ty::ProjectionPredicate { projection_term, term: term.into() })
         }
         ty::Closure(_, args) => {
             let args = args.as_closure();
@@ -1910,11 +1929,11 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
                 }
                 name => bug!("no such associated type: {name}"),
             };
-            let projection_ty = match item_name {
+            let projection_term = match item_name {
                 sym::CallOnceFuture | sym::Output => {
-                    ty::AliasTy::new(tcx, obligation.predicate.def_id, [self_ty, sig.inputs()[0]])
+                    ty::AliasTerm::new(tcx, obligation.predicate.def_id, [self_ty, sig.inputs()[0]])
                 }
-                sym::CallRefFuture => ty::AliasTy::new(
+                sym::CallRefFuture => ty::AliasTerm::new(
                     tcx,
                     obligation.predicate.def_id,
                     [ty::GenericArg::from(self_ty), sig.inputs()[0].into(), env_region.into()],
@@ -1922,7 +1941,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
                 name => bug!("no such associated type: {name}"),
             };
 
-            bound_sig.rebind(ty::ProjectionPredicate { projection_ty, term: term.into() })
+            bound_sig.rebind(ty::ProjectionPredicate { projection_term, term: term.into() })
         }
         _ => bug!("expected callable type for AsyncFn candidate"),
     };
@@ -1933,7 +1952,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
 
 fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
     let [
@@ -1950,7 +1969,7 @@ fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>(
     };
 
     let predicate = ty::ProjectionPredicate {
-        projection_ty: ty::AliasTy::new(
+        projection_term: ty::AliasTerm::new(
             selcx.tcx(),
             obligation.predicate.def_id,
             obligation.predicate.args,
@@ -1972,7 +1991,7 @@ fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>(
 
 fn confirm_param_env_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     poly_cache_entry: ty::PolyProjectionPredicate<'tcx>,
     potentially_unnormalized_candidate: bool,
 ) -> Progress<'tcx> {
@@ -1986,7 +2005,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
         poly_cache_entry,
     );
 
-    let cache_projection = cache_entry.projection_ty;
+    let cache_projection = cache_entry.projection_term;
     let mut nested_obligations = Vec::new();
     let obligation_projection = obligation.predicate;
     let obligation_projection = ensure_sufficient_stack(|| {
@@ -2041,7 +2060,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
 
 fn confirm_impl_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     impl_impl_source: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
     let tcx = selcx.tcx();
@@ -2102,7 +2121,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
 // associated type itself.
 fn assoc_ty_own_obligations<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
     nested: &mut Vec<PredicateObligation<'tcx>>,
 ) {
     let tcx = selcx.tcx();
@@ -2164,7 +2183,7 @@ impl<'cx, 'tcx> ProjectionCacheKeyExt<'cx, 'tcx> for ProjectionCacheKey<'tcx> {
                 // from a specific call to `opt_normalize_projection_type` - if
                 // there's no precise match, the original cache entry is "stranded"
                 // anyway.
-                infcx.resolve_vars_if_possible(predicate.projection_ty),
+                infcx.resolve_vars_if_possible(predicate.projection_term),
                 obligation.param_env,
             )
         })
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index 8b39c23da56..1b5ffeebc01 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -222,7 +222,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
                                 .infcx
                                 .err_ctxt()
                                 .build_overflow_error(
-                                    OverflowCause::DeeplyNormalize(data),
+                                    OverflowCause::DeeplyNormalize(data.into()),
                                     self.cause.span,
                                     true,
                                 )
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 40d206b92b8..19968fd362f 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -944,7 +944,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         }
 
         self.infcx.probe(|_| {
-            let ty = traits::normalize_projection_type(
+            let ty = traits::normalize_projection_ty(
                 self,
                 param_env,
                 ty::AliasTy::new(tcx, tcx.lang_items().deref_target()?, trait_ref.args),
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 7aa2aabed7f..d665f3c3907 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -8,7 +8,7 @@ use self::SelectionCandidate::*;
 use super::coherence::{self, Conflict};
 use super::const_evaluatable;
 use super::project;
-use super::project::ProjectionTyObligation;
+use super::project::ProjectionTermObligation;
 use super::util;
 use super::util::closure_trait_ref_and_return_type;
 use super::wf;
@@ -808,7 +808,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
                     let data = bound_predicate.rebind(data);
                     let project_obligation = obligation.with(self.tcx(), data);
-                    match project::poly_project_and_unify_type(self, &project_obligation) {
+                    match project::poly_project_and_unify_term(self, &project_obligation) {
                         ProjectAndUnifyResult::Holds(mut subobligations) => {
                             'compute_res: {
                                 // If we've previously marked this projection as 'complete', then
@@ -1733,7 +1733,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     /// in cases like #91762.
     pub(super) fn match_projection_projections(
         &mut self,
-        obligation: &ProjectionTyObligation<'tcx>,
+        obligation: &ProjectionTermObligation<'tcx>,
         env_predicate: PolyProjectionPredicate<'tcx>,
         potentially_unnormalized_candidates: bool,
     ) -> ProjectionMatchesProjection {
@@ -1752,12 +1752,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     obligation.param_env,
                     obligation.cause.clone(),
                     obligation.recursion_depth + 1,
-                    infer_predicate.projection_ty,
+                    infer_predicate.projection_term,
                     &mut nested_obligations,
                 )
             })
         } else {
-            infer_predicate.projection_ty
+            infer_predicate.projection_term
         };
 
         let is_match = self
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 562a82cc73d..8a0ce3c1f98 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -165,11 +165,8 @@ pub fn clause_obligations<'tcx>(
             wf.compute(ty.into());
         }
         ty::ClauseKind::Projection(t) => {
-            wf.compute_alias(t.projection_ty);
-            wf.compute(match t.term.unpack() {
-                ty::TermKind::Ty(ty) => ty.into(),
-                ty::TermKind::Const(c) => c.into(),
-            })
+            wf.compute_alias_term(t.projection_term);
+            wf.compute(t.term.into_arg());
         }
         ty::ClauseKind::ConstArgHasType(ct, ty) => {
             wf.compute(ct.into());
@@ -439,7 +436,37 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
 
     /// Pushes the obligations required for an alias (except inherent) to be WF
     /// into `self.out`.
-    fn compute_alias(&mut self, data: ty::AliasTy<'tcx>) {
+    fn compute_alias_ty(&mut self, data: ty::AliasTy<'tcx>) {
+        // A projection is well-formed if
+        //
+        // (a) its predicates hold (*)
+        // (b) its args are wf
+        //
+        // (*) The predicates of an associated type include the predicates of
+        //     the trait that it's contained in. For example, given
+        //
+        // trait A<T>: Clone {
+        //     type X where T: Copy;
+        // }
+        //
+        // The predicates of `<() as A<i32>>::X` are:
+        // [
+        //     `(): Sized`
+        //     `(): Clone`
+        //     `(): A<i32>`
+        //     `i32: Sized`
+        //     `i32: Clone`
+        //     `i32: Copy`
+        // ]
+        let obligations = self.nominal_obligations(data.def_id, data.args);
+        self.out.extend(obligations);
+
+        self.compute_projection_args(data.args);
+    }
+
+    /// Pushes the obligations required for an alias (except inherent) to be WF
+    /// into `self.out`.
+    fn compute_alias_term(&mut self, data: ty::AliasTerm<'tcx>) {
         // A projection is well-formed if
         //
         // (a) its predicates hold (*)
@@ -698,7 +725,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
             }
 
             ty::Alias(ty::Projection | ty::Opaque | ty::Weak, data) => {
-                self.compute_alias(data);
+                self.compute_alias_ty(data);
                 return; // Subtree handled by compute_projection.
             }
             ty::Alias(ty::Inherent, data) => {