about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis')
-rw-r--r--compiler/rustc_hir_analysis/Cargo.toml1
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl11
-rw-r--r--compiler/rustc_hir_analysis/src/autoderef.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs54
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs86
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs111
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs555
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs21
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs64
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs70
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/constrained_generic_params.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs30
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs132
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs227
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/variance/constraints.rs30
32 files changed, 496 insertions, 1028 deletions
diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml
index e5017794d8f..58213c4f4e4 100644
--- a/compiler/rustc_hir_analysis/Cargo.toml
+++ b/compiler/rustc_hir_analysis/Cargo.toml
@@ -26,7 +26,6 @@ rustc_macros = { path = "../rustc_macros" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
-rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 2f7c3cb3c7d..277bb7bd3e1 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -1,5 +1,5 @@
-hir_analysis_ambiguous_assoc_item = ambiguous associated {$assoc_kind} `{$assoc_name}` in bounds of `{$qself}`
-    .label = ambiguous associated {$assoc_kind} `{$assoc_name}`
+hir_analysis_ambiguous_assoc_item = ambiguous associated {$assoc_kind} `{$assoc_ident}` in bounds of `{$qself}`
+    .label = ambiguous associated {$assoc_kind} `{$assoc_ident}`
 
 hir_analysis_ambiguous_lifetime_bound =
     ambiguous lifetime bound, explicit lifetime bound required
@@ -12,13 +12,13 @@ hir_analysis_assoc_item_is_private = {$kind} `{$name}` is private
     .label = private {$kind}
     .defined_here_label = the {$kind} is defined here
 
-hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_name}` not found for `{$qself}`
+hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_ident}` not found for `{$qself}`
 
 hir_analysis_assoc_item_not_found_found_in_other_trait_label = there is {$identically_named ->
         [true] an
         *[false] a similarly named
     } associated {$assoc_kind} `{$suggested_name}` in the trait `{$trait_name}`
-hir_analysis_assoc_item_not_found_label = associated {$assoc_kind} `{$assoc_name}` not found
+hir_analysis_assoc_item_not_found_label = associated {$assoc_kind} `{$assoc_ident}` not found
 hir_analysis_assoc_item_not_found_other_sugg = `{$qself}` has the following associated {$assoc_kind}
 hir_analysis_assoc_item_not_found_similar_in_other_trait_qpath_sugg =
     consider fully qualifying{$identically_named ->
@@ -450,9 +450,6 @@ hir_analysis_recursive_generic_parameter = {$param_def_kind} `{$param_name}` is
 hir_analysis_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}`
     .note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}`
 
-hir_analysis_register_type_unstable =
-    type `{$ty}` cannot be used with this register class in stable
-
 hir_analysis_requires_note = the `{$trait_name}` impl for `{$ty}` requires that `{$error_predicate}`
 
 hir_analysis_return_type_notation_equality_bound =
diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs
index b3eade8c8ae..99e495d9266 100644
--- a/compiler/rustc_hir_analysis/src/autoderef.rs
+++ b/compiler/rustc_hir_analysis/src/autoderef.rs
@@ -2,8 +2,8 @@ use rustc_infer::infer::InferCtxt;
 use rustc_infer::traits::PredicateObligations;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 use rustc_session::Limit;
-use rustc_span::Span;
 use rustc_span::def_id::{LOCAL_CRATE, LocalDefId};
+use rustc_span::{ErrorGuaranteed, Span};
 use rustc_trait_selection::traits::ObligationCtxt;
 use tracing::{debug, instrument};
 
@@ -259,7 +259,11 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
     }
 }
 
-pub fn report_autoderef_recursion_limit_error<'tcx>(tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) {
+pub fn report_autoderef_recursion_limit_error<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    span: Span,
+    ty: Ty<'tcx>,
+) -> ErrorGuaranteed {
     // We've reached the recursion limit, error gracefully.
     let suggested_limit = match tcx.recursion_limit() {
         Limit(0) => Limit(2),
@@ -270,5 +274,5 @@ pub fn report_autoderef_recursion_limit_error<'tcx>(tcx: TyCtxt<'tcx>, span: Spa
         ty,
         suggested_limit,
         crate_name: tcx.crate_name(LOCAL_CRATE),
-    });
+    })
 }
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 18ef00dc8b1..f92b2aea160 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -443,13 +443,13 @@ fn best_definition_site_of_opaque<'tcx>(
             let impl_def_id = tcx.local_parent(parent);
             for assoc in tcx.associated_items(impl_def_id).in_definition_order() {
                 match assoc.kind {
-                    ty::AssocKind::Const | ty::AssocKind::Fn => {
+                    ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => {
                         if let ControlFlow::Break(span) = locator.check(assoc.def_id.expect_local())
                         {
                             return Some(span);
                         }
                     }
-                    ty::AssocKind::Type => {}
+                    ty::AssocKind::Type { .. } => {}
                 }
             }
 
@@ -719,7 +719,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                     def_id,
                     tcx.def_ident_span(def_id).unwrap(),
                     i.name,
-                    ExternAbi::Rust,
                 )
             }
         }
@@ -731,7 +730,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                     .is_ok()
                 {
                     check_impl_items_against_trait(tcx, def_id, impl_trait_header);
-                    check_on_unimplemented(tcx, def_id);
                 }
             }
         }
@@ -741,7 +739,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 
             for &assoc_item in assoc_items.in_definition_order() {
                 match assoc_item.kind {
-                    ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
+                    ty::AssocKind::Type { .. } if assoc_item.defaultness(tcx).has_value() => {
                         let trait_args = GenericArgs::identity_for_item(tcx, def_id);
                         let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
                             tcx,
@@ -787,16 +785,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
             for item in items {
                 let def_id = item.id.owner_id.def_id;
 
-                if tcx.has_attr(def_id, sym::rustc_intrinsic) {
-                    intrinsic::check_intrinsic_type(
-                        tcx,
-                        item.id.owner_id.def_id,
-                        item.span,
-                        item.ident.name,
-                        abi,
-                    );
-                }
-
                 let generics = tcx.generics_of(def_id);
                 let own_counts = generics.own_counts();
                 if generics.own_params.len() - own_counts.lifetimes != 0 {
@@ -937,31 +925,7 @@ fn check_impl_items_against_trait<'tcx>(
 
     let trait_def = tcx.trait_def(trait_ref.def_id);
 
-    let infcx = tcx.infer_ctxt().ignoring_regions().build(TypingMode::non_body_analysis());
-
-    let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
-    let cause = ObligationCause::misc(tcx.def_span(impl_id), impl_id);
-    let param_env = tcx.param_env(impl_id);
-
-    let self_is_guaranteed_unsized = match tcx
-        .struct_tail_raw(
-            trait_ref.self_ty(),
-            |ty| {
-                ocx.structurally_normalize_ty(&cause, param_env, ty).unwrap_or_else(|_| {
-                    Ty::new_error_with_message(
-                        tcx,
-                        tcx.def_span(impl_id),
-                        "struct tail should be computable",
-                    )
-                })
-            },
-            || (),
-        )
-        .kind()
-    {
-        ty::Dynamic(_, _, ty::DynKind::Dyn) | ty::Slice(_) | ty::Str => true,
-        _ => false,
-    };
+    let self_is_guaranteed_unsize_self = tcx.impl_self_is_guaranteed_unsized(impl_id);
 
     for &impl_item in impl_item_refs {
         let ty_impl_item = tcx.associated_item(impl_item);
@@ -977,7 +941,7 @@ fn check_impl_items_against_trait<'tcx>(
 
         if res.is_ok() {
             match ty_impl_item.kind {
-                ty::AssocKind::Fn => {
+                ty::AssocKind::Fn { .. } => {
                     compare_impl_item::refine::check_refining_return_position_impl_trait_in_trait(
                         tcx,
                         ty_impl_item,
@@ -987,12 +951,12 @@ fn check_impl_items_against_trait<'tcx>(
                             .instantiate_identity(),
                     );
                 }
-                ty::AssocKind::Const => {}
-                ty::AssocKind::Type => {}
+                ty::AssocKind::Const { .. } => {}
+                ty::AssocKind::Type { .. } => {}
             }
         }
 
-        if self_is_guaranteed_unsized && tcx.generics_require_sized_self(ty_trait_item.def_id) {
+        if self_is_guaranteed_unsize_self && tcx.generics_require_sized_self(ty_trait_item.def_id) {
             tcx.emit_node_span_lint(
                 rustc_lint_defs::builtin::DEAD_CODE,
                 tcx.local_def_id_to_hir_id(ty_impl_item.def_id.expect_local()),
@@ -1027,7 +991,7 @@ fn check_impl_items_against_trait<'tcx>(
             if !is_implemented
                 && tcx.defaultness(impl_id).is_final()
                 // unsized types don't need to implement methods that have `Self: Sized` bounds.
-                && !(self_is_guaranteed_unsized && tcx.generics_require_sized_self(trait_item_id))
+                && !(self_is_guaranteed_unsize_self && tcx.generics_require_sized_self(trait_item_id))
             {
                 missing_items.push(tcx.associated_item(trait_item_id));
             }
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 32a8f101849..bbf36fef1dd 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -43,9 +43,11 @@ pub(super) fn compare_impl_item(
     debug!(?impl_trait_ref);
 
     match impl_item.kind {
-        ty::AssocKind::Fn => compare_impl_method(tcx, impl_item, trait_item, impl_trait_ref),
-        ty::AssocKind::Type => compare_impl_ty(tcx, impl_item, trait_item, impl_trait_ref),
-        ty::AssocKind::Const => compare_impl_const(tcx, impl_item, trait_item, impl_trait_ref),
+        ty::AssocKind::Fn { .. } => compare_impl_method(tcx, impl_item, trait_item, impl_trait_ref),
+        ty::AssocKind::Type { .. } => compare_impl_ty(tcx, impl_item, trait_item, impl_trait_ref),
+        ty::AssocKind::Const { .. } => {
+            compare_impl_const(tcx, impl_item, trait_item, impl_trait_ref)
+        }
     }
 }
 
@@ -377,13 +379,13 @@ fn compare_method_predicate_entailment<'tcx>(
         // Annoyingly, asking for the WF predicates of an array (with an unevaluated const (only?))
         // will give back the well-formed predicate of the same array.
         let mut wf_args_seen: FxHashSet<_> = wf_args.iter().copied().collect();
-        while let Some(arg) = wf_args.pop() {
+        while let Some(term) = wf_args.pop() {
             let Some(obligations) = rustc_trait_selection::traits::wf::obligations(
                 infcx,
                 param_env,
                 impl_m_def_id,
                 0,
-                arg,
+                term,
                 impl_m_span,
             ) else {
                 continue;
@@ -400,9 +402,9 @@ fn compare_method_predicate_entailment<'tcx>(
                         | ty::ClauseKind::TypeOutlives(..)
                         | ty::ClauseKind::Projection(..),
                     ) => ocx.register_obligation(obligation),
-                    ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
-                        if wf_args_seen.insert(arg) {
-                            wf_args.push(arg)
+                    ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => {
+                        if wf_args_seen.insert(term) {
+                            wf_args.push(term)
                         }
                     }
                     _ => {}
@@ -606,7 +608,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
     // with placeholders, which imply nothing about outlives bounds, and then
     // prove below that the hidden types are well formed.
     let universe = infcx.create_next_universe();
-    let mut idx = 0;
+    let mut idx = ty::BoundVar::ZERO;
     let mapping: FxIndexMap<_, _> = collector
         .types
         .iter()
@@ -623,10 +625,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
                     tcx,
                     ty::Placeholder {
                         universe,
-                        bound: ty::BoundTy {
-                            var: ty::BoundVar::from_usize(idx),
-                            kind: ty::BoundTyKind::Anon,
-                        },
+                        bound: ty::BoundTy { var: idx, kind: ty::BoundTyKind::Anon },
                     },
                 ),
             )
@@ -654,7 +653,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
                 cause.span,
                 E0053,
                 "method `{}` has an incompatible return type for trait",
-                trait_m.name
+                trait_m.name()
             );
             infcx.err_ctxt().note_type_err(
                 &mut diag,
@@ -1032,11 +1031,11 @@ fn report_trait_method_mismatch<'tcx>(
         impl_err_span,
         E0053,
         "method `{}` has an incompatible type for trait",
-        trait_m.name
+        trait_m.name()
     );
     match &terr {
         TypeError::ArgumentMutability(0) | TypeError::ArgumentSorts(_, 0)
-            if trait_m.fn_has_self_parameter =>
+            if trait_m.is_method() =>
         {
             let ty = trait_sig.inputs()[0];
             let sugg = get_self_string(ty, |ty| ty == impl_trait_ref.self_ty());
@@ -1046,11 +1045,11 @@ fn report_trait_method_mismatch<'tcx>(
             // argument pattern and type.
             let (sig, body) = tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).expect_fn();
             let span = tcx
-                .hir_body_param_names(body)
+                .hir_body_param_idents(body)
                 .zip(sig.decl.inputs.iter())
-                .map(|(param_name, ty)| {
-                    if let Some(param_name) = param_name {
-                        param_name.span.to(ty.span)
+                .map(|(param_ident, ty)| {
+                    if let Some(param_ident) = param_ident {
+                        param_ident.span.to(ty.span)
                     } else {
                         ty.span
                     }
@@ -1255,7 +1254,7 @@ fn compare_self_type<'tcx>(
         get_self_string(self_arg_ty, can_eq_self)
     };
 
-    match (trait_m.fn_has_self_parameter, impl_m.fn_has_self_parameter) {
+    match (trait_m.is_method(), impl_m.is_method()) {
         (false, false) | (true, true) => {}
 
         (false, true) => {
@@ -1266,14 +1265,14 @@ fn compare_self_type<'tcx>(
                 impl_m_span,
                 E0185,
                 "method `{}` has a `{}` declaration in the impl, but not in the trait",
-                trait_m.name,
+                trait_m.name(),
                 self_descr
             );
             err.span_label(impl_m_span, format!("`{self_descr}` used in impl"));
             if let Some(span) = tcx.hir_span_if_local(trait_m.def_id) {
                 err.span_label(span, format!("trait method declared without `{self_descr}`"));
             } else {
-                err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
+                err.note_trait_signature(trait_m.name(), trait_m.signature(tcx));
             }
             return Err(err.emit_unless(delay));
         }
@@ -1286,14 +1285,14 @@ fn compare_self_type<'tcx>(
                 impl_m_span,
                 E0186,
                 "method `{}` has a `{}` declaration in the trait, but not in the impl",
-                trait_m.name,
+                trait_m.name(),
                 self_descr
             );
             err.span_label(impl_m_span, format!("expected `{self_descr}` in impl"));
             if let Some(span) = tcx.hir_span_if_local(trait_m.def_id) {
                 err.span_label(span, format!("`{self_descr}` used in trait"));
             } else {
-                err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
+                err.note_trait_signature(trait_m.name(), trait_m.signature(tcx));
             }
 
             return Err(err.emit_unless(delay));
@@ -1363,7 +1362,7 @@ fn compare_number_of_generics<'tcx>(
     let mut err_occurred = None;
     for (kind, trait_count, impl_count) in matchings {
         if impl_count != trait_count {
-            let arg_spans = |kind: ty::AssocKind, generics: &hir::Generics<'_>| {
+            let arg_spans = |item: &ty::AssocItem, generics: &hir::Generics<'_>| {
                 let mut spans = generics
                     .params
                     .iter()
@@ -1373,7 +1372,7 @@ fn compare_number_of_generics<'tcx>(
                         } => {
                             // A fn can have an arbitrary number of extra elided lifetimes for the
                             // same signature.
-                            !matches!(kind, ty::AssocKind::Fn)
+                            !item.is_fn()
                         }
                         _ => true,
                     })
@@ -1386,7 +1385,7 @@ fn compare_number_of_generics<'tcx>(
             };
             let (trait_spans, impl_trait_spans) = if let Some(def_id) = trait_.def_id.as_local() {
                 let trait_item = tcx.hir_expect_trait_item(def_id);
-                let arg_spans: Vec<Span> = arg_spans(trait_.kind, trait_item.generics);
+                let arg_spans: Vec<Span> = arg_spans(&trait_, trait_item.generics);
                 let impl_trait_spans: Vec<Span> = trait_item
                     .generics
                     .params
@@ -1412,7 +1411,7 @@ fn compare_number_of_generics<'tcx>(
                     _ => None,
                 })
                 .collect();
-            let spans = arg_spans(impl_.kind, impl_item.generics);
+            let spans = arg_spans(&impl_, impl_item.generics);
             let span = spans.first().copied();
 
             let mut err = tcx.dcx().struct_span_err(
@@ -1421,7 +1420,7 @@ fn compare_number_of_generics<'tcx>(
                     "{} `{}` has {} {kind} parameter{} but its trait \
                      declaration has {} {kind} parameter{}",
                     item_kind,
-                    trait_.name,
+                    trait_.name(),
                     impl_count,
                     pluralize!(impl_count),
                     trait_count,
@@ -1512,7 +1511,7 @@ fn compare_number_of_method_arguments<'tcx>(
             impl_span,
             E0050,
             "method `{}` has {} but the declaration in trait `{}` has {}",
-            trait_m.name,
+            trait_m.name(),
             potentially_plural_count(impl_number_args, "parameter"),
             tcx.def_path_str(trait_m.def_id),
             trait_number_args
@@ -1527,7 +1526,7 @@ fn compare_number_of_method_arguments<'tcx>(
                 ),
             );
         } else {
-            err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
+            err.note_trait_signature(trait_m.name(), trait_m.signature(tcx));
         }
 
         err.span_label(
@@ -1581,7 +1580,7 @@ fn compare_synthetic_generics<'tcx>(
                 impl_span,
                 E0643,
                 "method `{}` has incompatible signature for trait",
-                trait_m.name
+                trait_m.name()
             );
             err.span_label(trait_span, "declaration in trait here");
             if impl_synthetic {
@@ -1703,7 +1702,7 @@ fn compare_generic_param_kinds<'tcx>(
     trait_item: ty::AssocItem,
     delay: bool,
 ) -> Result<(), ErrorGuaranteed> {
-    assert_eq!(impl_item.kind, trait_item.kind);
+    assert_eq!(impl_item.as_tag(), trait_item.as_tag());
 
     let ty_const_params_of = |def_id| {
         tcx.generics_of(def_id).own_params.iter().filter(|param| {
@@ -1741,7 +1740,7 @@ fn compare_generic_param_kinds<'tcx>(
                 E0053,
                 "{} `{}` has an incompatible generic parameter for trait `{}`",
                 impl_item.descr(),
-                trait_item.name,
+                trait_item.name(),
                 &tcx.def_path_str(tcx.parent(trait_item.def_id))
             );
 
@@ -1877,7 +1876,7 @@ fn compare_const_predicate_entailment<'tcx>(
             cause.span,
             E0326,
             "implemented const `{}` has an incompatible type for trait",
-            trait_ct.name
+            trait_ct.name()
         );
 
         let trait_c_span = trait_ct.def_id.as_local().map(|trait_ct_def_id| {
@@ -2235,16 +2234,19 @@ fn param_env_with_gat_bounds<'tcx>(
     // of the RPITITs associated with the same body. This is because checking
     // the item bounds of RPITITs often involves nested RPITITs having to prove
     // bounds about themselves.
-    let impl_tys_to_install = match impl_ty.opt_rpitit_info {
-        None => vec![impl_ty],
-        Some(
-            ty::ImplTraitInTraitData::Impl { fn_def_id }
-            | ty::ImplTraitInTraitData::Trait { fn_def_id, .. },
-        ) => tcx
+    let impl_tys_to_install = match impl_ty.kind {
+        ty::AssocKind::Type {
+            data:
+                ty::AssocTypeData::Rpitit(
+                    ty::ImplTraitInTraitData::Impl { fn_def_id }
+                    | ty::ImplTraitInTraitData::Trait { fn_def_id, .. },
+                ),
+        } => tcx
             .associated_types_for_impl_traits_in_associated_fn(fn_def_id)
             .iter()
             .map(|def_id| tcx.associated_item(*def_id))
             .collect(),
+        _ => vec![impl_ty],
     };
 
     for impl_ty in impl_tys_to_install {
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 0bf9e127989..692784bf171 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -1,10 +1,8 @@
 //! Type-checking for the `#[rustc_intrinsic]` intrinsics that the compiler exposes.
 
 use rustc_abi::ExternAbi;
-use rustc_errors::codes::*;
-use rustc_errors::{DiagMessage, struct_span_code_err};
-use rustc_hir::{self as hir, Safety};
-use rustc_middle::bug;
+use rustc_errors::DiagMessage;
+use rustc_hir::{self as hir, LangItem};
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::def_id::LocalDefId;
@@ -26,17 +24,10 @@ fn equate_intrinsic_type<'tcx>(
     sig: ty::PolyFnSig<'tcx>,
 ) {
     let (generics, span) = match tcx.hir_node_by_def_id(def_id) {
-        hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { generics, .. }, .. })
-        | hir::Node::ForeignItem(hir::ForeignItem {
-            kind: hir::ForeignItemKind::Fn(_, _, generics),
-            ..
-        }) => (tcx.generics_of(def_id), generics.span),
-        _ => {
-            struct_span_code_err!(tcx.dcx(), span, E0622, "intrinsic must be a function")
-                .with_span_label(span, "expected a function")
-                .emit();
-            return;
+        hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { generics, .. }, .. }) => {
+            (tcx.generics_of(def_id), generics.span)
         }
+        _ => tcx.dcx().span_bug(span, "intrinsic must be a function"),
     };
     let own_counts = generics.own_counts();
 
@@ -70,13 +61,7 @@ fn equate_intrinsic_type<'tcx>(
 }
 
 /// Returns the unsafety of the given intrinsic.
-pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hir::Safety {
-    let has_safe_attr = if tcx.has_attr(intrinsic_id, sym::rustc_intrinsic) {
-        tcx.fn_sig(intrinsic_id).skip_binder().safety()
-    } else {
-        // Old-style intrinsics are never safe
-        Safety::Unsafe
-    };
+fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hir::Safety {
     let is_in_list = match tcx.item_name(intrinsic_id.into()) {
         // When adding a new intrinsic to this list,
         // it's usually worth updating that intrinsic's documentation
@@ -148,7 +133,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
         _ => hir::Safety::Unsafe,
     };
 
-    if has_safe_attr != is_in_list {
+    if tcx.fn_sig(intrinsic_id).skip_binder().safety() != is_in_list {
         tcx.dcx().struct_span_err(
             tcx.def_span(intrinsic_id),
             DiagMessage::from(format!(
@@ -163,12 +148,11 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
 
 /// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`,
 /// and in `library/core/src/intrinsics.rs`.
-pub fn check_intrinsic_type(
+pub(crate) fn check_intrinsic_type(
     tcx: TyCtxt<'_>,
     intrinsic_id: LocalDefId,
     span: Span,
     intrinsic_name: Symbol,
-    abi: ExternAbi,
 ) {
     let generics = tcx.generics_of(intrinsic_id);
     let param = |n| {
@@ -188,23 +172,22 @@ pub fn check_intrinsic_type(
         ty::BoundVariableKind::Region(ty::BoundRegionKind::ClosureEnv),
     ]);
     let mk_va_list_ty = |mutbl| {
-        tcx.lang_items().va_list().map(|did| {
-            let region = ty::Region::new_bound(
-                tcx,
-                ty::INNERMOST,
-                ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::Anon },
-            );
-            let env_region = ty::Region::new_bound(
-                tcx,
-                ty::INNERMOST,
-                ty::BoundRegion {
-                    var: ty::BoundVar::from_u32(2),
-                    kind: ty::BoundRegionKind::ClosureEnv,
-                },
-            );
-            let va_list_ty = tcx.type_of(did).instantiate(tcx, &[region.into()]);
-            (Ty::new_ref(tcx, env_region, va_list_ty, mutbl), va_list_ty)
-        })
+        let did = tcx.require_lang_item(LangItem::VaList, Some(span));
+        let region = ty::Region::new_bound(
+            tcx,
+            ty::INNERMOST,
+            ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::Anon },
+        );
+        let env_region = ty::Region::new_bound(
+            tcx,
+            ty::INNERMOST,
+            ty::BoundRegion {
+                var: ty::BoundVar::from_u32(2),
+                kind: ty::BoundRegionKind::ClosureEnv,
+            },
+        );
+        let va_list_ty = tcx.type_of(did).instantiate(tcx, &[region.into()]);
+        (Ty::new_ref(tcx, env_region, va_list_ty, mutbl), va_list_ty)
     };
 
     let (n_tps, n_lts, n_cts, inputs, output, safety) = if name_str.starts_with("atomic_") {
@@ -232,15 +215,11 @@ pub fn check_intrinsic_type(
         };
         (n_tps, 0, 0, inputs, output, hir::Safety::Unsafe)
     } else if intrinsic_name == sym::contract_check_ensures {
-        // contract_check_ensures::<'a, Ret, C>(&'a Ret, C)
-        // where C: impl Fn(&'a Ret) -> bool,
+        // contract_check_ensures::<Ret, C>(Ret, C) -> Ret
+        // where C: for<'a> Fn(&'a Ret) -> bool,
         //
-        // so: two type params, one lifetime param, 0 const params, two inputs, no return
-
-        let p = generics.param_at(0, tcx);
-        let r = ty::Region::new_early_param(tcx, p.to_early_bound_region_data());
-        let ref_ret = Ty::new_imm_ref(tcx, r, param(1));
-        (2, 1, 0, vec![ref_ret, param(2)], tcx.types.unit, hir::Safety::Safe)
+        // so: two type params, 0 lifetime param, 0 const params, two inputs, no return
+        (2, 0, 0, vec![param(0), param(1)], param(1), hir::Safety::Safe)
     } else {
         let safety = intrinsic_operation_unsafety(tcx, intrinsic_id);
         let (n_tps, n_cts, inputs, output) = match intrinsic_name {
@@ -567,23 +546,17 @@ pub fn check_intrinsic_type(
                 )
             }
 
-            sym::va_start | sym::va_end => match mk_va_list_ty(hir::Mutability::Mut) {
-                Some((va_list_ref_ty, _)) => (0, 0, vec![va_list_ref_ty], tcx.types.unit),
-                None => bug!("`va_list` lang item needed for C-variadic intrinsics"),
-            },
+            sym::va_start | sym::va_end => {
+                (0, 0, vec![mk_va_list_ty(hir::Mutability::Mut).0], tcx.types.unit)
+            }
 
-            sym::va_copy => match mk_va_list_ty(hir::Mutability::Not) {
-                Some((va_list_ref_ty, va_list_ty)) => {
-                    let va_list_ptr_ty = Ty::new_mut_ptr(tcx, va_list_ty);
-                    (0, 0, vec![va_list_ptr_ty, va_list_ref_ty], tcx.types.unit)
-                }
-                None => bug!("`va_list` lang item needed for C-variadic intrinsics"),
-            },
+            sym::va_copy => {
+                let (va_list_ref_ty, va_list_ty) = mk_va_list_ty(hir::Mutability::Not);
+                let va_list_ptr_ty = Ty::new_mut_ptr(tcx, va_list_ty);
+                (0, 0, vec![va_list_ptr_ty, va_list_ref_ty], tcx.types.unit)
+            }
 
-            sym::va_arg => match mk_va_list_ty(hir::Mutability::Mut) {
-                Some((va_list_ref_ty, _)) => (1, 0, vec![va_list_ref_ty], param(0)),
-                None => bug!("`va_list` lang item needed for C-variadic intrinsics"),
-            },
+            sym::va_arg => (1, 0, vec![mk_va_list_ty(hir::Mutability::Mut).0], param(0)),
 
             sym::nontemporal_store => {
                 (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit)
@@ -674,8 +647,12 @@ pub fn check_intrinsic_type(
             sym::simd_masked_load => (3, 0, vec![param(0), param(1), param(2)], param(2)),
             sym::simd_masked_store => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit),
             sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit),
-            sym::simd_insert => (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0)),
-            sym::simd_extract => (2, 0, vec![param(0), tcx.types.u32], param(1)),
+            sym::simd_insert | sym::simd_insert_dyn => {
+                (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0))
+            }
+            sym::simd_extract | sym::simd_extract_dyn => {
+                (2, 0, vec![param(0), tcx.types.u32], param(1))
+            }
             sym::simd_cast
             | sym::simd_as
             | sym::simd_cast_ptr
@@ -706,7 +683,7 @@ pub fn check_intrinsic_type(
         };
         (n_tps, 0, n_cts, inputs, output, safety)
     };
-    let sig = tcx.mk_fn_sig(inputs, output, false, safety, abi);
+    let sig = tcx.mk_fn_sig(inputs, output, false, safety, ExternAbi::Rust);
     let sig = ty::Binder::bind_with_vars(sig, bound_vars);
     equate_intrinsic_type(tcx, span, intrinsic_id, n_tps, n_lts, n_cts, sig)
 }
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
deleted file mode 100644
index 32a582aadc1..00000000000
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ /dev/null
@@ -1,555 +0,0 @@
-use rustc_abi::FieldIdx;
-use rustc_ast::InlineAsmTemplatePiece;
-use rustc_data_structures::fx::FxIndexSet;
-use rustc_hir::def_id::DefId;
-use rustc_hir::{self as hir, LangItem};
-use rustc_infer::infer::InferCtxt;
-use rustc_middle::bug;
-use rustc_middle::ty::{
-    self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, TypeckResults, UintTy,
-};
-use rustc_session::lint;
-use rustc_span::def_id::LocalDefId;
-use rustc_span::{Symbol, sym};
-use rustc_target::asm::{
-    InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType, ModifierInfo,
-};
-
-use crate::errors::RegisterTypeUnstable;
-
-pub struct InlineAsmCtxt<'a, 'tcx> {
-    typing_env: ty::TypingEnv<'tcx>,
-    target_features: &'tcx FxIndexSet<Symbol>,
-    infcx: &'a InferCtxt<'tcx>,
-    typeck_results: &'a TypeckResults<'tcx>,
-}
-
-enum NonAsmTypeReason<'tcx> {
-    UnevaluatedSIMDArrayLength(DefId, ty::Const<'tcx>),
-    Invalid(Ty<'tcx>),
-    InvalidElement(DefId, Ty<'tcx>),
-    NotSizedPtr(Ty<'tcx>),
-    EmptySIMDArray(Ty<'tcx>),
-}
-
-impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
-    pub fn new(
-        def_id: LocalDefId,
-        infcx: &'a InferCtxt<'tcx>,
-        typing_env: ty::TypingEnv<'tcx>,
-        typeck_results: &'a TypeckResults<'tcx>,
-    ) -> Self {
-        InlineAsmCtxt {
-            typing_env,
-            target_features: infcx.tcx.asm_target_features(def_id),
-            infcx,
-            typeck_results,
-        }
-    }
-
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.infcx.tcx
-    }
-
-    fn expr_ty(&self, expr: &hir::Expr<'tcx>) -> Ty<'tcx> {
-        let ty = self.typeck_results.expr_ty_adjusted(expr);
-        let ty = self.infcx.resolve_vars_if_possible(ty);
-        if ty.has_non_region_infer() {
-            Ty::new_misc_error(self.tcx())
-        } else {
-            self.tcx().erase_regions(ty)
-        }
-    }
-
-    // FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()`
-    fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool {
-        // Type still may have region variables, but `Sized` does not depend
-        // on those, so just erase them before querying.
-        if ty.is_sized(self.tcx(), self.typing_env) {
-            return true;
-        }
-        if let ty::Foreign(..) = ty.kind() {
-            return true;
-        }
-        false
-    }
-
-    fn get_asm_ty(&self, ty: Ty<'tcx>) -> Result<InlineAsmType, NonAsmTypeReason<'tcx>> {
-        let asm_ty_isize = match self.tcx().sess.target.pointer_width {
-            16 => InlineAsmType::I16,
-            32 => InlineAsmType::I32,
-            64 => InlineAsmType::I64,
-            width => bug!("unsupported pointer width: {width}"),
-        };
-
-        match *ty.kind() {
-            ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Ok(InlineAsmType::I8),
-            ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Ok(InlineAsmType::I16),
-            ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Ok(InlineAsmType::I32),
-            ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => Ok(InlineAsmType::I64),
-            ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => Ok(InlineAsmType::I128),
-            ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => Ok(asm_ty_isize),
-            ty::Float(FloatTy::F16) => Ok(InlineAsmType::F16),
-            ty::Float(FloatTy::F32) => Ok(InlineAsmType::F32),
-            ty::Float(FloatTy::F64) => Ok(InlineAsmType::F64),
-            ty::Float(FloatTy::F128) => Ok(InlineAsmType::F128),
-            ty::FnPtr(..) => Ok(asm_ty_isize),
-            ty::RawPtr(elem_ty, _) => {
-                if self.is_thin_ptr_ty(elem_ty) {
-                    Ok(asm_ty_isize)
-                } else {
-                    Err(NonAsmTypeReason::NotSizedPtr(ty))
-                }
-            }
-            ty::Adt(adt, args) if adt.repr().simd() => {
-                let fields = &adt.non_enum_variant().fields;
-                if fields.is_empty() {
-                    return Err(NonAsmTypeReason::EmptySIMDArray(ty));
-                }
-                let field = &fields[FieldIdx::ZERO];
-                let elem_ty = field.ty(self.tcx(), args);
-
-                let (size, ty) = match elem_ty.kind() {
-                    ty::Array(ty, len) => {
-                        let len = self.tcx().normalize_erasing_regions(self.typing_env, *len);
-                        if let Some(len) = len.try_to_target_usize(self.tcx()) {
-                            (len, *ty)
-                        } else {
-                            return Err(NonAsmTypeReason::UnevaluatedSIMDArrayLength(
-                                field.did, len,
-                            ));
-                        }
-                    }
-                    _ => (fields.len() as u64, elem_ty),
-                };
-
-                match ty.kind() {
-                    ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Ok(InlineAsmType::VecI8(size)),
-                    ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Ok(InlineAsmType::VecI16(size)),
-                    ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Ok(InlineAsmType::VecI32(size)),
-                    ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => Ok(InlineAsmType::VecI64(size)),
-                    ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => {
-                        Ok(InlineAsmType::VecI128(size))
-                    }
-                    ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => {
-                        Ok(match self.tcx().sess.target.pointer_width {
-                            16 => InlineAsmType::VecI16(size),
-                            32 => InlineAsmType::VecI32(size),
-                            64 => InlineAsmType::VecI64(size),
-                            width => bug!("unsupported pointer width: {width}"),
-                        })
-                    }
-                    ty::Float(FloatTy::F16) => Ok(InlineAsmType::VecF16(size)),
-                    ty::Float(FloatTy::F32) => Ok(InlineAsmType::VecF32(size)),
-                    ty::Float(FloatTy::F64) => Ok(InlineAsmType::VecF64(size)),
-                    ty::Float(FloatTy::F128) => Ok(InlineAsmType::VecF128(size)),
-                    _ => Err(NonAsmTypeReason::InvalidElement(field.did, ty)),
-                }
-            }
-            ty::Infer(_) => bug!("unexpected infer ty in asm operand"),
-            _ => Err(NonAsmTypeReason::Invalid(ty)),
-        }
-    }
-
-    fn check_asm_operand_type(
-        &self,
-        idx: usize,
-        reg: InlineAsmRegOrRegClass,
-        expr: &'tcx hir::Expr<'tcx>,
-        template: &[InlineAsmTemplatePiece],
-        is_input: bool,
-        tied_input: Option<(&'tcx hir::Expr<'tcx>, Option<InlineAsmType>)>,
-    ) -> Option<InlineAsmType> {
-        let ty = self.expr_ty(expr);
-        if ty.has_non_region_infer() {
-            bug!("inference variable in asm operand ty: {:?} {:?}", expr, ty);
-        }
-
-        let asm_ty = match *ty.kind() {
-            // `!` is allowed for input but not for output (issue #87802)
-            ty::Never if is_input => return None,
-            _ if ty.references_error() => return None,
-            ty::Adt(adt, args) if self.tcx().is_lang_item(adt.did(), LangItem::MaybeUninit) => {
-                let fields = &adt.non_enum_variant().fields;
-                let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx(), args);
-                // FIXME: Are we just trying to map to the `T` in `MaybeUninit<T>`?
-                // If so, just get it from the args.
-                let ty::Adt(ty, args) = ty.kind() else {
-                    unreachable!("expected first field of `MaybeUninit` to be an ADT")
-                };
-                assert!(
-                    ty.is_manually_drop(),
-                    "expected first field of `MaybeUninit` to be `ManuallyDrop`"
-                );
-                let fields = &ty.non_enum_variant().fields;
-                let ty = fields[FieldIdx::ZERO].ty(self.tcx(), args);
-                self.get_asm_ty(ty)
-            }
-            _ => self.get_asm_ty(ty),
-        };
-        let asm_ty = match asm_ty {
-            Ok(asm_ty) => asm_ty,
-            Err(reason) => {
-                match reason {
-                    NonAsmTypeReason::UnevaluatedSIMDArrayLength(did, len) => {
-                        let msg = format!("cannot evaluate SIMD vector length `{len}`");
-                        self.infcx
-                            .dcx()
-                            .struct_span_err(self.tcx().def_span(did), msg)
-                            .with_span_note(
-                                expr.span,
-                                "SIMD vector length needs to be known statically for use in `asm!`",
-                            )
-                            .emit();
-                    }
-                    NonAsmTypeReason::Invalid(ty) => {
-                        let msg = format!("cannot use value of type `{ty}` for inline assembly");
-                        self.infcx.dcx().struct_span_err(expr.span, msg).with_note(
-                            "only integers, floats, SIMD vectors, pointers and function pointers \
-                            can be used as arguments for inline assembly",
-                        ).emit();
-                    }
-                    NonAsmTypeReason::NotSizedPtr(ty) => {
-                        let msg = format!(
-                            "cannot use value of unsized pointer type `{ty}` for inline assembly"
-                        );
-                        self.infcx
-                            .dcx()
-                            .struct_span_err(expr.span, msg)
-                            .with_note("only sized pointers can be used in inline assembly")
-                            .emit();
-                    }
-                    NonAsmTypeReason::InvalidElement(did, ty) => {
-                        let msg = format!(
-                            "cannot use SIMD vector with element type `{ty}` for inline assembly"
-                        );
-                        self.infcx.dcx()
-                        .struct_span_err(self.tcx().def_span(did), msg).with_span_note(
-                            expr.span,
-                            "only integers, floats, SIMD vectors, pointers and function pointers \
-                            can be used as arguments for inline assembly",
-                        ).emit();
-                    }
-                    NonAsmTypeReason::EmptySIMDArray(ty) => {
-                        let msg = format!("use of empty SIMD vector `{ty}`");
-                        self.infcx.dcx().struct_span_err(expr.span, msg).emit();
-                    }
-                }
-                return None;
-            }
-        };
-
-        // Check that the type implements Copy. The only case where this can
-        // possibly fail is for SIMD types which don't #[derive(Copy)].
-        if !self.tcx().type_is_copy_modulo_regions(self.typing_env, ty) {
-            let msg = "arguments for inline assembly must be copyable";
-            self.infcx
-                .dcx()
-                .struct_span_err(expr.span, msg)
-                .with_note(format!("`{ty}` does not implement the Copy trait"))
-                .emit();
-        }
-
-        // Ideally we wouldn't need to do this, but LLVM's register allocator
-        // really doesn't like it when tied operands have different types.
-        //
-        // This is purely an LLVM limitation, but we have to live with it since
-        // there is no way to hide this with implicit conversions.
-        //
-        // For the purposes of this check we only look at the `InlineAsmType`,
-        // which means that pointers and integers are treated as identical (modulo
-        // size).
-        if let Some((in_expr, Some(in_asm_ty))) = tied_input {
-            if in_asm_ty != asm_ty {
-                let msg = "incompatible types for asm inout argument";
-                let in_expr_ty = self.expr_ty(in_expr);
-                self.infcx
-                    .dcx()
-                    .struct_span_err(vec![in_expr.span, expr.span], msg)
-                    .with_span_label(in_expr.span, format!("type `{in_expr_ty}`"))
-                    .with_span_label(expr.span, format!("type `{ty}`"))
-                    .with_note(
-                        "asm inout arguments must have the same type, \
-                        unless they are both pointers or integers of the same size",
-                    )
-                    .emit();
-            }
-
-            // All of the later checks have already been done on the input, so
-            // let's not emit errors and warnings twice.
-            return Some(asm_ty);
-        }
-
-        // Check the type against the list of types supported by the selected
-        // register class.
-        let asm_arch = self.tcx().sess.asm_arch.unwrap();
-        let allow_experimental_reg = self.tcx().features().asm_experimental_reg();
-        let reg_class = reg.reg_class();
-        let supported_tys = reg_class.supported_types(asm_arch, allow_experimental_reg);
-        let Some((_, feature)) = supported_tys.iter().find(|&&(t, _)| t == asm_ty) else {
-            let mut err = if !allow_experimental_reg
-                && reg_class.supported_types(asm_arch, true).iter().any(|&(t, _)| t == asm_ty)
-            {
-                self.tcx().sess.create_feature_err(
-                    RegisterTypeUnstable { span: expr.span, ty },
-                    sym::asm_experimental_reg,
-                )
-            } else {
-                let msg = format!("type `{ty}` cannot be used with this register class");
-                let mut err = self.infcx.dcx().struct_span_err(expr.span, msg);
-                let supported_tys: Vec<_> =
-                    supported_tys.iter().map(|(t, _)| t.to_string()).collect();
-                err.note(format!(
-                    "register class `{}` supports these types: {}",
-                    reg_class.name(),
-                    supported_tys.join(", "),
-                ));
-                err
-            };
-            if let Some(suggest) = reg_class.suggest_class(asm_arch, asm_ty) {
-                err.help(format!("consider using the `{}` register class instead", suggest.name()));
-            }
-            err.emit();
-            return Some(asm_ty);
-        };
-
-        // Check whether the selected type requires a target feature. Note that
-        // this is different from the feature check we did earlier. While the
-        // previous check checked that this register class is usable at all
-        // with the currently enabled features, some types may only be usable
-        // with a register class when a certain feature is enabled. We check
-        // this here since it depends on the results of typeck.
-        //
-        // Also note that this check isn't run when the operand type is never
-        // (!). In that case we still need the earlier check to verify that the
-        // register class is usable at all.
-        if let Some(feature) = feature {
-            if !self.target_features.contains(feature) {
-                let msg = format!("`{feature}` target feature is not enabled");
-                self.infcx
-                    .dcx()
-                    .struct_span_err(expr.span, msg)
-                    .with_note(format!(
-                        "this is required to use type `{}` with register class `{}`",
-                        ty,
-                        reg_class.name(),
-                    ))
-                    .emit();
-                return Some(asm_ty);
-            }
-        }
-
-        // Check whether a modifier is suggested for using this type.
-        if let Some(ModifierInfo {
-            modifier: suggested_modifier,
-            result: suggested_result,
-            size: suggested_size,
-        }) = reg_class.suggest_modifier(asm_arch, asm_ty)
-        {
-            // Search for any use of this operand without a modifier and emit
-            // the suggestion for them.
-            let mut spans = vec![];
-            for piece in template {
-                if let &InlineAsmTemplatePiece::Placeholder { operand_idx, modifier, span } = piece
-                {
-                    if operand_idx == idx && modifier.is_none() {
-                        spans.push(span);
-                    }
-                }
-            }
-            if !spans.is_empty() {
-                let ModifierInfo {
-                    modifier: default_modifier,
-                    result: default_result,
-                    size: default_size,
-                } = reg_class.default_modifier(asm_arch).unwrap();
-                self.tcx().node_span_lint(
-                    lint::builtin::ASM_SUB_REGISTER,
-                    expr.hir_id,
-                    spans,
-                    |lint| {
-                        lint.primary_message("formatting may not be suitable for sub-register argument");
-                        lint.span_label(expr.span, "for this argument");
-                        lint.help(format!(
-                            "use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}` (for {suggested_size}-bit values)",
-                        ));
-                        lint.help(format!(
-                            "or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}` (for {default_size}-bit values)",
-                        ));
-                    },
-                );
-            }
-        }
-
-        Some(asm_ty)
-    }
-
-    pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>) {
-        let Some(asm_arch) = self.tcx().sess.asm_arch else {
-            self.infcx.dcx().delayed_bug("target architecture does not support asm");
-            return;
-        };
-        let allow_experimental_reg = self.tcx().features().asm_experimental_reg();
-        for (idx, &(op, op_sp)) in asm.operands.iter().enumerate() {
-            // Validate register classes against currently enabled target
-            // features. We check that at least one type is available for
-            // the enabled features.
-            //
-            // We ignore target feature requirements for clobbers: if the
-            // feature is disabled then the compiler doesn't care what we
-            // do with the registers.
-            //
-            // Note that this is only possible for explicit register
-            // operands, which cannot be used in the asm string.
-            if let Some(reg) = op.reg() {
-                // Some explicit registers cannot be used depending on the
-                // target. Reject those here.
-                if let InlineAsmRegOrRegClass::Reg(reg) = reg {
-                    if let InlineAsmReg::Err = reg {
-                        // `validate` will panic on `Err`, as an error must
-                        // already have been reported.
-                        continue;
-                    }
-                    if let Err(msg) = reg.validate(
-                        asm_arch,
-                        self.tcx().sess.relocation_model(),
-                        self.target_features,
-                        &self.tcx().sess.target,
-                        op.is_clobber(),
-                    ) {
-                        let msg = format!("cannot use register `{}`: {}", reg.name(), msg);
-                        self.infcx.dcx().span_err(op_sp, msg);
-                        continue;
-                    }
-                }
-
-                if !op.is_clobber() {
-                    let mut missing_required_features = vec![];
-                    let reg_class = reg.reg_class();
-                    if let InlineAsmRegClass::Err = reg_class {
-                        continue;
-                    }
-                    for &(_, feature) in reg_class.supported_types(asm_arch, allow_experimental_reg)
-                    {
-                        match feature {
-                            Some(feature) => {
-                                if self.target_features.contains(&feature) {
-                                    missing_required_features.clear();
-                                    break;
-                                } else {
-                                    missing_required_features.push(feature);
-                                }
-                            }
-                            None => {
-                                missing_required_features.clear();
-                                break;
-                            }
-                        }
-                    }
-
-                    // We are sorting primitive strs here and can use unstable sort here
-                    missing_required_features.sort_unstable();
-                    missing_required_features.dedup();
-                    match &missing_required_features[..] {
-                        [] => {}
-                        [feature] => {
-                            let msg = format!(
-                                "register class `{}` requires the `{}` target feature",
-                                reg_class.name(),
-                                feature
-                            );
-                            self.infcx.dcx().span_err(op_sp, msg);
-                            // register isn't enabled, don't do more checks
-                            continue;
-                        }
-                        features => {
-                            let msg = format!(
-                                "register class `{}` requires at least one of the following target features: {}",
-                                reg_class.name(),
-                                features
-                                    .iter()
-                                    .map(|f| f.as_str())
-                                    .intersperse(", ")
-                                    .collect::<String>(),
-                            );
-                            self.infcx.dcx().span_err(op_sp, msg);
-                            // register isn't enabled, don't do more checks
-                            continue;
-                        }
-                    }
-                }
-            }
-
-            match op {
-                hir::InlineAsmOperand::In { reg, expr } => {
-                    self.check_asm_operand_type(idx, reg, expr, asm.template, true, None);
-                }
-                hir::InlineAsmOperand::Out { reg, late: _, expr } => {
-                    if let Some(expr) = expr {
-                        self.check_asm_operand_type(idx, reg, expr, asm.template, false, None);
-                    }
-                }
-                hir::InlineAsmOperand::InOut { reg, late: _, expr } => {
-                    self.check_asm_operand_type(idx, reg, expr, asm.template, false, None);
-                }
-                hir::InlineAsmOperand::SplitInOut { reg, late: _, in_expr, out_expr } => {
-                    let in_ty =
-                        self.check_asm_operand_type(idx, reg, in_expr, asm.template, true, None);
-                    if let Some(out_expr) = out_expr {
-                        self.check_asm_operand_type(
-                            idx,
-                            reg,
-                            out_expr,
-                            asm.template,
-                            false,
-                            Some((in_expr, in_ty)),
-                        );
-                    }
-                }
-                hir::InlineAsmOperand::Const { anon_const } => {
-                    let ty = self.expr_ty(self.tcx().hir_body(anon_const.body).value);
-                    match ty.kind() {
-                        ty::Error(_) => {}
-                        _ if ty.is_integral() => {}
-                        _ => {
-                            self.infcx
-                                .dcx()
-                                .struct_span_err(op_sp, "invalid type for `const` operand")
-                                .with_span_label(
-                                    self.tcx().def_span(anon_const.def_id),
-                                    format!("is {} `{}`", ty.kind().article(), ty),
-                                )
-                                .with_help("`const` operands must be of an integer type")
-                                .emit();
-                        }
-                    }
-                }
-                // Typeck has checked that SymFn refers to a function.
-                hir::InlineAsmOperand::SymFn { expr } => {
-                    let ty = self.expr_ty(expr);
-                    match ty.kind() {
-                        ty::FnDef(..) => {}
-                        ty::Error(_) => {}
-                        _ => {
-                            self.infcx
-                                .dcx()
-                                .struct_span_err(op_sp, "invalid `sym` operand")
-                                .with_span_label(
-                                    expr.span,
-                                    format!("is {} `{}`", ty.kind().article(), ty),
-                                )
-                                .with_help(
-                                    "`sym` operands must refer to either a function or a static",
-                                )
-                                .emit();
-                        }
-                    }
-                }
-                // AST lowering guarantees that SymStatic points to a static.
-                hir::InlineAsmOperand::SymStatic { .. } => {}
-                // No special checking is needed for labels.
-                hir::InlineAsmOperand::Label { .. } => {}
-            }
-        }
-    }
-}
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 30921b6f055..fad8abf5fae 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -67,7 +67,6 @@ mod check;
 mod compare_impl_item;
 mod entry;
 pub mod intrinsic;
-pub mod intrinsicck;
 mod region;
 pub mod wfcheck;
 
@@ -205,7 +204,7 @@ fn missing_items_err(
 
     let missing_items_msg = missing_items
         .clone()
-        .map(|trait_item| trait_item.name.to_string())
+        .map(|trait_item| trait_item.name().to_string())
         .collect::<Vec<_>>()
         .join("`, `");
 
@@ -236,7 +235,7 @@ fn missing_items_err(
         let code = format!("{padding}{snippet}\n{padding}");
         if let Some(span) = tcx.hir_span_if_local(trait_item.def_id) {
             missing_trait_item_label
-                .push(errors::MissingTraitItemLabel { span, item: trait_item.name });
+                .push(errors::MissingTraitItemLabel { span, item: trait_item.name() });
             missing_trait_item.push(errors::MissingTraitItemSuggestion {
                 span: sugg_sp,
                 code,
@@ -407,14 +406,14 @@ fn fn_sig_suggestion<'tcx>(
         .enumerate()
         .map(|(i, ty)| {
             Some(match ty.kind() {
-                ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
+                ty::Param(_) if assoc.is_method() && i == 0 => "self".to_string(),
                 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
                     let reg = format!("{reg} ");
                     let reg = match &reg[..] {
                         "'_ " | " " => "",
                         reg => reg,
                     };
-                    if assoc.fn_has_self_parameter {
+                    if assoc.is_method() {
                         match ref_ty.kind() {
                             ty::Param(param) if param.name == kw::SelfUpper => {
                                 format!("&{}{}self", reg, mutability.prefix_str())
@@ -427,7 +426,7 @@ fn fn_sig_suggestion<'tcx>(
                     }
                 }
                 _ => {
-                    if assoc.fn_has_self_parameter && i == 0 {
+                    if assoc.is_method() && i == 0 {
                         format!("self: {ty}")
                     } else {
                         format!("_: {ty}")
@@ -489,7 +488,7 @@ fn suggestion_signature<'tcx>(
     );
 
     match assoc.kind {
-        ty::AssocKind::Fn => fn_sig_suggestion(
+        ty::AssocKind::Fn { .. } => fn_sig_suggestion(
             tcx,
             tcx.liberate_late_bound_regions(
                 assoc.def_id,
@@ -499,14 +498,14 @@ fn suggestion_signature<'tcx>(
             tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args),
             assoc,
         ),
-        ty::AssocKind::Type => {
+        ty::AssocKind::Type { .. } => {
             let (generics, where_clauses) = bounds_from_generic_predicates(
                 tcx,
                 tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args),
             );
-            format!("type {}{generics} = /* Type */{where_clauses};", assoc.name)
+            format!("type {}{generics} = /* Type */{where_clauses};", assoc.name())
         }
-        ty::AssocKind::Const => {
+        ty::AssocKind::Const { name } => {
             let ty = tcx.type_of(assoc.def_id).instantiate_identity();
             let val = tcx
                 .infer_ctxt()
@@ -514,7 +513,7 @@ fn suggestion_signature<'tcx>(
                 .err_ctxt()
                 .ty_kind_suggestion(tcx.param_env(assoc.def_id), ty)
                 .unwrap_or_else(|| "value".to_string());
-            format!("const {}: {} = {};", assoc.name, ty, val)
+            format!("const {}: {} = {};", name, ty, val)
         }
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 6292d03bf6a..fa36fe79716 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -76,12 +76,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
         )
     }
 
-    fn register_wf_obligation(
-        &self,
-        span: Span,
-        loc: Option<WellFormedLoc>,
-        arg: ty::GenericArg<'tcx>,
-    ) {
+    fn register_wf_obligation(&self, span: Span, loc: Option<WellFormedLoc>, term: ty::Term<'tcx>) {
         let cause = traits::ObligationCause::new(
             span,
             self.body_def_id,
@@ -91,7 +86,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
             self.tcx(),
             cause,
             self.param_env,
-            ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg))),
+            ty::ClauseKind::WellFormed(term),
         ));
     }
 }
@@ -408,7 +403,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
             let gat_def_id = gat_item.def_id.expect_local();
             let gat_item = tcx.associated_item(gat_def_id);
             // If this item is not an assoc ty, or has no args, then it's not a GAT
-            if gat_item.kind != ty::AssocKind::Type {
+            if !gat_item.is_type() {
                 continue;
             }
             let gat_generics = tcx.generics_of(gat_def_id);
@@ -432,7 +427,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
 
                 let item_required_bounds = match tcx.associated_item(item_def_id).kind {
                     // In our example, this corresponds to `into_iter` method
-                    ty::AssocKind::Fn => {
+                    ty::AssocKind::Fn { .. } => {
                         // For methods, we check the function signature's return type for any GATs
                         // to constrain. In the `into_iter` case, we see that the return type
                         // `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from.
@@ -453,7 +448,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
                         )
                     }
                     // In our example, this corresponds to the `Iter` and `Item` associated types
-                    ty::AssocKind::Type => {
+                    ty::AssocKind::Type { .. } => {
                         // If our associated item is a GAT with missing bounds, add them to
                         // the param-env here. This allows this GAT to propagate missing bounds
                         // to other GATs.
@@ -474,7 +469,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
                             gat_generics,
                         )
                     }
-                    ty::AssocKind::Const => None,
+                    ty::AssocKind::Const { .. } => None,
                 };
 
                 if let Some(item_required_bounds) = item_required_bounds {
@@ -1076,7 +1071,7 @@ fn check_associated_item(
         };
 
         match item.kind {
-            ty::AssocKind::Const => {
+            ty::AssocKind::Const { .. } => {
                 let ty = tcx.type_of(item.def_id).instantiate_identity();
                 let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
                 wfcx.register_wf_obligation(span, loc, ty.into());
@@ -1089,7 +1084,7 @@ fn check_associated_item(
                 );
                 Ok(())
             }
-            ty::AssocKind::Fn => {
+            ty::AssocKind::Fn { .. } => {
                 let sig = tcx.fn_sig(item.def_id).instantiate_identity();
                 let hir_sig = sig_if_method.expect("bad signature for method");
                 check_fn_or_method(
@@ -1101,7 +1096,7 @@ fn check_associated_item(
                 );
                 check_method_receiver(wfcx, hir_sig, item, self_ty)
             }
-            ty::AssocKind::Type => {
+            ty::AssocKind::Type { .. } => {
                 if let ty::AssocItemContainer::Trait = item.container {
                     check_associated_type_bounds(wfcx, item, span)
                 }
@@ -1486,8 +1481,41 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
                     tcx.def_span(param.def_id),
                     matches!(param.kind, GenericParamDefKind::Type { .. })
                         .then(|| WellFormedLoc::Ty(param.def_id.expect_local())),
-                    default,
+                    default.as_term().unwrap(),
                 );
+            } else {
+                // If we've got a generic const parameter we still want to check its
+                // type is correct in case both it and the param type are fully concrete.
+                let GenericArgKind::Const(ct) = default.unpack() else {
+                    continue;
+                };
+
+                let ct_ty = match ct.kind() {
+                    ty::ConstKind::Infer(_)
+                    | ty::ConstKind::Placeholder(_)
+                    | ty::ConstKind::Bound(_, _) => unreachable!(),
+                    ty::ConstKind::Error(_) | ty::ConstKind::Expr(_) => continue,
+                    ty::ConstKind::Value(cv) => cv.ty,
+                    ty::ConstKind::Unevaluated(uv) => {
+                        infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args)
+                    }
+                    ty::ConstKind::Param(param_ct) => param_ct.find_ty_from_env(wfcx.param_env),
+                };
+
+                let param_ty = tcx.type_of(param.def_id).instantiate_identity();
+                if !ct_ty.has_param() && !param_ty.has_param() {
+                    let cause = traits::ObligationCause::new(
+                        tcx.def_span(param.def_id),
+                        wfcx.body_def_id,
+                        ObligationCauseCode::WellFormed(None),
+                    );
+                    wfcx.register_obligation(Obligation::new(
+                        tcx,
+                        cause,
+                        wfcx.param_env,
+                        ty::ClauseKind::ConstArgHasType(ct, param_ty),
+                    ));
+                }
             }
         }
     }
@@ -1716,7 +1744,7 @@ fn check_method_receiver<'tcx>(
 ) -> Result<(), ErrorGuaranteed> {
     let tcx = wfcx.tcx();
 
-    if !method.fn_has_self_parameter {
+    if !method.is_method() {
         return Ok(());
     }
 
@@ -1991,7 +2019,7 @@ fn check_variances_for_type_defn<'tcx>(
         ItemKind::TyAlias(..) => {
             assert!(
                 tcx.type_alias_is_lazy(item.owner_id),
-                "should not be computing variance of non-weak type alias"
+                "should not be computing variance of non-free type alias"
             );
         }
         kind => span_bug!(item.span, "cannot compute the variances of {kind:?}"),
@@ -2223,7 +2251,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsProbablyCyclical<'tcx> {
     fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<(), ()> {
         let def_id = match ty.kind() {
             ty::Adt(adt_def, _) => Some(adt_def.did()),
-            ty::Alias(ty::Weak, alias_ty) => Some(alias_ty.def_id),
+            ty::Alias(ty::Free, alias_ty) => Some(alias_ty.def_id),
             _ => None,
         };
         if let Some(def_id) = def_id {
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 8ad9d80c6b5..52656fc2d90 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -750,7 +750,7 @@ fn visit_implementation_of_pointer_like(checker: &Checker<'_>) -> Result<(), Err
                         ObligationCause::misc(impl_span, checker.impl_def_id),
                         param_env,
                         nontrivial_field_ty,
-                        tcx.lang_items().pointer_like().unwrap(),
+                        tcx.require_lang_item(LangItem::PointerLike, Some(impl_span)),
                     );
                     // FIXME(dyn-star): We should regionck this implementation.
                     if ocx.select_all_or_error().is_empty() {
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
index c9a9180c5c9..bd25b4a3260 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
@@ -150,7 +150,7 @@ impl<'tcx> InherentCollect<'tcx> {
         let id = id.owner_id.def_id;
         let item_span = self.tcx.def_span(id);
         let self_ty = self.tcx.type_of(id).instantiate_identity();
-        let mut self_ty = self.tcx.peel_off_weak_alias_tys(self_ty);
+        let mut self_ty = self.tcx.peel_off_free_alias_tys(self_ty);
         // We allow impls on pattern types exactly when we allow impls on the base type.
         // FIXME(pattern_types): Figure out the exact coherence rules we want here.
         while let ty::Pat(base, _) = *self_ty.kind() {
@@ -188,7 +188,7 @@ impl<'tcx> InherentCollect<'tcx> {
             | ty::CoroutineClosure(..)
             | ty::Coroutine(..)
             | ty::CoroutineWitness(..)
-            | ty::Alias(ty::Weak, _)
+            | ty::Alias(ty::Free, _)
             | ty::Bound(..)
             | ty::Placeholder(_)
             | ty::Infer(_) => {
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
index dc616576c9c..242639125b1 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
@@ -51,7 +51,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
 
         for &item1 in impl_items1.in_definition_order() {
             let collision = impl_items2
-                .filter_by_name_unhygienic(item1.name)
+                .filter_by_name_unhygienic(item1.name())
                 .any(|&item2| self.compare_hygienically(item1, item2));
 
             if collision {
@@ -64,7 +64,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
 
     fn compare_hygienically(&self, item1: ty::AssocItem, item2: ty::AssocItem) -> bool {
         // Symbols and namespace match, compare hygienically.
-        item1.kind.namespace() == item2.kind.namespace()
+        item1.namespace() == item2.namespace()
             && item1.ident(self.tcx).normalize_to_macros_2_0()
                 == item2.ident(self.tcx).normalize_to_macros_2_0()
     }
@@ -113,7 +113,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
         let mut res = Ok(());
         for &item1 in impl_items1.in_definition_order() {
             let collision = impl_items2
-                .filter_by_name_unhygienic(item1.name)
+                .filter_by_name_unhygienic(item1.name())
                 .find(|&&item2| self.compare_hygienically(item1, item2));
 
             if let Some(item2) = collision {
@@ -230,11 +230,11 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
                 let mut ids = impl_items
                     .in_definition_order()
                     .filter_map(|item| {
-                        let entry = connected_region_ids.entry(item.name);
+                        let entry = connected_region_ids.entry(item.name());
                         if let IndexEntry::Occupied(e) = &entry {
                             Some(*e.get())
                         } else {
-                            idents_to_add.push(item.name);
+                            idents_to_add.push(item.name());
                             None
                         }
                     })
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 74ba4ffe25e..c75fef9f716 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -189,7 +189,7 @@ pub(crate) fn orphan_check_impl(
                     ty::Projection => "associated type",
                     // type Foo = (impl Sized, bool)
                     // impl AutoTrait for Foo {}
-                    ty::Weak => "type alias",
+                    ty::Free => "type alias",
                     // type Opaque = impl Trait;
                     // impl AutoTrait for Opaque {}
                     ty::Opaque => "opaque type",
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 69b921fccbf..4520fbe352c 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -44,7 +44,7 @@ use rustc_trait_selection::traits::ObligationCtxt;
 use tracing::{debug, instrument};
 
 use crate::errors;
-use crate::hir_ty_lowering::errors::assoc_kind_str;
+use crate::hir_ty_lowering::errors::assoc_tag_str;
 use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer, RegionInferReason};
 
 pub(crate) mod dump;
@@ -439,9 +439,9 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
         &self,
         span: Span,
         def_id: LocalDefId,
-        assoc_name: Ident,
+        assoc_ident: Ident,
     ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
-        self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_name))
+        self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_ident))
     }
 
     fn lower_assoc_shared(
@@ -450,7 +450,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
         item_def_id: DefId,
         item_segment: &rustc_hir::PathSegment<'tcx>,
         poly_trait_ref: ty::PolyTraitRef<'tcx>,
-        kind: ty::AssocKind,
+        assoc_tag: ty::AssocTag,
     ) -> Result<(DefId, ty::GenericArgsRef<'tcx>), ErrorGuaranteed> {
         if let Some(trait_ref) = poly_trait_ref.no_bound_vars() {
             let item_args = self.lowerer().lower_generic_args_of_assoc_item(
@@ -525,7 +525,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
                 inferred_sugg,
                 bound,
                 mpart_sugg,
-                what: assoc_kind_str(kind),
+                what: assoc_tag_str(assoc_tag),
             }))
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index e90a1cc24c1..ce0f83d0ec2 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -584,12 +584,12 @@ pub(super) fn explicit_super_predicates_of<'tcx>(
 
 pub(super) fn explicit_supertraits_containing_assoc_item<'tcx>(
     tcx: TyCtxt<'tcx>,
-    (trait_def_id, assoc_name): (DefId, Ident),
+    (trait_def_id, assoc_ident): (DefId, Ident),
 ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
     implied_predicates_with_filter(
         tcx,
         trait_def_id,
-        PredicateFilter::SelfTraitThatDefines(assoc_name),
+        PredicateFilter::SelfTraitThatDefines(assoc_ident),
     )
 }
 
@@ -617,7 +617,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
     filter: PredicateFilter,
 ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
     let Some(trait_def_id) = trait_def_id.as_local() else {
-        // if `assoc_name` is None, then the query should've been redirected to an
+        // if `assoc_ident` is None, then the query should've been redirected to an
         // external provider
         assert_matches!(filter, PredicateFilter::SelfTraitThatDefines(_));
         return tcx.explicit_super_predicates_of(trait_def_id);
@@ -834,11 +834,11 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>(
 #[instrument(level = "trace", skip(tcx))]
 pub(super) fn type_param_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
-    (item_def_id, def_id, assoc_name): (LocalDefId, LocalDefId, Ident),
+    (item_def_id, def_id, assoc_ident): (LocalDefId, LocalDefId, Ident),
 ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
     match tcx.opt_rpitit_info(item_def_id.to_def_id()) {
         Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
-            return tcx.type_param_predicates((opaque_def_id.expect_local(), def_id, assoc_name));
+            return tcx.type_param_predicates((opaque_def_id.expect_local(), def_id, assoc_ident));
         }
         Some(ty::ImplTraitInTraitData::Impl { .. }) => {
             unreachable!("should not be lowering bounds on RPITIT in impl")
@@ -863,7 +863,7 @@ pub(super) fn type_param_predicates<'tcx>(
 
     let result = if let Some(parent) = parent {
         let icx = ItemCtxt::new(tcx, parent);
-        icx.probe_ty_param_bounds(DUMMY_SP, def_id, assoc_name)
+        icx.probe_ty_param_bounds(DUMMY_SP, def_id, assoc_ident)
     } else {
         ty::EarlyBinder::bind(&[] as &[_])
     };
@@ -889,7 +889,7 @@ pub(super) fn type_param_predicates<'tcx>(
     let extra_predicates = extend.into_iter().chain(icx.probe_ty_param_bounds_in_generics(
         hir_generics,
         def_id,
-        PredicateFilter::SelfTraitThatDefines(assoc_name),
+        PredicateFilter::SelfTraitThatDefines(assoc_ident),
     ));
 
     let bounds =
@@ -908,7 +908,7 @@ pub(super) fn type_param_predicates<'tcx>(
         _ => unreachable!(),
     };
     assert_only_contains_predicates_from(
-        PredicateFilter::SelfTraitThatDefines(assoc_name),
+        PredicateFilter::SelfTraitThatDefines(assoc_ident),
         bounds,
         self_ty,
     );
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 404753875ee..59ab36d98fd 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -16,7 +16,7 @@ use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt};
 use rustc_hir::{
-    self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeName, Node,
+    self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeKind, Node,
 };
 use rustc_macros::extension;
 use rustc_middle::hir::nested_filter;
@@ -646,14 +646,14 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
         arg: &'tcx hir::PreciseCapturingArg<'tcx>,
     ) -> Self::Result {
         match *arg {
-            hir::PreciseCapturingArg::Lifetime(lt) => match lt.res {
-                LifetimeName::Param(def_id) => {
+            hir::PreciseCapturingArg::Lifetime(lt) => match lt.kind {
+                LifetimeKind::Param(def_id) => {
                     self.resolve_lifetime_ref(def_id, lt);
                 }
-                LifetimeName::Error => {}
-                LifetimeName::ImplicitObjectLifetimeDefault
-                | LifetimeName::Infer
-                | LifetimeName::Static => {
+                LifetimeKind::Error => {}
+                LifetimeKind::ImplicitObjectLifetimeDefault
+                | LifetimeKind::Infer
+                | LifetimeKind::Static => {
                     self.tcx.dcx().emit_err(errors::BadPreciseCapture {
                         span: lt.ident.span,
                         kind: "lifetime",
@@ -774,26 +774,26 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                         );
                     }
                 });
-                match lifetime.res {
-                    LifetimeName::ImplicitObjectLifetimeDefault => {
+                match lifetime.kind {
+                    LifetimeKind::ImplicitObjectLifetimeDefault => {
                         // If the user does not write *anything*, we
                         // use the object lifetime defaulting
                         // rules. So e.g., `Box<dyn Debug>` becomes
                         // `Box<dyn Debug + 'static>`.
                         self.resolve_object_lifetime_default(&*lifetime)
                     }
-                    LifetimeName::Infer => {
+                    LifetimeKind::Infer => {
                         // If the user writes `'_`, we use the *ordinary* elision
                         // rules. So the `'_` in e.g., `Box<dyn Debug + '_>` will be
                         // resolved the same as the `'_` in `&'_ Foo`.
                         //
                         // cc #48468
                     }
-                    LifetimeName::Param(..) | LifetimeName::Static => {
+                    LifetimeKind::Param(..) | LifetimeKind::Static => {
                         // If the user wrote an explicit name, use that.
                         self.visit_lifetime(&*lifetime);
                     }
-                    LifetimeName::Error => {}
+                    LifetimeKind::Error => {}
                 }
             }
             hir::TyKind::Ref(lifetime_ref, ref mt) => {
@@ -873,17 +873,17 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
 
     #[instrument(level = "debug", skip(self))]
     fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
-        match lifetime_ref.res {
-            hir::LifetimeName::Static => {
+        match lifetime_ref.kind {
+            hir::LifetimeKind::Static => {
                 self.insert_lifetime(lifetime_ref, ResolvedArg::StaticLifetime)
             }
-            hir::LifetimeName::Param(param_def_id) => {
+            hir::LifetimeKind::Param(param_def_id) => {
                 self.resolve_lifetime_ref(param_def_id, lifetime_ref)
             }
             // If we've already reported an error, just ignore `lifetime_ref`.
-            hir::LifetimeName::Error => {}
+            hir::LifetimeKind::Error => {}
             // Those will be resolved by typechecking.
-            hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Infer => {}
+            hir::LifetimeKind::ImplicitObjectLifetimeDefault | hir::LifetimeKind::Infer => {}
         }
     }
 
@@ -1063,15 +1063,15 @@ fn object_lifetime_default(tcx: TyCtxt<'_>, param_def_id: LocalDefId) -> ObjectL
 
                         for bound in bound.bounds {
                             if let hir::GenericBound::Outlives(lifetime) = bound {
-                                set.insert(lifetime.res);
+                                set.insert(lifetime.kind);
                             }
                         }
                     }
 
                     match set {
                         Set1::Empty => ObjectLifetimeDefault::Empty,
-                        Set1::One(hir::LifetimeName::Static) => ObjectLifetimeDefault::Static,
-                        Set1::One(hir::LifetimeName::Param(param_def_id)) => {
+                        Set1::One(hir::LifetimeKind::Static) => ObjectLifetimeDefault::Static,
+                        Set1::One(hir::LifetimeKind::Param(param_def_id)) => {
                             ObjectLifetimeDefault::Param(param_def_id.to_def_id())
                         }
                         _ => ObjectLifetimeDefault::Ambiguous,
@@ -1241,7 +1241,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                     // Fresh lifetimes in APIT used to be allowed in async fns and forbidden in
                     // regular fns.
                     if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin
-                        && let hir::LifetimeName::Param(param_id) = lifetime_ref.res
+                        && let hir::LifetimeKind::Param(param_id) = lifetime_ref.kind
                         && let Some(generics) =
                             self.tcx.hir_get_generics(self.tcx.local_parent(param_id))
                         && let Some(param) = generics.params.iter().find(|p| p.def_id == param_id)
@@ -1811,7 +1811,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                         self.tcx,
                         type_def_id,
                         constraint.ident,
-                        ty::AssocKind::Fn,
+                        ty::AssocTag::Fn,
                     ) {
                     bound_vars.extend(
                         self.tcx
@@ -1843,7 +1843,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                     self.tcx,
                     type_def_id,
                     constraint.ident,
-                    ty::AssocKind::Type,
+                    ty::AssocTag::Type,
                 )
                 .map(|(bound_vars, _)| bound_vars);
                 self.with(scope, |this| {
@@ -1874,14 +1874,14 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
     fn supertrait_hrtb_vars(
         tcx: TyCtxt<'tcx>,
         def_id: DefId,
-        assoc_name: Ident,
-        assoc_kind: ty::AssocKind,
+        assoc_ident: Ident,
+        assoc_tag: ty::AssocTag,
     ) -> Option<(Vec<ty::BoundVariableKind>, &'tcx ty::AssocItem)> {
         let trait_defines_associated_item_named = |trait_def_id: DefId| {
-            tcx.associated_items(trait_def_id).find_by_name_and_kind(
+            tcx.associated_items(trait_def_id).find_by_ident_and_kind(
                 tcx,
-                assoc_name,
-                assoc_kind,
+                assoc_ident,
+                assoc_tag,
                 trait_def_id,
             )
         };
@@ -1894,8 +1894,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
             let Some((def_id, bound_vars)) = stack.pop() else {
                 break None;
             };
-            // See issue #83753. If someone writes an associated type on a non-trait, just treat it as
-            // there being no supertrait HRTBs.
+            // See issue #83753. If someone writes an associated type on a non-trait, just treat it
+            // as there being no supertrait HRTBs.
             match tcx.def_kind(def_id) {
                 DefKind::Trait | DefKind::TraitAlias | DefKind::Impl { .. } => {}
                 _ => break None,
@@ -1904,7 +1904,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
             if let Some(assoc_item) = trait_defines_associated_item_named(def_id) {
                 break Some((bound_vars.into_iter().collect(), assoc_item));
             }
-            let predicates = tcx.explicit_supertraits_containing_assoc_item((def_id, assoc_name));
+            let predicates = tcx.explicit_supertraits_containing_assoc_item((def_id, assoc_ident));
             let obligations = predicates.iter_identity_copied().filter_map(|(pred, _)| {
                 let bound_predicate = pred.kind();
                 match bound_predicate.skip_binder() {
@@ -2067,7 +2067,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                                     self.tcx,
                                     trait_def_id,
                                     item_segment.ident,
-                                    ty::AssocKind::Fn,
+                                    ty::AssocTag::Fn,
                                 )
                             });
 
@@ -2112,7 +2112,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                             self.tcx,
                             trait_def_id,
                             item_segment.ident,
-                            ty::AssocKind::Fn,
+                            ty::AssocTag::Fn,
                         ) else {
                             return;
                         };
@@ -2440,7 +2440,7 @@ fn is_late_bound_map(
         }
 
         fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
-            if let hir::LifetimeName::Param(def_id) = lifetime_ref.res {
+            if let hir::LifetimeKind::Param(def_id) = lifetime_ref.kind {
                 self.regions.insert(def_id);
             }
         }
@@ -2453,7 +2453,7 @@ fn is_late_bound_map(
 
     impl<'tcx> Visitor<'tcx> for AllCollector {
         fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
-            if let hir::LifetimeName::Param(def_id) = lifetime_ref.res {
+            if let hir::LifetimeKind::Param(def_id) = lifetime_ref.kind {
                 self.regions.insert(def_id);
             }
         }
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 694c1228859..c20b14df770 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -94,10 +94,12 @@ fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: S
         }
 
         Node::TyPat(pat) => {
-            let hir::TyKind::Pat(ty, p) = tcx.parent_hir_node(pat.hir_id).expect_ty().kind else {
-                bug!()
+            let node = match tcx.parent_hir_node(pat.hir_id) {
+                // Or patterns can be nested one level deep
+                Node::TyPat(p) => tcx.parent_hir_node(p.hir_id),
+                other => other,
             };
-            assert_eq!(p.hir_id, pat.hir_id);
+            let hir::TyKind::Pat(ty, _) = node.expect_ty().kind else { bug!() };
             icx.lower_ty(ty)
         }
 
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index 772197a53ac..50e20a19eda 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -32,9 +32,11 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
     for &assoc_id in tcx.associated_item_def_ids(impl_def_id) {
         let assoc = tcx.associated_item(assoc_id);
         match assoc.kind {
-            ty::AssocKind::Const | ty::AssocKind::Fn => locator.check(assoc_id.expect_local()),
+            ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => {
+                locator.check(assoc_id.expect_local())
+            }
             // Associated types don't have bodies, so they can't constrain hidden types
-            ty::AssocKind::Type => {}
+            ty::AssocKind::Type { .. } => {}
         }
     }
 
diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
index 951eda72ffe..366b3943a05 100644
--- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
+++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
@@ -49,7 +49,7 @@ pub(crate) fn parameters_for<'tcx>(
     include_nonconstraining: bool,
 ) -> Vec<Parameter> {
     let mut collector = ParameterCollector { parameters: vec![], include_nonconstraining };
-    let value = if !include_nonconstraining { tcx.expand_weak_alias_tys(value) } else { value };
+    let value = if !include_nonconstraining { tcx.expand_free_alias_tys(value) } else { value };
     value.visit_with(&mut collector);
     collector.parameters
 }
@@ -68,9 +68,9 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParameterCollector {
             {
                 return;
             }
-            // All weak alias types should've been expanded beforehand.
-            ty::Alias(ty::Weak, _) if !self.include_nonconstraining => {
-                bug!("unexpected weak alias type")
+            // All free alias types should've been expanded beforehand.
+            ty::Alias(ty::Free, _) if !self.include_nonconstraining => {
+                bug!("unexpected free alias type")
             }
             ty::Param(param) => self.parameters.push(Parameter::from(param)),
             _ => {}
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index e6090a128b1..2b1661aaac8 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -23,7 +23,7 @@ pub(crate) struct AmbiguousAssocItem<'a> {
     #[label]
     pub span: Span,
     pub assoc_kind: &'static str,
-    pub assoc_name: Ident,
+    pub assoc_ident: Ident,
     pub qself: &'a str,
 }
 
@@ -75,7 +75,7 @@ pub(crate) struct AssocItemIsPrivate {
 pub(crate) struct AssocItemNotFound<'a> {
     #[primary_span]
     pub span: Span,
-    pub assoc_name: Ident,
+    pub assoc_ident: Ident,
     pub assoc_kind: &'static str,
     pub qself: &'a str,
     #[subdiagnostic]
@@ -1675,14 +1675,6 @@ pub(crate) struct CmseEntryGeneric {
     pub span: Span,
 }
 
-#[derive(Diagnostic)]
-#[diag(hir_analysis_register_type_unstable)]
-pub(crate) struct RegisterTypeUnstable<'a> {
-    #[primary_span]
-    pub span: Span,
-    pub ty: Ty<'a>,
-}
-
 #[derive(LintDiagnostic)]
 #[diag(hir_analysis_supertrait_item_shadowing)]
 pub(crate) struct SupertraitItemShadowing {
diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs
index 610b293a114..a3c8ce620b3 100644
--- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs
@@ -4,7 +4,7 @@ use GenericArgsInfo::*;
 use rustc_errors::codes::*;
 use rustc_errors::{Applicability, Diag, Diagnostic, EmissionGuarantee, MultiSpan, pluralize};
 use rustc_hir as hir;
-use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt};
+use rustc_middle::ty::{self as ty, AssocItems, TyCtxt};
 use rustc_span::def_id::DefId;
 use tracing::debug;
 
@@ -486,15 +486,15 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
             let items: &AssocItems = self.tcx.associated_items(self.def_id);
             items
                 .in_definition_order()
-                .filter(|item| item.kind == AssocKind::Type)
                 .filter(|item| {
-                    !self
-                        .gen_args
-                        .constraints
-                        .iter()
-                        .any(|constraint| constraint.ident.name == item.name)
+                    item.is_type()
+                        && !item.is_impl_trait_in_trait()
+                        && !self
+                            .gen_args
+                            .constraints
+                            .iter()
+                            .any(|constraint| constraint.ident.name == item.name())
                 })
-                .filter(|item| !item.is_impl_trait_in_trait())
                 .map(|item| self.tcx.item_ident(item.def_id).to_string())
                 .collect()
         } else {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index 55087d1f400..bf91eb1b8fd 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -363,10 +363,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         for hir_bound in hir_bounds {
             // In order to avoid cycles, when we're lowering `SelfTraitThatDefines`,
             // we skip over any traits that don't define the given associated type.
-            if let PredicateFilter::SelfTraitThatDefines(assoc_name) = predicate_filter {
+            if let PredicateFilter::SelfTraitThatDefines(assoc_ident) = predicate_filter {
                 if let Some(trait_ref) = hir_bound.trait_ref()
                     && let Some(trait_did) = trait_ref.trait_def_id()
-                    && self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
+                    && self.tcx().trait_may_define_assoc_item(trait_did, assoc_ident)
                 {
                     // Okay
                 } else {
@@ -431,16 +431,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     ) -> Result<(), ErrorGuaranteed> {
         let tcx = self.tcx();
 
-        let assoc_kind = if constraint.gen_args.parenthesized
+        let assoc_tag = if constraint.gen_args.parenthesized
             == hir::GenericArgsParentheses::ReturnTypeNotation
         {
-            ty::AssocKind::Fn
+            ty::AssocTag::Fn
         } else if let hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(_) } =
             constraint.kind
         {
-            ty::AssocKind::Const
+            ty::AssocTag::Const
         } else {
-            ty::AssocKind::Type
+            ty::AssocTag::Type
         };
 
         // Given something like `U: Trait<T = X>`, we want to produce a predicate like
@@ -453,7 +453,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         //     trait SuperTrait<A> { type T; }
         let candidate = if self.probe_trait_that_defines_assoc_item(
             trait_ref.def_id(),
-            assoc_kind,
+            assoc_tag,
             constraint.ident,
         ) {
             // Simple case: The assoc item is defined in the current trait.
@@ -464,7 +464,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             self.probe_single_bound_for_assoc_item(
                 || traits::supertraits(tcx, trait_ref),
                 AssocItemQSelf::Trait(trait_ref.def_id()),
-                assoc_kind,
+                assoc_tag,
                 constraint.ident,
                 path_span,
                 Some(constraint),
@@ -474,7 +474,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let assoc_item = self
             .probe_assoc_item(
                 constraint.ident,
-                assoc_kind,
+                assoc_tag,
                 hir_ref_id,
                 constraint.span,
                 candidate.def_id(),
@@ -493,7 +493,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             })
             .or_insert(constraint.span);
 
-        let projection_term = if let ty::AssocKind::Fn = assoc_kind {
+        let projection_term = if let ty::AssocTag::Fn = assoc_tag {
             let bound_vars = tcx.late_bound_vars(constraint.hir_id);
             ty::Binder::bind_with_vars(
                 self.lower_return_type_notation_ty(candidate, assoc_item.def_id, path_span)?.into(),
@@ -542,7 +542,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         };
 
         match constraint.kind {
-            hir::AssocItemConstraintKind::Equality { .. } if let ty::AssocKind::Fn = assoc_kind => {
+            hir::AssocItemConstraintKind::Equality { .. } if let ty::AssocTag::Fn = assoc_tag => {
                 return Err(self.dcx().emit_err(crate::errors::ReturnTypeNotationEqualityBound {
                     span: constraint.span,
                 }));
@@ -679,7 +679,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         trait_def_id,
                         hir_ty.span,
                         item_segment,
-                        ty::AssocKind::Type,
+                        ty::AssocTag::Type,
                     );
                     return Ty::new_error(tcx, guar);
                 };
@@ -771,7 +771,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         )
                     },
                     AssocItemQSelf::SelfTyAlias,
-                    ty::AssocKind::Fn,
+                    ty::AssocTag::Fn,
                     assoc_ident,
                     span,
                     None,
@@ -783,7 +783,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             ) => self.probe_single_ty_param_bound_for_assoc_item(
                 param_did.expect_local(),
                 qself.span,
-                ty::AssocKind::Fn,
+                ty::AssocTag::Fn,
                 assoc_ident,
                 span,
             )?,
@@ -823,7 +823,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         let trait_def_id = bound.def_id();
         let assoc_ty = self
-            .probe_assoc_item(assoc_ident, ty::AssocKind::Fn, qpath_hir_id, span, trait_def_id)
+            .probe_assoc_item(assoc_ident, ty::AssocTag::Fn, qpath_hir_id, span, trait_def_id)
             .expect("failed to find associated type");
 
         Ok((bound, assoc_ty.def_id))
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
index ecb453bced0..d1ee5a5494c 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
@@ -49,13 +49,13 @@ pub(crate) fn validate_cmse_abi<'tcx>(
                 Ok(Err(index)) => {
                     // fn(x: u32, u32, u32, u16, y: u16) -> u32,
                     //                           ^^^^^^
-                    let span = if let Some(ident) = bare_fn_ty.param_names[index] {
+                    let span = if let Some(ident) = bare_fn_ty.param_idents[index] {
                         ident.span.to(bare_fn_ty.decl.inputs[index].span)
                     } else {
                         bare_fn_ty.decl.inputs[index].span
                     }
                     .to(bare_fn_ty.decl.inputs.last().unwrap().span);
-                    let plural = bare_fn_ty.param_names.len() - index != 1;
+                    let plural = bare_fn_ty.param_idents.len() - index != 1;
                     dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi });
                 }
                 Err(layout_err) => {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index e64cd8ec302..88f74589204 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -201,7 +201,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                             tcx.associated_items(pred.trait_ref.def_id)
                                 .in_definition_order()
                                 // We only care about associated types.
-                                .filter(|item| item.kind == ty::AssocKind::Type)
+                                .filter(|item| item.is_type())
                                 // No RPITITs -- they're not dyn-compatible for now.
                                 .filter(|item| !item.is_impl_trait_in_trait())
                                 // If the associated type has a `where Self: Sized` bound,
@@ -415,7 +415,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime)
                 } else {
                     let reason =
-                        if let hir::LifetimeName::ImplicitObjectLifetimeDefault = lifetime.res {
+                        if let hir::LifetimeKind::ImplicitObjectLifetimeDefault = lifetime.kind {
                             if let hir::Node::Ty(hir::Ty {
                                 kind: hir::TyKind::Ref(parent_lifetime, _),
                                 ..
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 6e9c178d33a..3759a224ff7 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -116,8 +116,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         &self,
         all_candidates: impl Fn() -> I,
         qself: AssocItemQSelf,
-        assoc_kind: ty::AssocKind,
-        assoc_name: Ident,
+        assoc_tag: ty::AssocTag,
+        assoc_ident: Ident,
         span: Span,
         constraint: Option<&hir::AssocItemConstraint<'tcx>>,
     ) -> ErrorGuaranteed
@@ -129,31 +129,35 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // First and foremost, provide a more user-friendly & “intuitive” error on kind mismatches.
         if let Some(assoc_item) = all_candidates().find_map(|r| {
             tcx.associated_items(r.def_id())
-                .filter_by_name_unhygienic(assoc_name.name)
-                .find(|item| tcx.hygienic_eq(assoc_name, item.ident(tcx), r.def_id()))
+                .filter_by_name_unhygienic(assoc_ident.name)
+                .find(|item| tcx.hygienic_eq(assoc_ident, item.ident(tcx), r.def_id()))
         }) {
             return self.complain_about_assoc_kind_mismatch(
-                assoc_item, assoc_kind, assoc_name, span, constraint,
+                assoc_item,
+                assoc_tag,
+                assoc_ident,
+                span,
+                constraint,
             );
         }
 
-        let assoc_kind_str = assoc_kind_str(assoc_kind);
+        let assoc_kind_str = assoc_tag_str(assoc_tag);
         let qself_str = qself.to_string(tcx);
 
         // The fallback span is needed because `assoc_name` might be an `Fn()`'s `Output` without a
         // valid span, so we point at the whole path segment instead.
-        let is_dummy = assoc_name.span == DUMMY_SP;
+        let is_dummy = assoc_ident.span == DUMMY_SP;
 
         let mut err = errors::AssocItemNotFound {
-            span: if is_dummy { span } else { assoc_name.span },
-            assoc_name,
+            span: if is_dummy { span } else { assoc_ident.span },
+            assoc_ident,
             assoc_kind: assoc_kind_str,
             qself: &qself_str,
             label: None,
             sugg: None,
             // Try to get the span of the identifier within the path's syntax context
             // (if that's different).
-            within_macro_span: assoc_name.span.within_macro(span, tcx.sess.source_map()),
+            within_macro_span: assoc_ident.span.within_macro(span, tcx.sess.source_map()),
         };
 
         if is_dummy {
@@ -164,15 +168,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let all_candidate_names: Vec<_> = all_candidates()
             .flat_map(|r| tcx.associated_items(r.def_id()).in_definition_order())
             .filter_map(|item| {
-                (!item.is_impl_trait_in_trait() && item.kind == assoc_kind).then_some(item.name)
+                if !item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag {
+                    item.opt_name()
+                } else {
+                    None
+                }
             })
             .collect();
 
         if let Some(suggested_name) =
-            find_best_match_for_name(&all_candidate_names, assoc_name.name, None)
+            find_best_match_for_name(&all_candidate_names, assoc_ident.name, None)
         {
             err.sugg = Some(errors::AssocItemNotFoundSugg::Similar {
-                span: assoc_name.span,
+                span: assoc_ident.span,
                 assoc_kind: assoc_kind_str,
                 suggested_name,
             });
@@ -196,12 +204,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             .iter()
             .flat_map(|trait_def_id| tcx.associated_items(*trait_def_id).in_definition_order())
             .filter_map(|item| {
-                (!item.is_impl_trait_in_trait() && item.kind == assoc_kind).then_some(item.name)
+                (!item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag).then(|| item.name())
             })
             .collect();
 
         if let Some(suggested_name) =
-            find_best_match_for_name(&wider_candidate_names, assoc_name.name, None)
+            find_best_match_for_name(&wider_candidate_names, assoc_ident.name, None)
         {
             if let [best_trait] = visible_traits
                 .iter()
@@ -209,17 +217,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 .filter(|trait_def_id| {
                     tcx.associated_items(trait_def_id)
                         .filter_by_name_unhygienic(suggested_name)
-                        .any(|item| item.kind == assoc_kind)
+                        .any(|item| item.as_tag() == assoc_tag)
                 })
                 .collect::<Vec<_>>()[..]
             {
                 let trait_name = tcx.def_path_str(best_trait);
                 err.label = Some(errors::AssocItemNotFoundLabel::FoundInOtherTrait {
-                    span: assoc_name.span,
+                    span: assoc_ident.span,
                     assoc_kind: assoc_kind_str,
                     trait_name: &trait_name,
                     suggested_name,
-                    identically_named: suggested_name == assoc_name.name,
+                    identically_named: suggested_name == assoc_ident.name,
                 });
                 if let AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span) = qself
                     // Not using `self.item_def_id()` here as that would yield the opaque type itself if we're
@@ -246,7 +254,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         // The type param already has a bound for `trait_name`, we just need to
                         // change the associated item.
                         err.sugg = Some(errors::AssocItemNotFoundSugg::SimilarInOtherTrait {
-                            span: assoc_name.span,
+                            span: assoc_ident.span,
                             assoc_kind: assoc_kind_str,
                             suggested_name,
                         });
@@ -265,7 +273,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         Applicability::MaybeIncorrect
                     };
 
-                    let identically_named = suggested_name == assoc_name.name;
+                    let identically_named = suggested_name == assoc_ident.name;
 
                     if let DefKind::TyAlias = tcx.def_kind(item_def_id)
                         && !tcx.type_alias_is_lazy(item_def_id)
@@ -273,7 +281,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         err.sugg = Some(errors::AssocItemNotFoundSugg::SimilarInOtherTraitQPath {
                             lo: ty_param_span.shrink_to_lo(),
                             mi: ty_param_span.shrink_to_hi(),
-                            hi: (!identically_named).then_some(assoc_name.span),
+                            hi: (!identically_named).then_some(assoc_ident.span),
                             trait_ref,
                             identically_named,
                             suggested_name,
@@ -294,7 +302,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                             // We suggested constraining a type parameter, but the associated item on it
                             // was also not an exact match, so we also suggest changing it.
                             err.span_suggestion_verbose(
-                                assoc_name.span,
+                                assoc_ident.span,
                                 fluent::hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg,
                                 suggested_name,
                                 Applicability::MaybeIncorrect,
@@ -311,13 +319,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // suggest using it.
         if let [candidate_name] = all_candidate_names.as_slice() {
             err.sugg = Some(errors::AssocItemNotFoundSugg::Other {
-                span: assoc_name.span,
+                span: assoc_ident.span,
                 qself: &qself_str,
                 assoc_kind: assoc_kind_str,
                 suggested_name: *candidate_name,
             });
         } else {
-            err.label = Some(errors::AssocItemNotFoundLabel::NotFound { span: assoc_name.span });
+            err.label = Some(errors::AssocItemNotFoundLabel::NotFound { span: assoc_ident.span });
         }
 
         self.dcx().emit_err(err)
@@ -326,14 +334,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     fn complain_about_assoc_kind_mismatch(
         &self,
         assoc_item: &ty::AssocItem,
-        assoc_kind: ty::AssocKind,
+        assoc_tag: ty::AssocTag,
         ident: Ident,
         span: Span,
         constraint: Option<&hir::AssocItemConstraint<'tcx>>,
     ) -> ErrorGuaranteed {
         let tcx = self.tcx();
 
-        let bound_on_assoc_const_label = if let ty::AssocKind::Const = assoc_item.kind
+        let bound_on_assoc_const_label = if let ty::AssocKind::Const { .. } = assoc_item.kind
             && let Some(constraint) = constraint
             && let hir::AssocItemConstraintKind::Bound { .. } = constraint.kind
         {
@@ -371,17 +379,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 hir::Term::Ty(ty) => ty.span,
                 hir::Term::Const(ct) => ct.span(),
             };
-            (span, Some(ident.span), assoc_item.kind, assoc_kind)
+            (span, Some(ident.span), assoc_item.as_tag(), assoc_tag)
         } else {
-            (ident.span, None, assoc_kind, assoc_item.kind)
+            (ident.span, None, assoc_tag, assoc_item.as_tag())
         };
 
         self.dcx().emit_err(errors::AssocKindMismatch {
             span,
-            expected: assoc_kind_str(expected),
-            got: assoc_kind_str(got),
+            expected: assoc_tag_str(expected),
+            got: assoc_tag_str(got),
             expected_because_label,
-            assoc_kind: assoc_kind_str(assoc_item.kind),
+            assoc_kind: assoc_tag_str(assoc_item.as_tag()),
             def_span: tcx.def_span(assoc_item.def_id),
             bound_on_assoc_const_label,
             wrap_in_braces_sugg,
@@ -394,9 +402,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         types: &[String],
         traits: &[String],
         name: Symbol,
-        kind: ty::AssocKind,
+        assoc_tag: ty::AssocTag,
     ) -> ErrorGuaranteed {
-        let kind_str = assoc_kind_str(kind);
+        let kind_str = assoc_tag_str(assoc_tag);
         let mut err =
             struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated {kind_str}");
         if self
@@ -565,7 +573,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         candidates: Vec<(DefId, (DefId, DefId))>,
         fulfillment_errors: Vec<FulfillmentError<'tcx>>,
         span: Span,
-        kind: ty::AssocKind,
+        assoc_tag: ty::AssocTag,
     ) -> ErrorGuaranteed {
         // FIXME(fmease): This was copied in parts from an old version of `rustc_hir_typeck::method::suggest`.
         // Either
@@ -575,14 +583,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         let tcx = self.tcx();
 
-        let kind_str = assoc_kind_str(kind);
+        let assoc_tag_str = assoc_tag_str(assoc_tag);
         let adt_did = self_ty.ty_adt_def().map(|def| def.did());
         let add_def_label = |err: &mut Diag<'_>| {
             if let Some(did) = adt_did {
                 err.span_label(
                     tcx.def_span(did),
                     format!(
-                        "associated {kind_str} `{name}` not found for this {}",
+                        "associated {assoc_tag_str} `{name}` not found for this {}",
                         tcx.def_descr(did)
                     ),
                 );
@@ -611,11 +619,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 self.dcx(),
                 name.span,
                 E0220,
-                "associated {kind_str} `{name}` not found for `{self_ty}` in the current scope"
+                "associated {assoc_tag_str} `{name}` not found for `{self_ty}` in the current scope"
             );
             err.span_label(name.span, format!("associated item not found in `{self_ty}`"));
             err.note(format!(
-                "the associated {kind_str} was found for\n{type_candidates}{additional_types}",
+                "the associated {assoc_tag_str} was found for\n{type_candidates}{additional_types}",
             ));
             add_def_label(&mut err);
             return err.emit();
@@ -696,7 +704,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         let mut err = self.dcx().struct_span_err(
             name.span,
-            format!("the associated {kind_str} `{name}` exists for `{self_ty}`, but its trait bounds were not satisfied")
+            format!("the associated {assoc_tag_str} `{name}` exists for `{self_ty}`, but its trait bounds were not satisfied")
         );
         if !bounds.is_empty() {
             err.note(format!(
@@ -706,7 +714,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         }
         err.span_label(
             name.span,
-            format!("associated {kind_str} cannot be referenced on `{self_ty}` due to unsatisfied trait bounds")
+            format!("associated {assoc_tag_str} cannot be referenced on `{self_ty}` due to unsatisfied trait bounds")
         );
 
         for (span, mut bounds) in bound_spans {
@@ -757,7 +765,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // `issue-22560.rs`.
         let mut dyn_compatibility_violations = Ok(());
         for (assoc_item, trait_ref) in &missing_assoc_types {
-            names.entry(trait_ref).or_default().push(assoc_item.name);
+            names.entry(trait_ref).or_default().push(assoc_item.name());
             names_len += 1;
 
             let violations =
@@ -805,10 +813,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         return None;
                     };
 
-                    let assoc_item = tcx.associated_items(trait_def).find_by_name_and_kind(
+                    let assoc_item = tcx.associated_items(trait_def).find_by_ident_and_kind(
                         tcx,
                         ident,
-                        ty::AssocKind::Type,
+                        ty::AssocTag::Type,
                         trait_def,
                     );
 
@@ -848,16 +856,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let mut names: UnordMap<_, usize> = Default::default();
         for (item, _) in &missing_assoc_types {
             types_count += 1;
-            *names.entry(item.name).or_insert(0) += 1;
+            *names.entry(item.name()).or_insert(0) += 1;
         }
         let mut dupes = false;
         let mut shadows = false;
         for (item, trait_ref) in &missing_assoc_types {
-            let prefix = if names[&item.name] > 1 {
+            let name = item.name();
+            let prefix = if names[&name] > 1 {
                 let trait_def_id = trait_ref.def_id();
                 dupes = true;
                 format!("{}::", tcx.def_path_str(trait_def_id))
-            } else if bound_names.get(&item.name).is_some_and(|x| *x != item) {
+            } else if bound_names.get(&name).is_some_and(|x| *x != item) {
                 let trait_def_id = trait_ref.def_id();
                 shadows = true;
                 format!("{}::", tcx.def_path_str(trait_def_id))
@@ -867,7 +876,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
             let mut is_shadowed = false;
 
-            if let Some(assoc_item) = bound_names.get(&item.name)
+            if let Some(assoc_item) = bound_names.get(&name)
                 && *assoc_item != item
             {
                 is_shadowed = true;
@@ -876,17 +885,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     if assoc_item.def_id.is_local() { ", consider renaming it" } else { "" };
                 err.span_label(
                     tcx.def_span(assoc_item.def_id),
-                    format!("`{}{}` shadowed here{}", prefix, item.name, rename_message),
+                    format!("`{}{}` shadowed here{}", prefix, name, rename_message),
                 );
             }
 
             let rename_message = if is_shadowed { ", consider renaming it" } else { "" };
 
             if let Some(sp) = tcx.hir_span_if_local(item.def_id) {
-                err.span_label(
-                    sp,
-                    format!("`{}{}` defined here{}", prefix, item.name, rename_message),
-                );
+                err.span_label(sp, format!("`{}{}` defined here{}", prefix, name, rename_message));
             }
         }
         if potential_assoc_types.len() == missing_assoc_types.len() {
@@ -899,7 +905,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         {
             let types: Vec<_> = missing_assoc_types
                 .iter()
-                .map(|(item, _)| format!("{} = Type", item.name))
+                .map(|(item, _)| format!("{} = Type", item.name()))
                 .collect();
             let code = if let Some(snippet) = snippet.strip_suffix('>') {
                 // The user wrote `Trait<'a>` or similar and we don't have a type we can
@@ -934,16 +940,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             let mut names: FxIndexMap<_, usize> = FxIndexMap::default();
             for (item, _) in &missing_assoc_types {
                 types_count += 1;
-                *names.entry(item.name).or_insert(0) += 1;
+                *names.entry(item.name()).or_insert(0) += 1;
             }
             let mut label = vec![];
             for (item, trait_ref) in &missing_assoc_types {
-                let postfix = if names[&item.name] > 1 {
+                let name = item.name();
+                let postfix = if names[&name] > 1 {
                     format!(" (from trait `{}`)", trait_ref.print_trait_sugared())
                 } else {
                     String::new()
                 };
-                label.push(format!("`{}`{}", item.name, postfix));
+                label.push(format!("`{}`{}", name, postfix));
             }
             if !label.is_empty() {
                 err.span_label(
@@ -1018,12 +1025,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         .map(|simple_ty| tcx.incoherent_impls(simple_ty))
                 })
             && let name = Symbol::intern(&format!("{ident2}_{ident3}"))
-            && let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = inherent_impls
+            && let Some(item) = inherent_impls
                 .iter()
                 .flat_map(|inherent_impl| {
                     tcx.associated_items(inherent_impl).filter_by_name_unhygienic(name)
                 })
                 .next()
+            && item.is_fn()
         {
             Err(struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated type")
                 .with_span_suggestion_verbose(
@@ -1625,10 +1633,10 @@ fn generics_args_err_extend<'a>(
     }
 }
 
-pub(crate) fn assoc_kind_str(kind: ty::AssocKind) -> &'static str {
-    match kind {
-        ty::AssocKind::Fn => "function",
-        ty::AssocKind::Const => "constant",
-        ty::AssocKind::Type => "type",
+pub(crate) fn assoc_tag_str(assoc_tag: ty::AssocTag) -> &'static str {
+    match assoc_tag {
+        ty::AssocTag::Fn => "function",
+        ty::AssocTag::Const => "constant",
+        ty::AssocTag::Type => "type",
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
index 8e62dce2191..483b61add33 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
@@ -501,8 +501,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let names: Vec<_> = tcx
             .associated_items(trait_def_id)
             .in_definition_order()
-            .filter(|assoc| assoc.kind.namespace() == Namespace::ValueNS)
-            .map(|cand| cand.name)
+            .filter(|assoc| assoc.namespace() == Namespace::ValueNS)
+            .map(|cand| cand.name())
             .collect();
         if let Some(typo) = find_best_match_for_name(&names, segment.ident.name, None) {
             diag.span_suggestion_verbose(
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index b4a71edc118..fcb7382549f 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -29,7 +29,7 @@ use rustc_errors::codes::*;
 use rustc_errors::{
     Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, struct_span_code_err,
 };
-use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
+use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId};
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
@@ -38,8 +38,8 @@ use rustc_middle::middle::stability::AllowUnstable;
 use rustc_middle::mir::interpret::LitToConstInput;
 use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
 use rustc_middle::ty::{
-    self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
-    TypeVisitableExt, TypingMode, Upcast, fold_regions,
+    self, AssocTag, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty,
+    TyCtxt, TypeVisitableExt, TypingMode, Upcast, fold_regions,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
@@ -51,7 +51,7 @@ use rustc_trait_selection::traits::wf::object_region_bounds;
 use rustc_trait_selection::traits::{self, ObligationCtxt};
 use tracing::{debug, instrument};
 
-use self::errors::assoc_kind_str;
+use self::errors::assoc_tag_str;
 use crate::check::check_abi_fn_ptr;
 use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, NoVariantNamed};
 use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
@@ -147,7 +147,7 @@ pub trait HirTyLowerer<'tcx> {
         &self,
         span: Span,
         def_id: LocalDefId,
-        assoc_name: Ident,
+        assoc_ident: Ident,
     ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]>;
 
     /// Lower an associated type/const (from a trait) to a projection.
@@ -168,7 +168,7 @@ pub trait HirTyLowerer<'tcx> {
         item_def_id: DefId,
         item_segment: &hir::PathSegment<'tcx>,
         poly_trait_ref: ty::PolyTraitRef<'tcx>,
-        kind: ty::AssocKind,
+        assoc_tag: ty::AssocTag,
     ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed>;
 
     fn lower_fn_sig(
@@ -251,10 +251,10 @@ enum LowerAssocMode {
 }
 
 impl LowerAssocMode {
-    fn kind(self) -> ty::AssocKind {
+    fn assoc_tag(self) -> ty::AssocTag {
         match self {
-            LowerAssocMode::Type { .. } => ty::AssocKind::Type,
-            LowerAssocMode::Const => ty::AssocKind::Const,
+            LowerAssocMode::Type { .. } => ty::AssocTag::Type,
+            LowerAssocMode::Const => ty::AssocTag::Const,
         }
     }
 
@@ -268,7 +268,8 @@ impl LowerAssocMode {
     fn permit_variants(self) -> bool {
         match self {
             LowerAssocMode::Type { permit_variants } => permit_variants,
-            // FIXME(mgca): Support paths like `Option::<T>::None` or `Option::<T>::Some` which resolve to const ctors/fn items respectively
+            // FIXME(mgca): Support paths like `Option::<T>::None` or `Option::<T>::Some` which
+            // resolve to const ctors/fn items respectively.
             LowerAssocMode::Const => false,
         }
     }
@@ -932,12 +933,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     fn probe_trait_that_defines_assoc_item(
         &self,
         trait_def_id: DefId,
-        assoc_kind: ty::AssocKind,
-        assoc_name: Ident,
+        assoc_tag: AssocTag,
+        assoc_ident: Ident,
     ) -> bool {
         self.tcx()
             .associated_items(trait_def_id)
-            .find_by_name_and_kind(self.tcx(), assoc_name, assoc_kind, trait_def_id)
+            .find_by_ident_and_kind(self.tcx(), assoc_ident, assoc_tag, trait_def_id)
             .is_some()
     }
 
@@ -957,14 +958,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             // feature `lazy_type_alias` enabled get encoded as a type alias that normalization will
             // then actually instantiate the where bounds of.
             let alias_ty = ty::AliasTy::new_from_args(tcx, did, args);
-            Ty::new_alias(tcx, ty::Weak, alias_ty)
+            Ty::new_alias(tcx, ty::Free, alias_ty)
         } else {
             tcx.at(span).type_of(did).instantiate(tcx, args)
         }
     }
 
     /// Search for a trait bound on a type parameter whose trait defines the associated item
-    /// given by `assoc_name` and `kind`.
+    /// given by `assoc_ident` and `kind`.
     ///
     /// This fails if there is no such bound in the list of candidates or if there are multiple
     /// candidates in which case it reports ambiguity.
@@ -975,14 +976,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         &self,
         ty_param_def_id: LocalDefId,
         ty_param_span: Span,
-        kind: ty::AssocKind,
-        assoc_name: Ident,
+        assoc_tag: AssocTag,
+        assoc_ident: Ident,
         span: Span,
     ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
-        debug!(?ty_param_def_id, ?assoc_name, ?span);
+        debug!(?ty_param_def_id, ?assoc_ident, ?span);
         let tcx = self.tcx();
 
-        let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_name);
+        let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_ident);
         debug!("predicates={:#?}", predicates);
 
         self.probe_single_bound_for_assoc_item(
@@ -990,17 +991,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 let trait_refs = predicates
                     .iter_identity_copied()
                     .filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref)));
-                traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_name)
+                traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_ident)
             },
             AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span),
-            kind,
-            assoc_name,
+            assoc_tag,
+            assoc_ident,
             span,
             None,
         )
     }
 
-    /// Search for a single trait bound whose trait defines the associated item given by `assoc_name`.
+    /// Search for a single trait bound whose trait defines the associated item given by
+    /// `assoc_ident`.
     ///
     /// This fails if there is no such bound in the list of candidates or if there are multiple
     /// candidates in which case it reports ambiguity.
@@ -1009,8 +1011,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         &self,
         all_candidates: impl Fn() -> I,
         qself: AssocItemQSelf,
-        assoc_kind: ty::AssocKind,
-        assoc_name: Ident,
+        assoc_tag: AssocTag,
+        assoc_ident: Ident,
         span: Span,
         constraint: Option<&hir::AssocItemConstraint<'tcx>>,
     ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>
@@ -1020,15 +1022,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let tcx = self.tcx();
 
         let mut matching_candidates = all_candidates().filter(|r| {
-            self.probe_trait_that_defines_assoc_item(r.def_id(), assoc_kind, assoc_name)
+            self.probe_trait_that_defines_assoc_item(r.def_id(), assoc_tag, assoc_ident)
         });
 
         let Some(bound) = matching_candidates.next() else {
             let reported = self.complain_about_assoc_item_not_found(
                 all_candidates,
                 qself,
-                assoc_kind,
-                assoc_name,
+                assoc_tag,
+                assoc_ident,
                 span,
                 constraint,
             );
@@ -1039,12 +1041,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         if let Some(bound2) = matching_candidates.next() {
             debug!(?bound2);
 
-            let assoc_kind_str = errors::assoc_kind_str(assoc_kind);
+            let assoc_kind_str = errors::assoc_tag_str(assoc_tag);
             let qself_str = qself.to_string(tcx);
             let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem {
                 span,
                 assoc_kind: assoc_kind_str,
-                assoc_name,
+                assoc_ident,
                 qself: &qself_str,
             });
             // Provide a more specific error code index entry for equality bindings.
@@ -1058,20 +1060,21 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 },
             );
 
-            // FIXME(#97583): Print associated item bindings properly (i.e., not as equality predicates!).
+            // FIXME(#97583): Print associated item bindings properly (i.e., not as equality
+            // predicates!).
             // FIXME: Turn this into a structured, translateable & more actionable suggestion.
             let mut where_bounds = vec![];
             for bound in [bound, bound2].into_iter().chain(matching_candidates) {
                 let bound_id = bound.def_id();
                 let bound_span = tcx
                     .associated_items(bound_id)
-                    .find_by_name_and_kind(tcx, assoc_name, assoc_kind, bound_id)
+                    .find_by_ident_and_kind(tcx, assoc_ident, assoc_tag, bound_id)
                     .and_then(|item| tcx.hir_span_if_local(item.def_id));
 
                 if let Some(bound_span) = bound_span {
                     err.span_label(
                         bound_span,
-                        format!("ambiguous `{assoc_name}` from `{}`", bound.print_trait_sugared(),),
+                        format!("ambiguous `{assoc_ident}` from `{}`", bound.print_trait_sugared(),),
                     );
                     if let Some(constraint) = constraint {
                         match constraint.kind {
@@ -1087,7 +1090,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                                 }
                                 // FIXME(#97583): This isn't syntactically well-formed!
                                 where_bounds.push(format!(
-                                    "        T: {trait}::{assoc_name} = {term}",
+                                    "        T: {trait}::{assoc_ident} = {term}",
                                     trait = bound.print_only_trait_path(),
                                 ));
                             }
@@ -1096,7 +1099,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         }
                     } else {
                         err.span_suggestion_verbose(
-                            span.with_hi(assoc_name.span.lo()),
+                            span.with_hi(assoc_ident.span.lo()),
                             "use fully-qualified syntax to disambiguate",
                             format!("<{qself_str} as {}>::", bound.print_only_trait_path()),
                             Applicability::MaybeIncorrect,
@@ -1104,7 +1107,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     }
                 } else {
                     err.note(format!(
-                        "associated {assoc_kind_str} `{assoc_name}` could derive from `{}`",
+                        "associated {assoc_kind_str} `{assoc_ident}` could derive from `{}`",
                         bound.print_only_trait_path(),
                     ));
                 }
@@ -1264,7 +1267,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 qself_ty,
                 hir_ref_id,
                 span,
-                mode.kind(),
+                mode.assoc_tag(),
             )? {
                 return Ok(LoweredAssoc::Term(did, args));
             }
@@ -1295,7 +1298,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         )
                     },
                     AssocItemQSelf::SelfTyAlias,
-                    mode.kind(),
+                    mode.assoc_tag(),
                     assoc_ident,
                     span,
                     None,
@@ -1307,12 +1310,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             ) => self.probe_single_ty_param_bound_for_assoc_item(
                 param_did.expect_local(),
                 qself.span,
-                mode.kind(),
+                mode.assoc_tag(),
                 assoc_ident,
                 span,
             )?,
             _ => {
-                let kind_str = assoc_kind_str(mode.kind());
+                let kind_str = assoc_tag_str(mode.assoc_tag());
                 let reported = if variant_resolution.is_some() {
                     // Variant in type position
                     let msg = format!("expected {kind_str}, found variant `{assoc_ident}`");
@@ -1419,7 +1422,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         &[qself_ty.to_string()],
                         &traits,
                         assoc_ident.name,
-                        mode.kind(),
+                        mode.assoc_tag(),
                     )
                 };
                 return Err(reported);
@@ -1428,10 +1431,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         let trait_did = bound.def_id();
         let assoc_item = self
-            .probe_assoc_item(assoc_ident, mode.kind(), hir_ref_id, span, trait_did)
+            .probe_assoc_item(assoc_ident, mode.assoc_tag(), hir_ref_id, span, trait_did)
             .expect("failed to find associated item");
-        let (def_id, args) =
-            self.lower_assoc_shared(span, assoc_item.def_id, assoc_segment, bound, mode.kind())?;
+        let (def_id, args) = self.lower_assoc_shared(
+            span,
+            assoc_item.def_id,
+            assoc_segment,
+            bound,
+            mode.assoc_tag(),
+        )?;
         let result = LoweredAssoc::Term(def_id, args);
 
         if let Some(variant_def_id) = variant_resolution {
@@ -1468,20 +1476,21 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         self_ty: Ty<'tcx>,
         block: HirId,
         span: Span,
-        kind: ty::AssocKind,
+        assoc_tag: ty::AssocTag,
     ) -> Result<Option<(DefId, GenericArgsRef<'tcx>)>, ErrorGuaranteed> {
         let tcx = self.tcx();
 
         if !tcx.features().inherent_associated_types() {
-            match kind {
-                // Don't attempt to look up inherent associated types when the feature is not enabled.
-                // Theoretically it'd be fine to do so since we feature-gate their definition site.
-                // However, due to current limitations of the implementation (caused by us performing
-                // selection during HIR ty lowering instead of in the trait solver), IATs can lead to cycle
-                // errors (#108491) which mask the feature-gate error, needlessly confusing users
-                // who use IATs by accident (#113265).
-                ty::AssocKind::Type => return Ok(None),
-                ty::AssocKind::Const => {
+            match assoc_tag {
+                // Don't attempt to look up inherent associated types when the feature is not
+                // enabled. Theoretically it'd be fine to do so since we feature-gate their
+                // definition site. However, due to current limitations of the implementation
+                // (caused by us performing selection during HIR ty lowering instead of in the
+                // trait solver), IATs can lead to cycle errors (#108491) which mask the
+                // feature-gate error, needlessly confusing users who use IATs by accident
+                // (#113265).
+                ty::AssocTag::Type => return Ok(None),
+                ty::AssocTag::Const => {
                     // We also gate the mgca codepath for type-level uses of inherent consts
                     // with the inherent_associated_types feature gate since it relies on the
                     // same machinery and has similar rough edges.
@@ -1493,7 +1502,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     )
                     .emit());
                 }
-                ty::AssocKind::Fn => unreachable!(),
+                ty::AssocTag::Fn => unreachable!(),
             }
         }
 
@@ -1502,7 +1511,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             .inherent_impls(adt_did)
             .iter()
             .filter_map(|&impl_| {
-                let (item, scope) = self.probe_assoc_item_unchecked(name, kind, block, impl_)?;
+                let (item, scope) =
+                    self.probe_assoc_item_unchecked(name, assoc_tag, block, impl_)?;
                 Some((impl_, (item.def_id, scope)))
             })
             .collect();
@@ -1541,7 +1551,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             self_ty,
             |self_ty| {
                 self.select_inherent_assoc_candidates(
-                    infcx, name, span, self_ty, param_env, candidates, kind,
+                    infcx, name, span, self_ty, param_env, candidates, assoc_tag,
                 )
             },
         )?;
@@ -1569,7 +1579,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         self_ty: Ty<'tcx>,
         param_env: ParamEnv<'tcx>,
         candidates: Vec<(DefId, (DefId, DefId))>,
-        kind: ty::AssocKind,
+        assoc_tag: ty::AssocTag,
     ) -> Result<(DefId, (DefId, DefId)), ErrorGuaranteed> {
         let tcx = self.tcx();
         let mut fulfillment_errors = Vec::new();
@@ -1620,7 +1630,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 candidates,
                 fulfillment_errors,
                 span,
-                kind,
+                assoc_tag,
             )),
 
             &[applicable_candidate] => Ok(applicable_candidate),
@@ -1639,12 +1649,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     fn probe_assoc_item(
         &self,
         ident: Ident,
-        kind: ty::AssocKind,
+        assoc_tag: ty::AssocTag,
         block: HirId,
         span: Span,
         scope: DefId,
     ) -> Option<ty::AssocItem> {
-        let (item, scope) = self.probe_assoc_item_unchecked(ident, kind, block, scope)?;
+        let (item, scope) = self.probe_assoc_item_unchecked(ident, assoc_tag, block, scope)?;
         self.check_assoc_item(item.def_id, ident, scope, block, span);
         Some(item)
     }
@@ -1656,7 +1666,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     fn probe_assoc_item_unchecked(
         &self,
         ident: Ident,
-        kind: ty::AssocKind,
+        assoc_tag: ty::AssocTag,
         block: HirId,
         scope: DefId,
     ) -> Option<(ty::AssocItem, /*scope*/ DefId)> {
@@ -1669,7 +1679,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let item = tcx
             .associated_items(scope)
             .filter_by_name_unhygienic(ident.name)
-            .find(|i| i.kind == kind && i.ident(tcx).normalize_to_macros_2_0() == ident)?;
+            .find(|i| i.as_tag() == assoc_tag && i.ident(tcx).normalize_to_macros_2_0() == ident)?;
 
         Some((*item, def_scope))
     }
@@ -1721,9 +1731,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 tcx.associated_items(*trait_def_id)
                         .in_definition_order()
                         .any(|i| {
-                            i.kind.namespace() == Namespace::TypeNS
+                            i.is_type()
+                                && !i.is_impl_trait_in_trait()
                                 && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
-                                && matches!(i.kind, ty::AssocKind::Type)
                         })
                     // Consider only accessible traits
                     && tcx.visibility(*trait_def_id)
@@ -1769,7 +1779,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             item_def_id,
             trait_segment,
             item_segment,
-            ty::AssocKind::Type,
+            ty::AssocTag::Type,
         ) {
             Ok((item_def_id, item_args)) => {
                 Ty::new_projection_from_args(self.tcx(), item_def_id, item_args)
@@ -1794,7 +1804,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             item_def_id,
             trait_segment,
             item_segment,
-            ty::AssocKind::Const,
+            ty::AssocTag::Const,
         ) {
             Ok((item_def_id, item_args)) => {
                 let uv = ty::UnevaluatedConst::new(item_def_id, item_args);
@@ -1812,7 +1822,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         item_def_id: DefId,
         trait_segment: &hir::PathSegment<'tcx>,
         item_segment: &hir::PathSegment<'tcx>,
-        kind: ty::AssocKind,
+        assoc_tag: ty::AssocTag,
     ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed> {
         let tcx = self.tcx();
 
@@ -1820,7 +1830,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         debug!(?trait_def_id);
 
         let Some(self_ty) = opt_self_ty else {
-            return Err(self.error_missing_qpath_self_ty(trait_def_id, span, item_segment, kind));
+            return Err(self.error_missing_qpath_self_ty(
+                trait_def_id,
+                span,
+                item_segment,
+                assoc_tag,
+            ));
         };
         debug!(?self_ty);
 
@@ -1839,7 +1854,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         trait_def_id: DefId,
         span: Span,
         item_segment: &hir::PathSegment<'tcx>,
-        kind: ty::AssocKind,
+        assoc_tag: ty::AssocTag,
     ) -> ErrorGuaranteed {
         let tcx = self.tcx();
         let path_str = tcx.def_path_str(trait_def_id);
@@ -1876,7 +1891,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // FIXME: also look at `tcx.generics_of(self.item_def_id()).params` any that
         // references the trait. Relevant for the first case in
         // `src/test/ui/associated-types/associated-types-in-ambiguous-context.rs`
-        self.report_ambiguous_assoc(span, &type_names, &[path_str], item_segment.ident.name, kind)
+        self.report_ambiguous_assoc(
+            span,
+            &type_names,
+            &[path_str],
+            item_segment.ident.name,
+            assoc_tag,
+        )
     }
 
     pub fn prohibit_generic_args<'a>(
@@ -2694,30 +2715,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             hir::TyKind::Pat(ty, pat) => {
                 let ty_span = ty.span;
                 let ty = self.lower_ty(ty);
-                let pat_ty = match pat.kind {
-                    hir::TyPatKind::Range(start, end) => {
-                        let (ty, start, end) = match ty.kind() {
-                            // Keep this list of types in sync with the list of types that
-                            // the `RangePattern` trait is implemented for.
-                            ty::Int(_) | ty::Uint(_) | ty::Char => {
-                                let start = self.lower_const_arg(start, FeedConstTy::No);
-                                let end = self.lower_const_arg(end, FeedConstTy::No);
-                                (ty, start, end)
-                            }
-                            _ => {
-                                let guar = self.dcx().span_delayed_bug(
-                                    ty_span,
-                                    "invalid base type for range pattern",
-                                );
-                                let errc = ty::Const::new_error(tcx, guar);
-                                (Ty::new_error(tcx, guar), errc, errc)
-                            }
-                        };
-
-                        let pat = tcx.mk_pat(ty::PatternKind::Range { start, end });
-                        Ty::new_pat(tcx, ty, pat)
-                    }
-                    hir::TyPatKind::Err(e) => Ty::new_error(tcx, e),
+                let pat_ty = match self.lower_pat_ty_pat(ty, ty_span, pat) {
+                    Ok(kind) => Ty::new_pat(tcx, ty, tcx.mk_pat(kind)),
+                    Err(guar) => Ty::new_error(tcx, guar),
                 };
                 self.record_ty(pat.hir_id, ty, pat.span);
                 pat_ty
@@ -2729,6 +2729,39 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         result_ty
     }
 
+    fn lower_pat_ty_pat(
+        &self,
+        ty: Ty<'tcx>,
+        ty_span: Span,
+        pat: &hir::TyPat<'tcx>,
+    ) -> Result<ty::PatternKind<'tcx>, ErrorGuaranteed> {
+        let tcx = self.tcx();
+        match pat.kind {
+            hir::TyPatKind::Range(start, end) => {
+                match ty.kind() {
+                    // Keep this list of types in sync with the list of types that
+                    // the `RangePattern` trait is implemented for.
+                    ty::Int(_) | ty::Uint(_) | ty::Char => {
+                        let start = self.lower_const_arg(start, FeedConstTy::No);
+                        let end = self.lower_const_arg(end, FeedConstTy::No);
+                        Ok(ty::PatternKind::Range { start, end })
+                    }
+                    _ => Err(self
+                        .dcx()
+                        .span_delayed_bug(ty_span, "invalid base type for range pattern")),
+                }
+            }
+            hir::TyPatKind::Or(patterns) => {
+                self.tcx()
+                    .mk_patterns_from_iter(patterns.iter().map(|pat| {
+                        self.lower_pat_ty_pat(ty, ty_span, pat).map(|pat| tcx.mk_pat(pat))
+                    }))
+                    .map(ty::PatternKind::Or)
+            }
+            hir::TyPatKind::Err(e) => Err(e),
+        }
+    }
+
     /// Lower an opaque type (i.e., an existential impl-Trait type) from the HIR.
     #[instrument(level = "debug", skip(self), ret)]
     fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: bool) -> Ty<'tcx> {
@@ -2858,10 +2891,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         let trait_ref = self.lower_impl_trait_ref(i.of_trait.as_ref()?, self.lower_ty(i.self_ty));
 
-        let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind(
+        let assoc = tcx.associated_items(trait_ref.def_id).find_by_ident_and_kind(
             tcx,
             *ident,
-            ty::AssocKind::Fn,
+            ty::AssocTag::Fn,
             trait_ref.def_id,
         )?;
 
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index c30b39dfe76..cbdc501291b 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -112,14 +112,14 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained(
         .flat_map(|def_id| {
             let item = tcx.associated_item(def_id);
             match item.kind {
-                ty::AssocKind::Type => {
+                ty::AssocKind::Type { .. } => {
                     if item.defaultness(tcx).has_value() {
                         cgp::parameters_for(tcx, tcx.type_of(def_id).instantiate_identity(), true)
                     } else {
                         vec![]
                     }
                 }
-                ty::AssocKind::Fn | ty::AssocKind::Const => vec![],
+                ty::AssocKind::Fn { .. } | ty::AssocKind::Const { .. } => vec![],
             }
         })
         .collect();
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index af1107b499f..309221f9a12 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -374,9 +374,12 @@ fn check_predicates<'tcx>(
 
     // Include the well-formed predicates of the type parameters of the impl.
     for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().instantiate_identity().args {
+        let Some(term) = arg.as_term() else {
+            continue;
+        };
         let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis());
         let obligations =
-            wf::obligations(infcx, tcx.param_env(impl1_def_id), impl1_def_id, 0, arg, span)
+            wf::obligations(infcx, tcx.param_env(impl1_def_id), impl1_def_id, 0, term, span)
                 .unwrap();
 
         assert!(!obligations.has_infer());
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index e7ecd727a85..309b8f2c761 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -59,7 +59,7 @@ This API is completely unstable and subject to change.
 #![allow(internal_features)]
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::untranslatable_diagnostic)]
-#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141
+#![cfg_attr(bootstrap, feature(let_chains))]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(assert_matches)]
@@ -68,7 +68,6 @@ This API is completely unstable and subject to change.
 #![feature(if_let_guard)]
 #![feature(iter_from_coroutine)]
 #![feature(iter_intersperse)]
-#![feature(let_chains)]
 #![feature(never_type)]
 #![feature(rustdoc_internals)]
 #![feature(slice_partition_dedup)]
diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
index 780c27d4595..c99eb12efcc 100644
--- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
@@ -157,10 +157,10 @@ fn insert_required_predicates_to_be_wf<'tcx>(
                 );
             }
 
-            ty::Alias(ty::Weak, alias) => {
+            ty::Alias(ty::Free, alias) => {
                 // This corresponds to a type like `Type<'a, T>`.
                 // We check inferred and explicit predicates.
-                debug!("Weak");
+                debug!("Free");
                 check_inferred_predicates(
                     tcx,
                     alias.def_id,
diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs
index 23223de918c..92cfece77c4 100644
--- a/compiler/rustc_hir_analysis/src/variance/constraints.rs
+++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs
@@ -107,7 +107,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
         let current_item = &CurrentItem { inferred_start };
         let ty = tcx.type_of(def_id).instantiate_identity();
 
-        // The type as returned by `type_of` is the underlying type and generally not a weak projection.
+        // The type as returned by `type_of` is the underlying type and generally not a free alias.
         // Therefore we need to check the `DefKind` first.
         if let DefKind::TyAlias = tcx.def_kind(def_id)
             && tcx.type_alias_is_lazy(def_id)
@@ -251,12 +251,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
             }
 
             ty::Pat(typ, pat) => {
-                match *pat {
-                    ty::PatternKind::Range { start, end } => {
-                        self.add_constraints_from_const(current, start, variance);
-                        self.add_constraints_from_const(current, end, variance);
-                    }
-                }
+                self.add_constraints_from_pat(current, variance, pat);
                 self.add_constraints_from_ty(current, typ, variance);
             }
 
@@ -282,7 +277,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                 self.add_constraints_from_invariant_args(current, data.args, variance);
             }
 
-            ty::Alias(ty::Weak, ref data) => {
+            ty::Alias(ty::Free, ref data) => {
                 self.add_constraints_from_args(current, data.def_id, data.args, variance);
             }
 
@@ -334,6 +329,25 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
         }
     }
 
+    fn add_constraints_from_pat(
+        &mut self,
+        current: &CurrentItem,
+        variance: VarianceTermPtr<'a>,
+        pat: ty::Pattern<'tcx>,
+    ) {
+        match *pat {
+            ty::PatternKind::Range { start, end } => {
+                self.add_constraints_from_const(current, start, variance);
+                self.add_constraints_from_const(current, end, variance);
+            }
+            ty::PatternKind::Or(patterns) => {
+                for pat in patterns {
+                    self.add_constraints_from_pat(current, variance, pat)
+                }
+            }
+        }
+    }
+
     /// Adds constraints appropriate for a nominal type (enum, struct,
     /// object, etc) appearing in a context with ambient variance `variance`
     fn add_constraints_from_args(