about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs33
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/check/dropck.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs19
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs48
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs24
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/collect/dump.rs82
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs94
-rw-r--r--compiler/rustc_hir_analysis/src/delegation.rs360
-rw-r--r--compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs23
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/variance/solve.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/variance/xform.rs22
22 files changed, 370 insertions, 444 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index b0a6922ff72..40049f96de4 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -27,7 +27,6 @@ use rustc_session::lint::builtin::UNINHABITED_STATIC;
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
 use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedDirective;
 use rustc_trait_selection::traits;
-use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
 use rustc_type_ir::fold::TypeFoldable;
 use tracing::{debug, instrument};
 use ty::TypingMode;
@@ -417,9 +416,7 @@ fn check_opaque_meets_bounds<'tcx>(
     }
 
     let wf_tys = ocx.assumed_wf_types_and_report_errors(param_env, defining_use_anchor)?;
-    let implied_bounds = infcx.implied_bounds_tys(param_env, def_id, &wf_tys);
-    let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
-    ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?;
+    ocx.resolve_regions_and_report_errors(defining_use_anchor, param_env, wf_tys)?;
 
     if infcx.next_trait_solver() {
         Ok(())
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 d2ab98bae89..3bff5fe02c0 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -9,7 +9,6 @@ use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_e
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::VisitorExt;
 use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, intravisit};
-use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::util;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
@@ -24,7 +23,6 @@ use rustc_span::Span;
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
 use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::regions::InferCtxtRegionExt;
-use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
 use rustc_trait_selection::traits::{
     self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt,
 };
@@ -416,11 +414,7 @@ fn compare_method_predicate_entailment<'tcx>(
 
     // Finally, resolve all regions. This catches wily misuses of
     // lifetime parameters.
-    let outlives_env = OutlivesEnvironment::with_bounds(
-        param_env,
-        infcx.implied_bounds_tys(param_env, impl_m_def_id, &wf_tys),
-    );
-    let errors = infcx.resolve_regions(&outlives_env);
+    let errors = infcx.resolve_regions(impl_m_def_id, param_env, wf_tys);
     if !errors.is_empty() {
         return Err(infcx
             .tainted_by_errors()
@@ -430,12 +424,12 @@ fn compare_method_predicate_entailment<'tcx>(
     Ok(())
 }
 
-struct RemapLateParam<'a, 'tcx> {
+struct RemapLateParam<'tcx> {
     tcx: TyCtxt<'tcx>,
-    mapping: &'a FxIndexMap<ty::LateParamRegionKind, ty::LateParamRegionKind>,
+    mapping: FxIndexMap<ty::LateParamRegionKind, ty::LateParamRegionKind>,
 }
 
-impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateParam<'_, 'tcx> {
+impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateParam<'tcx> {
     fn cx(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
@@ -659,6 +653,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
                 }))),
                 terr,
                 false,
+                None,
             );
             return Err(diag.emit());
         }
@@ -725,11 +720,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
 
     // Finally, resolve all regions. This catches wily misuses of
     // lifetime parameters.
-    let outlives_env = OutlivesEnvironment::with_bounds(
-        param_env,
-        infcx.implied_bounds_tys(param_env, impl_m_def_id, &wf_tys),
-    );
-    ocx.resolve_regions_and_report_errors(impl_m_def_id, &outlives_env)?;
+    ocx.resolve_regions_and_report_errors(impl_m_def_id, param_env, wf_tys)?;
 
     let mut remapped_types = DefIdMap::default();
     for (def_id, (ty, args)) in collected_types {
@@ -1080,6 +1071,7 @@ fn report_trait_method_mismatch<'tcx>(
         }))),
         terr,
         false,
+        None,
     );
 
     diag.emit()
@@ -1872,6 +1864,7 @@ fn compare_const_predicate_entailment<'tcx>(
             }))),
             terr,
             false,
+            None,
         );
         return Err(diag.emit());
     };
@@ -1883,8 +1876,7 @@ fn compare_const_predicate_entailment<'tcx>(
         return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
     }
 
-    let outlives_env = OutlivesEnvironment::new(param_env);
-    ocx.resolve_regions_and_report_errors(impl_ct_def_id, &outlives_env)
+    ocx.resolve_regions_and_report_errors(impl_ct_def_id, param_env, [])
 }
 
 #[instrument(level = "debug", skip(tcx))]
@@ -2017,8 +2009,7 @@ fn compare_type_predicate_entailment<'tcx>(
 
     // Finally, resolve all regions. This catches wily misuses of
     // lifetime parameters.
-    let outlives_env = OutlivesEnvironment::new(param_env);
-    ocx.resolve_regions_and_report_errors(impl_ty_def_id, &outlives_env)
+    ocx.resolve_regions_and_report_errors(impl_ty_def_id, param_env, [])
 }
 
 /// Validate that `ProjectionCandidate`s created for this associated type will
@@ -2147,9 +2138,7 @@ pub(super) fn check_type_bounds<'tcx>(
 
     // Finally, resolve all regions. This catches wily misuses of
     // lifetime parameters.
-    let implied_bounds = infcx.implied_bounds_tys(param_env, impl_ty_def_id, &assumed_wf_types);
-    let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
-    ocx.resolve_regions_and_report_errors(impl_ty_def_id, &outlives_env)
+    ocx.resolve_regions_and_report_errors(impl_ty_def_id, param_env, assumed_wf_types)
 }
 
 struct ReplaceTy<'tcx> {
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
index 2b14594ea1b..0e9e9b48ab3 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
@@ -3,7 +3,6 @@ use rustc_data_structures::fx::FxIndexSet;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_infer::infer::TyCtxtInferExt;
-use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE};
 use rustc_middle::span_bug;
 use rustc_middle::traits::ObligationCause;
@@ -13,7 +12,6 @@ use rustc_middle::ty::{
 };
 use rustc_span::Span;
 use rustc_trait_selection::regions::InferCtxtRegionExt;
-use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt;
 use rustc_trait_selection::traits::{ObligationCtxt, elaborate, normalize_param_env_or_error};
 
 /// Check that an implementation does not refine an RPITIT from a trait method signature.
@@ -170,11 +168,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
         tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (selection)");
         return;
     }
-    let outlives_env = OutlivesEnvironment::with_bounds(
-        param_env,
-        infcx.implied_bounds_tys(param_env, impl_m.def_id.expect_local(), &implied_wf_types),
-    );
-    let errors = infcx.resolve_regions(&outlives_env);
+    let errors = infcx.resolve_regions(impl_m.def_id.expect_local(), param_env, implied_wf_types);
     if !errors.is_empty() {
         tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (regions)");
         return;
@@ -305,8 +299,7 @@ fn report_mismatched_rpitit_signature<'tcx>(
     })
     .collect();
 
-    let mut return_ty =
-        trait_m_sig.output().fold_with(&mut super::RemapLateParam { tcx, mapping: &mapping });
+    let mut return_ty = trait_m_sig.output().fold_with(&mut super::RemapLateParam { tcx, mapping });
 
     if tcx.asyncness(impl_m_def_id).is_async() && tcx.asyncness(trait_m_def_id).is_async() {
         let ty::Alias(ty::Projection, future_ty) = return_ty.kind() else {
diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs
index 1c9bbe627fb..d7dfe482da4 100644
--- a/compiler/rustc_hir_analysis/src/check/dropck.rs
+++ b/compiler/rustc_hir_analysis/src/check/dropck.rs
@@ -1,11 +1,6 @@
-// FIXME(@lcnr): Move this module out of `rustc_hir_analysis`.
-//
-// We don't do any drop checking during hir typeck.
-
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::codes::*;
 use rustc_errors::{ErrorGuaranteed, struct_span_code_err};
-use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
 use rustc_infer::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::util::CheckRegions;
@@ -33,7 +28,10 @@ use crate::hir::def_id::{DefId, LocalDefId};
 ///    struct/enum definition for the nominal type itself (i.e.
 ///    cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`).
 ///
-pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), ErrorGuaranteed> {
+pub(crate) fn check_drop_impl(
+    tcx: TyCtxt<'_>,
+    drop_impl_did: DefId,
+) -> Result<(), ErrorGuaranteed> {
     match tcx.impl_polarity(drop_impl_did) {
         ty::ImplPolarity::Positive => {}
         ty::ImplPolarity::Negative => {
@@ -192,7 +190,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
         return Err(guar.unwrap());
     }
 
-    let errors = ocx.infcx.resolve_regions(&OutlivesEnvironment::new(adt_env));
+    let errors = ocx.infcx.resolve_regions(adt_def_id, adt_env, []);
     if !errors.is_empty() {
         let mut guar = None;
         for error in errors {
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 8aa95d1c1d5..cf3d4897304 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -199,7 +199,8 @@ pub fn check_intrinsic_type(
         let split: Vec<&str> = name_str.split('_').collect();
         assert!(split.len() >= 2, "Atomic intrinsic in an incorrect format");
 
-        //We only care about the operation here
+        // Each atomic op has variants with different suffixes (`_seq_cst`, `_acquire`, etc.). Use
+        // string ops to strip the suffixes, because the variants all get the same treatment here.
         let (n_tps, inputs, output) = match split[1] {
             "cxchg" | "cxchgweak" => (
                 1,
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index cc0b7fdd8dd..96b33bdd250 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -80,7 +80,6 @@ use rustc_errors::{Diag, ErrorGuaranteed, pluralize, struct_span_code_err};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::Visitor;
 use rustc_index::bit_set::DenseBitSet;
-use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{self, TyCtxtInferExt as _};
 use rustc_infer::traits::ObligationCause;
 use rustc_middle::query::Providers;
@@ -456,18 +455,14 @@ fn fn_sig_suggestion<'tcx>(
     let mut output = sig.output();
 
     let asyncness = if tcx.asyncness(assoc.def_id).is_async() {
-        output = if let ty::Alias(_, alias_ty) = *output.kind() {
-            tcx.explicit_item_self_bounds(alias_ty.def_id)
+        output = if let ty::Alias(_, alias_ty) = *output.kind()
+            && let Some(output) = tcx
+                .explicit_item_self_bounds(alias_ty.def_id)
                 .iter_instantiated_copied(tcx, alias_ty.args)
                 .find_map(|(bound, _)| {
                     bound.as_projection_clause()?.no_bound_vars()?.term.as_type()
-                })
-                .unwrap_or_else(|| {
-                    span_bug!(
-                        ident.span,
-                        "expected async fn to have `impl Future` output, but it returns {output}"
-                    )
-                })
+                }) {
+            output
         } else {
             span_bug!(
                 ident.span,
@@ -650,13 +645,13 @@ pub fn check_function_signature<'tcx>(
                 }))),
                 err,
                 false,
+                None,
             );
             return Err(diag.emit());
         }
     }
 
-    let outlives_env = OutlivesEnvironment::new(param_env);
-    if let Err(e) = ocx.resolve_regions_and_report_errors(local_id, &outlives_env) {
+    if let Err(e) = ocx.resolve_regions_and_report_errors(local_id, param_env, []) {
         return Err(e);
     }
 
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index cd19993f937..c9837ca3716 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -25,11 +25,10 @@ use rustc_middle::{bug, span_bug};
 use rustc_session::parse::feature_err;
 use rustc_span::{DUMMY_SP, Ident, Span, sym};
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
-use rustc_trait_selection::regions::InferCtxtRegionExt;
+use rustc_trait_selection::regions::{InferCtxtRegionExt, OutlivesEnvironmentBuildExt};
 use rustc_trait_selection::traits::misc::{
     ConstParamTyImplementationError, type_allowed_to_implement_const_param_ty,
 };
-use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_trait_selection::traits::{
     self, FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, ObligationCtxt,
@@ -128,13 +127,17 @@ where
     let infcx_compat = infcx.fork();
 
     // We specifically want to call the non-compat version of `implied_bounds_tys`; we do this always.
-    let implied_bounds =
-        infcx.implied_bounds_tys_compat(param_env, body_def_id, &assumed_wf_types, false);
-    let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
+    let outlives_env = OutlivesEnvironment::new_with_implied_bounds_compat(
+        &infcx,
+        body_def_id,
+        param_env,
+        assumed_wf_types.iter().copied(),
+        false,
+    );
 
     lint_redundant_lifetimes(tcx, body_def_id, &outlives_env);
 
-    let errors = infcx.resolve_regions(&outlives_env);
+    let errors = infcx.resolve_regions_with_outlives_env(&outlives_env);
     if errors.is_empty() {
         return Ok(());
     }
@@ -172,10 +175,14 @@ where
     // but that does result in slightly more work when this option is set and
     // just obscures what we mean here anyways. Let's just be explicit.
     if is_bevy && !infcx.tcx.sess.opts.unstable_opts.no_implied_bounds_compat {
-        let implied_bounds =
-            infcx_compat.implied_bounds_tys_compat(param_env, body_def_id, &assumed_wf_types, true);
-        let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
-        let errors_compat = infcx_compat.resolve_regions(&outlives_env);
+        let outlives_env = OutlivesEnvironment::new_with_implied_bounds_compat(
+            &infcx,
+            body_def_id,
+            param_env,
+            assumed_wf_types,
+            true,
+        );
+        let errors_compat = infcx_compat.resolve_regions_with_outlives_env(&outlives_env);
         if errors_compat.is_empty() {
             Ok(())
         } else {
@@ -769,12 +776,7 @@ fn test_region_obligations<'tcx>(
 
     add_constraints(&infcx);
 
-    let outlives_environment = OutlivesEnvironment::with_bounds(
-        param_env,
-        infcx.implied_bounds_tys(param_env, id, wf_tys),
-    );
-
-    let errors = infcx.resolve_regions(&outlives_environment);
+    let errors = infcx.resolve_regions(id, param_env, wf_tys.iter().copied());
     debug!(?errors, "errors");
 
     // If we were able to prove that the type outlives the region without
@@ -2265,14 +2267,12 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
 
 fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), ErrorGuaranteed> {
     let items = tcx.hir_module_items(module);
-    let mut res = items.par_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id));
-    res =
-        res.and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)));
-    res =
-        res.and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)));
-    res = res
-        .and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)));
-    res = res.and(items.par_opaques(|item| tcx.ensure().check_well_formed(item)));
+    let res = items
+        .par_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))
+        .and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)))
+        .and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)))
+        .and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)))
+        .and(items.par_opaques(|item| tcx.ensure().check_well_formed(item)));
     if module == LocalModDefId::CRATE_DEF_ID {
         super::entry::check_for_entry_fn(tcx);
     }
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 27a7c2ea530..30f51fe1724 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -10,7 +10,6 @@ use rustc_hir as hir;
 use rustc_hir::ItemKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::lang_items::LangItem;
-use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{self, RegionResolutionError, TyCtxtInferExt};
 use rustc_infer::traits::Obligation;
 use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
@@ -346,8 +345,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
                 }
 
                 // Finally, resolve all regions.
-                let outlives_env = OutlivesEnvironment::new(param_env);
-                res = res.and(ocx.resolve_regions_and_report_errors(impl_did, &outlives_env));
+                res = res.and(ocx.resolve_regions_and_report_errors(impl_did, param_env, []));
             }
             res
         }
@@ -406,17 +404,12 @@ pub(crate) fn coerce_unsized_info<'tcx>(
             check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ref(tcx, r_b, ty))
         }
 
-        (&ty::Ref(_, ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b)) => check_mutbl(
-            ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a },
-            ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b },
-            &|ty| Ty::new_imm_ptr(tcx, ty),
-        ),
-
-        (&ty::RawPtr(ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b)) => check_mutbl(
-            ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a },
-            ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b },
-            &|ty| Ty::new_imm_ptr(tcx, ty),
-        ),
+        (&ty::Ref(_, ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b))
+        | (&ty::RawPtr(ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b)) => {
+            let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a };
+            let mt_b = ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b };
+            check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ptr(tcx, ty))
+        }
 
         (&ty::Adt(def_a, args_a), &ty::Adt(def_b, args_b))
             if def_a.is_struct() && def_b.is_struct() =>
@@ -564,8 +557,7 @@ pub(crate) fn coerce_unsized_info<'tcx>(
     }
 
     // Finally, resolve all regions.
-    let outlives_env = OutlivesEnvironment::new(param_env);
-    let _ = ocx.resolve_regions_and_report_errors(impl_did, &outlives_env);
+    let _ = ocx.resolve_regions_and_report_errors(impl_did, param_env, []);
 
     Ok(CoerceUnsizedInfo { custom_kind: kind })
 }
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index 4e5f0a3186a..b1f73a903d8 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -158,12 +158,12 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed>
         let trait_ref = trait_header.trait_ref.instantiate_identity();
         let trait_def = tcx.trait_def(trait_ref.def_id);
 
-        res = res.and(check_impl(tcx, impl_def_id, trait_ref, trait_def));
-        res = res.and(check_object_overlap(tcx, impl_def_id, trait_ref));
-
-        res = res.and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def));
-        res = res.and(tcx.ensure().orphan_check_impl(impl_def_id));
-        res = res.and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header));
+        res = res
+            .and(check_impl(tcx, impl_def_id, trait_ref, trait_def))
+            .and(check_object_overlap(tcx, impl_def_id, trait_ref))
+            .and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def))
+            .and(tcx.ensure().orphan_check_impl(impl_def_id))
+            .and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header));
     }
 
     res
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index cad7b2a1e57..226370fccad 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -57,7 +57,7 @@ mod type_of;
 
 ///////////////////////////////////////////////////////////////////////////
 
-pub fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers) {
     resolve_bound_vars::provide(providers);
     *providers = Providers {
         type_of: type_of::type_of,
@@ -122,7 +122,7 @@ pub fn provide(providers: &mut Providers) {
 /// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
 /// `probe_ty_param_bounds` requests, drawing the information from
 /// the HIR (`hir::Generics`), recursively.
-pub struct ItemCtxt<'tcx> {
+pub(crate) struct ItemCtxt<'tcx> {
     tcx: TyCtxt<'tcx>,
     item_def_id: LocalDefId,
     tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
@@ -148,7 +148,7 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector {
     }
 }
 
-pub struct CollectItemTypesVisitor<'tcx> {
+pub(crate) struct CollectItemTypesVisitor<'tcx> {
     pub tcx: TyCtxt<'tcx>,
 }
 
@@ -364,19 +364,19 @@ fn bad_placeholder<'cx, 'tcx>(
 }
 
 impl<'tcx> ItemCtxt<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId) -> ItemCtxt<'tcx> {
+    pub(crate) fn new(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId) -> ItemCtxt<'tcx> {
         ItemCtxt { tcx, item_def_id, tainted_by_errors: Cell::new(None) }
     }
 
-    pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
+    pub(crate) fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
         self.lowerer().lower_ty(hir_ty)
     }
 
-    pub fn hir_id(&self) -> hir::HirId {
+    pub(crate) fn hir_id(&self) -> hir::HirId {
         self.tcx.local_def_id_to_hir_id(self.item_def_id)
     }
 
-    pub fn node(&self) -> hir::Node<'tcx> {
+    pub(crate) fn node(&self) -> hir::Node<'tcx> {
         self.tcx.hir_node(self.hir_id())
     }
 
diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs
index f1022d95753..4a508fc0cf6 100644
--- a/compiler/rustc_hir_analysis/src/collect/dump.rs
+++ b/compiler/rustc_hir_analysis/src/collect/dump.rs
@@ -1,7 +1,8 @@
+use rustc_hir as hir;
 use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
 use rustc_hir::intravisit;
 use rustc_middle::hir::nested_filter;
-use rustc_middle::ty::TyCtxt;
+use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 use rustc_span::sym;
 
 pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) {
@@ -87,3 +88,82 @@ pub(crate) fn def_parents(tcx: TyCtxt<'_>) {
         }
     }
 }
+
+pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
+    for id in tcx.hir().items() {
+        let def_id = id.owner_id.def_id;
+
+        let Some(attr) = tcx.get_attr(def_id, sym::rustc_dump_vtable) else {
+            continue;
+        };
+
+        let vtable_entries = match tcx.hir().item(id).kind {
+            hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => {
+                let trait_ref = tcx.impl_trait_ref(def_id).unwrap().instantiate_identity();
+                if trait_ref.has_non_region_param() {
+                    tcx.dcx().span_err(
+                        attr.span,
+                        "`rustc_dump_vtable` must be applied to non-generic impl",
+                    );
+                    continue;
+                }
+                if !tcx.is_dyn_compatible(trait_ref.def_id) {
+                    tcx.dcx().span_err(
+                        attr.span,
+                        "`rustc_dump_vtable` must be applied to dyn-compatible trait",
+                    );
+                    continue;
+                }
+                let Ok(trait_ref) = tcx
+                    .try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref)
+                else {
+                    tcx.dcx().span_err(
+                        attr.span,
+                        "`rustc_dump_vtable` applied to impl header that cannot be normalized",
+                    );
+                    continue;
+                };
+                tcx.vtable_entries(trait_ref)
+            }
+            hir::ItemKind::TyAlias(_, _) => {
+                let ty = tcx.type_of(def_id).instantiate_identity();
+                if ty.has_non_region_param() {
+                    tcx.dcx().span_err(
+                        attr.span,
+                        "`rustc_dump_vtable` must be applied to non-generic type",
+                    );
+                    continue;
+                }
+                let Ok(ty) =
+                    tcx.try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
+                else {
+                    tcx.dcx().span_err(
+                        attr.span,
+                        "`rustc_dump_vtable` applied to type alias that cannot be normalized",
+                    );
+                    continue;
+                };
+                let ty::Dynamic(data, _, _) = *ty.kind() else {
+                    tcx.dcx().span_err(attr.span, "`rustc_dump_vtable` to type alias of dyn type");
+                    continue;
+                };
+                if let Some(principal) = data.principal() {
+                    tcx.vtable_entries(
+                        tcx.instantiate_bound_regions_with_erased(principal).with_self_ty(tcx, ty),
+                    )
+                } else {
+                    TyCtxt::COMMON_VTABLE_ENTRIES
+                }
+            }
+            _ => {
+                tcx.dcx().span_err(
+                    attr.span,
+                    "`rustc_dump_vtable` only applies to impl, or type alias of dyn type",
+                );
+                continue;
+            }
+        };
+
+        tcx.dcx().span_err(tcx.def_span(def_id), format!("vtable entries: {vtable_entries:#?}"));
+    }
+}
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 72baf5c4b58..d67b9d33596 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -12,13 +12,11 @@ use std::ops::ControlFlow;
 
 use rustc_ast::visit::walk_list;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
-use rustc_data_structures::sorted_map::SortedMap;
 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, ItemLocalMap,
-    LifetimeName, Node,
+    self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeName, Node,
 };
 use rustc_macros::extension;
 use rustc_middle::hir::nested_filter;
@@ -26,7 +24,7 @@ use rustc_middle::middle::resolve_bound_vars::*;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
 use rustc_middle::{bug, span_bug};
-use rustc_span::def_id::{DefId, LocalDefId, LocalDefIdMap};
+use rustc_span::def_id::{DefId, LocalDefId};
 use rustc_span::{Ident, Span, sym};
 use tracing::{debug, debug_span, instrument};
 
@@ -62,33 +60,9 @@ impl ResolvedArg {
     }
 }
 
-/// Maps the id of each bound variable reference to the variable decl
-/// that it corresponds to.
-///
-/// FIXME. This struct gets converted to a `ResolveBoundVars` for
-/// actual use. It has the same data, but indexed by `LocalDefId`. This
-/// is silly.
-#[derive(Debug, Default)]
-struct NamedVarMap {
-    // maps from every use of a named (not anonymous) bound var to a
-    // `ResolvedArg` describing how that variable is bound
-    defs: ItemLocalMap<ResolvedArg>,
-
-    // Maps relevant hir items to the bound vars on them. These include:
-    // - function defs
-    // - function pointers
-    // - closures
-    // - trait refs
-    // - bound types (like `T` in `for<'a> T<'a>: Foo`)
-    late_bound_vars: ItemLocalMap<Vec<ty::BoundVariableKind>>,
-
-    // List captured variables for each opaque type.
-    opaque_captured_lifetimes: LocalDefIdMap<Vec<(ResolvedArg, LocalDefId)>>,
-}
-
 struct BoundVarContext<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
-    map: &'a mut NamedVarMap,
+    rbv: &'a mut ResolveBoundVars,
     scope: ScopeRef<'a>,
 }
 
@@ -267,19 +241,12 @@ pub(crate) fn provide(providers: &mut Providers) {
 
 /// Computes the `ResolveBoundVars` map that contains data for an entire `Item`.
 /// You should not read the result of this query directly, but rather use
-/// `named_variable_map`, `is_late_bound_map`, etc.
+/// `named_variable_map`, `late_bound_vars_map`, etc.
 #[instrument(level = "debug", skip(tcx))]
 fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBoundVars {
-    let mut named_variable_map = NamedVarMap {
-        defs: Default::default(),
-        late_bound_vars: Default::default(),
-        opaque_captured_lifetimes: Default::default(),
-    };
-    let mut visitor = BoundVarContext {
-        tcx,
-        map: &mut named_variable_map,
-        scope: &Scope::Root { opt_parent_item: None },
-    };
+    let mut rbv = ResolveBoundVars::default();
+    let mut visitor =
+        BoundVarContext { tcx, rbv: &mut rbv, scope: &Scope::Root { opt_parent_item: None } };
     match tcx.hir_owner_node(local_def_id) {
         hir::OwnerNode::Item(item) => visitor.visit_item(item),
         hir::OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item),
@@ -299,19 +266,10 @@ fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBou
         hir::OwnerNode::Synthetic => unreachable!(),
     }
 
-    let defs = named_variable_map.defs.into_sorted_stable_ord();
-    let late_bound_vars = named_variable_map.late_bound_vars.into_sorted_stable_ord();
-    let opaque_captured_lifetimes = named_variable_map.opaque_captured_lifetimes;
-    let rl = ResolveBoundVars {
-        defs: SortedMap::from_presorted_elements(defs),
-        late_bound_vars: SortedMap::from_presorted_elements(late_bound_vars),
-        opaque_captured_lifetimes,
-    };
-
-    debug!(?rl.defs);
-    debug!(?rl.late_bound_vars);
-    debug!(?rl.opaque_captured_lifetimes);
-    rl
+    debug!(?rbv.defs);
+    debug!(?rbv.late_bound_vars);
+    debug!(?rbv.opaque_captured_lifetimes);
+    rbv
 }
 
 fn late_arg_as_bound_arg<'tcx>(
@@ -404,7 +362,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                 Scope::Binder { hir_id, .. } => {
                     // Nested poly trait refs have the binders concatenated
                     let mut full_binders =
-                        self.map.late_bound_vars.entry(hir_id.local_id).or_default().clone();
+                        self.rbv.late_bound_vars.get_mut_or_insert_default(hir_id.local_id).clone();
                     full_binders.extend(supertrait_bound_vars);
                     break (full_binders, BinderScopeType::Concatenating);
                 }
@@ -646,7 +604,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
 
         let captures = captures.into_inner().into_iter().collect();
         debug!(?captures);
-        self.map.opaque_captured_lifetimes.insert(opaque.def_id, captures);
+        self.rbv.opaque_captured_lifetimes.insert(opaque.def_id, captures);
     }
 
     #[instrument(level = "debug", skip(self))]
@@ -848,7 +806,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
             hir::TyKind::Ref(lifetime_ref, ref mt) => {
                 self.visit_lifetime(lifetime_ref);
                 let scope = Scope::ObjectLifetimeDefault {
-                    lifetime: self.map.defs.get(&lifetime_ref.hir_id.local_id).cloned(),
+                    lifetime: self.rbv.defs.get(&lifetime_ref.hir_id.local_id).cloned(),
                     s: self.scope,
                 };
                 self.with(scope, |this| this.visit_ty_unambig(mt.ty));
@@ -966,7 +924,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
             let bound_vars: Vec<_> =
                 self.tcx.fn_sig(sig_id).skip_binder().bound_vars().iter().collect();
             let hir_id = self.tcx.local_def_id_to_hir_id(def_id);
-            self.map.late_bound_vars.insert(hir_id.local_id, bound_vars);
+            self.rbv.late_bound_vars.insert(hir_id.local_id, bound_vars);
         }
         self.visit_fn_like_elision(fd.inputs, output, matches!(fk, intravisit::FnKind::Closure));
         intravisit::walk_fn_kind(self, fk);
@@ -1140,8 +1098,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
     where
         F: for<'b> FnOnce(&mut BoundVarContext<'b, 'tcx>),
     {
-        let BoundVarContext { tcx, map, .. } = self;
-        let mut this = BoundVarContext { tcx: *tcx, map, scope: &wrap_scope };
+        let BoundVarContext { tcx, rbv, .. } = self;
+        let mut this = BoundVarContext { tcx: *tcx, rbv, scope: &wrap_scope };
         let span = debug_span!("scope", scope = ?this.scope.debug_truncated());
         {
             let _enter = span.enter();
@@ -1150,10 +1108,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
     }
 
     fn record_late_bound_vars(&mut self, hir_id: HirId, binder: Vec<ty::BoundVariableKind>) {
-        if let Some(old) = self.map.late_bound_vars.insert(hir_id.local_id, binder) {
+        if let Some(old) = self.rbv.late_bound_vars.insert(hir_id.local_id, binder) {
             bug!(
                 "overwrote bound vars for {hir_id:?}:\nold={old:?}\nnew={:?}",
-                self.map.late_bound_vars[&hir_id.local_id]
+                self.rbv.late_bound_vars[&hir_id.local_id]
             )
         }
     }
@@ -1597,9 +1555,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                         kind.descr(param_def_id.to_def_id())
                     ),
                 };
-                self.map.defs.insert(hir_id.local_id, ResolvedArg::Error(guar));
+                self.rbv.defs.insert(hir_id.local_id, ResolvedArg::Error(guar));
             } else {
-                self.map.defs.insert(hir_id.local_id, def);
+                self.rbv.defs.insert(hir_id.local_id, def);
             }
             return;
         }
@@ -1632,7 +1590,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                             bug!("unexpected def-kind: {}", kind.descr(param_def_id.to_def_id()))
                         }
                     });
-                    self.map.defs.insert(hir_id.local_id, ResolvedArg::Error(guar));
+                    self.rbv.defs.insert(hir_id.local_id, ResolvedArg::Error(guar));
                     return;
                 }
                 Scope::Root { .. } => break,
@@ -1725,7 +1683,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                 }
             };
 
-            let map = &self.map;
+            let rbv = &self.rbv;
             let generics = self.tcx.generics_of(def_id);
 
             // `type_def_id` points to an item, so there is nothing to inherit generics from.
@@ -1744,7 +1702,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                     // This index can be used with `generic_args` since `parent_count == 0`.
                     let index = generics.param_def_id_to_index[&param_def_id] as usize;
                     generic_args.args.get(index).and_then(|arg| match arg {
-                        GenericArg::Lifetime(lt) => map.defs.get(&lt.hir_id.local_id).copied(),
+                        GenericArg::Lifetime(lt) => rbv.defs.get(&lt.hir_id.local_id).copied(),
                         _ => None,
                     })
                 }
@@ -2042,7 +2000,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
     #[instrument(level = "debug", skip(self))]
     fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: ResolvedArg) {
         debug!(span = ?lifetime_ref.ident.span);
-        self.map.defs.insert(lifetime_ref.hir_id.local_id, def);
+        self.rbv.defs.insert(lifetime_ref.hir_id.local_id, def);
     }
 
     // When we have a return type notation type in a where clause, like
@@ -2197,7 +2155,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
         // See where these vars are used in `HirTyLowerer::lower_ty_maybe_return_type_notation`.
         // And this is exercised in:
         // `tests/ui/associated-type-bounds/return-type-notation/higher-ranked-bound-works.rs`.
-        let existing_bound_vars = self.map.late_bound_vars.get_mut(&hir_id.local_id).unwrap();
+        let existing_bound_vars = self.rbv.late_bound_vars.get_mut(&hir_id.local_id).unwrap();
         let existing_bound_vars_saved = existing_bound_vars.clone();
         existing_bound_vars.extend(bound_vars);
         self.record_late_bound_vars(item_segment.hir_id, existing_bound_vars_saved);
diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs
index e65420ea8bf..ed45833b614 100644
--- a/compiler/rustc_hir_analysis/src/delegation.rs
+++ b/compiler/rustc_hir_analysis/src/delegation.rs
@@ -100,213 +100,156 @@ enum InheritanceKind {
     Own,
 }
 
-struct GenericsBuilder<'tcx> {
+fn build_generics<'tcx>(
     tcx: TyCtxt<'tcx>,
     sig_id: DefId,
     parent: Option<DefId>,
     inh_kind: InheritanceKind,
-}
-
-impl<'tcx> GenericsBuilder<'tcx> {
-    fn new(tcx: TyCtxt<'tcx>, sig_id: DefId) -> GenericsBuilder<'tcx> {
-        GenericsBuilder { tcx, sig_id, parent: None, inh_kind: InheritanceKind::WithParent(false) }
-    }
-
-    fn with_parent(mut self, parent: DefId) -> Self {
-        self.parent = Some(parent);
-        self
-    }
-
-    fn with_inheritance_kind(mut self, inh_kind: InheritanceKind) -> Self {
-        self.inh_kind = inh_kind;
-        self
-    }
-
-    fn build(self) -> ty::Generics {
-        let mut own_params = vec![];
+) -> ty::Generics {
+    let mut own_params = vec![];
 
-        let sig_generics = self.tcx.generics_of(self.sig_id);
-        if let InheritanceKind::WithParent(has_self) = self.inh_kind
-            && let Some(parent_def_id) = sig_generics.parent
-        {
-            let sig_parent_generics = self.tcx.generics_of(parent_def_id);
-            own_params.append(&mut sig_parent_generics.own_params.clone());
-            if !has_self {
-                own_params.remove(0);
-            }
+    let sig_generics = tcx.generics_of(sig_id);
+    if let InheritanceKind::WithParent(has_self) = inh_kind
+        && let Some(parent_def_id) = sig_generics.parent
+    {
+        let sig_parent_generics = tcx.generics_of(parent_def_id);
+        own_params.append(&mut sig_parent_generics.own_params.clone());
+        if !has_self {
+            own_params.remove(0);
         }
-        own_params.append(&mut sig_generics.own_params.clone());
+    }
+    own_params.append(&mut sig_generics.own_params.clone());
+
+    // Lifetime parameters must be declared before type and const parameters.
+    // Therefore, When delegating from a free function to a associated function,
+    // generic parameters need to be reordered:
+    //
+    // trait Trait<'a, A> {
+    //     fn foo<'b, B>(...) {...}
+    // }
+    //
+    // reuse Trait::foo;
+    // desugaring:
+    // fn foo<'a, 'b, This: Trait<'a, A>, A, B>(...) {
+    //     Trait::foo(...)
+    // }
+    own_params.sort_by_key(|key| key.kind.is_ty_or_const());
+
+    let param_def_id_to_index =
+        own_params.iter().map(|param| (param.def_id, param.index)).collect();
+
+    let (parent_count, has_self) = if let Some(def_id) = parent {
+        let parent_generics = tcx.generics_of(def_id);
+        let parent_kind = tcx.def_kind(def_id);
+        (parent_generics.count(), parent_kind == DefKind::Trait)
+    } else {
+        (0, false)
+    };
 
-        // Lifetime parameters must be declared before type and const parameters.
-        // Therefore, When delegating from a free function to a associated function,
-        // generic parameters need to be reordered:
+    for (idx, param) in own_params.iter_mut().enumerate() {
+        param.index = (idx + parent_count) as u32;
+        // FIXME(fn_delegation): Default parameters are not inherited, because they are
+        // not permitted in functions. Therefore, there are 2 options here:
         //
-        // trait Trait<'a, A> {
-        //     fn foo<'b, B>(...) {...}
-        // }
+        // - We can create non-default generic parameters.
+        // - We can substitute default parameters into the signature.
         //
-        // reuse Trait::foo;
-        // desugaring:
-        // fn foo<'a, 'b, This: Trait<'a, A>, A, B>(...) {
-        //     Trait::foo(...)
-        // }
-        own_params.sort_by_key(|key| key.kind.is_ty_or_const());
-
-        let param_def_id_to_index =
-            own_params.iter().map(|param| (param.def_id, param.index)).collect();
-
-        let (parent_count, has_self) = if let Some(def_id) = self.parent {
-            let parent_generics = self.tcx.generics_of(def_id);
-            let parent_kind = self.tcx.def_kind(def_id);
-            (parent_generics.count(), parent_kind == DefKind::Trait)
-        } else {
-            (0, false)
-        };
-
-        for (idx, param) in own_params.iter_mut().enumerate() {
-            param.index = (idx + parent_count) as u32;
-            // FIXME(fn_delegation): Default parameters are not inherited, because they are
-            // not permitted in functions. Therefore, there are 2 options here:
-            //
-            // - We can create non-default generic parameters.
-            // - We can substitute default parameters into the signature.
-            //
-            // At the moment, first option has been selected as the most general.
-            if let ty::GenericParamDefKind::Type { has_default, .. }
-            | ty::GenericParamDefKind::Const { has_default, .. } = &mut param.kind
-            {
-                *has_default = false;
-            }
+        // At the moment, first option has been selected as the most general.
+        if let ty::GenericParamDefKind::Type { has_default, .. }
+        | ty::GenericParamDefKind::Const { has_default, .. } = &mut param.kind
+        {
+            *has_default = false;
         }
+    }
 
-        ty::Generics {
-            parent: self.parent,
-            parent_count,
-            own_params,
-            param_def_id_to_index,
-            has_self,
-            has_late_bound_regions: sig_generics.has_late_bound_regions,
-        }
+    ty::Generics {
+        parent,
+        parent_count,
+        own_params,
+        param_def_id_to_index,
+        has_self,
+        has_late_bound_regions: sig_generics.has_late_bound_regions,
     }
 }
 
-struct PredicatesBuilder<'tcx> {
+fn build_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     sig_id: DefId,
     parent: Option<DefId>,
     inh_kind: InheritanceKind,
     args: ty::GenericArgsRef<'tcx>,
-}
-
-impl<'tcx> PredicatesBuilder<'tcx> {
-    fn new(
+) -> ty::GenericPredicates<'tcx> {
+    struct PredicatesCollector<'tcx> {
         tcx: TyCtxt<'tcx>,
+        preds: Vec<(ty::Clause<'tcx>, Span)>,
         args: ty::GenericArgsRef<'tcx>,
-        sig_id: DefId,
-    ) -> PredicatesBuilder<'tcx> {
-        PredicatesBuilder {
-            tcx,
-            sig_id,
-            parent: None,
-            inh_kind: InheritanceKind::WithParent(false),
-            args,
-        }
-    }
-
-    fn with_parent(mut self, parent: DefId) -> Self {
-        self.parent = Some(parent);
-        self
     }
 
-    fn with_inheritance_kind(mut self, inh_kind: InheritanceKind) -> Self {
-        self.inh_kind = inh_kind;
-        self
-    }
-
-    fn build(self) -> ty::GenericPredicates<'tcx> {
-        struct PredicatesCollector<'tcx> {
-            tcx: TyCtxt<'tcx>,
-            preds: Vec<(ty::Clause<'tcx>, Span)>,
-            args: ty::GenericArgsRef<'tcx>,
+    impl<'tcx> PredicatesCollector<'tcx> {
+        fn new(tcx: TyCtxt<'tcx>, args: ty::GenericArgsRef<'tcx>) -> PredicatesCollector<'tcx> {
+            PredicatesCollector { tcx, preds: vec![], args }
         }
 
-        impl<'tcx> PredicatesCollector<'tcx> {
-            fn new(tcx: TyCtxt<'tcx>, args: ty::GenericArgsRef<'tcx>) -> PredicatesCollector<'tcx> {
-                PredicatesCollector { tcx, preds: vec![], args }
-            }
-
-            fn with_own_preds(
-                mut self,
-                f: impl Fn(DefId) -> ty::GenericPredicates<'tcx>,
-                def_id: DefId,
-            ) -> Self {
-                let preds = f(def_id).instantiate_own(self.tcx, self.args);
-                self.preds.extend(preds);
-                self
-            }
+        fn with_own_preds(
+            mut self,
+            f: impl Fn(DefId) -> ty::GenericPredicates<'tcx>,
+            def_id: DefId,
+        ) -> Self {
+            let preds = f(def_id).instantiate_own(self.tcx, self.args);
+            self.preds.extend(preds);
+            self
+        }
 
-            fn with_preds(
-                mut self,
-                f: impl Fn(DefId) -> ty::GenericPredicates<'tcx> + Copy,
-                def_id: DefId,
-            ) -> Self {
-                let preds = f(def_id);
-                if let Some(parent_def_id) = preds.parent {
-                    self = self.with_own_preds(f, parent_def_id);
-                }
-                self.with_own_preds(f, def_id)
+        fn with_preds(
+            mut self,
+            f: impl Fn(DefId) -> ty::GenericPredicates<'tcx> + Copy,
+            def_id: DefId,
+        ) -> Self {
+            let preds = f(def_id);
+            if let Some(parent_def_id) = preds.parent {
+                self = self.with_own_preds(f, parent_def_id);
             }
+            self.with_own_preds(f, def_id)
         }
-        let collector = PredicatesCollector::new(self.tcx, self.args);
-
-        // `explicit_predicates_of` is used here to avoid copying `Self: Trait` predicate.
-        // Note: `predicates_of` query can also add inferred outlives predicates, but that
-        // is not the case here as `sig_id` is either a trait or a function.
-        let preds = match self.inh_kind {
-            InheritanceKind::WithParent(false) => {
-                collector.with_preds(|def_id| self.tcx.explicit_predicates_of(def_id), self.sig_id)
-            }
-            InheritanceKind::WithParent(true) => {
-                collector.with_preds(|def_id| self.tcx.predicates_of(def_id), self.sig_id)
-            }
-            InheritanceKind::Own => {
-                collector.with_own_preds(|def_id| self.tcx.predicates_of(def_id), self.sig_id)
-            }
+    }
+    let collector = PredicatesCollector::new(tcx, args);
+
+    // `explicit_predicates_of` is used here to avoid copying `Self: Trait` predicate.
+    // Note: `predicates_of` query can also add inferred outlives predicates, but that
+    // is not the case here as `sig_id` is either a trait or a function.
+    let preds = match inh_kind {
+        InheritanceKind::WithParent(false) => {
+            collector.with_preds(|def_id| tcx.explicit_predicates_of(def_id), sig_id)
         }
-        .preds;
-
-        ty::GenericPredicates {
-            parent: self.parent,
-            predicates: self.tcx.arena.alloc_from_iter(preds),
+        InheritanceKind::WithParent(true) => {
+            collector.with_preds(|def_id| tcx.predicates_of(def_id), sig_id)
+        }
+        InheritanceKind::Own => {
+            collector.with_own_preds(|def_id| tcx.predicates_of(def_id), sig_id)
         }
     }
+    .preds;
+
+    ty::GenericPredicates { parent, predicates: tcx.arena.alloc_from_iter(preds) }
 }
 
-struct GenericArgsBuilder<'tcx> {
+fn build_generic_args<'tcx>(
     tcx: TyCtxt<'tcx>,
-    remap_table: RemapTable,
     sig_id: DefId,
     def_id: LocalDefId,
-}
+    args: ty::GenericArgsRef<'tcx>,
+) -> ty::GenericArgsRef<'tcx> {
+    let caller_generics = tcx.generics_of(def_id);
+    let callee_generics = tcx.generics_of(sig_id);
 
-impl<'tcx> GenericArgsBuilder<'tcx> {
-    fn new(tcx: TyCtxt<'tcx>, sig_id: DefId, def_id: LocalDefId) -> GenericArgsBuilder<'tcx> {
-        GenericArgsBuilder { tcx, remap_table: FxHashMap::default(), sig_id, def_id }
+    let mut remap_table = FxHashMap::default();
+    for caller_param in &caller_generics.own_params {
+        let callee_index = callee_generics.param_def_id_to_index(tcx, caller_param.def_id).unwrap();
+        remap_table.insert(callee_index, caller_param.index);
     }
 
-    fn build_from_args(mut self, args: ty::GenericArgsRef<'tcx>) -> ty::GenericArgsRef<'tcx> {
-        let caller_generics = self.tcx.generics_of(self.def_id);
-        let callee_generics = self.tcx.generics_of(self.sig_id);
-
-        for caller_param in &caller_generics.own_params {
-            let callee_index =
-                callee_generics.param_def_id_to_index(self.tcx, caller_param.def_id).unwrap();
-            self.remap_table.insert(callee_index, caller_param.index);
-        }
-
-        let mut folder = ParamIndexRemapper { tcx: self.tcx, remap_table: self.remap_table };
-        args.fold_with(&mut folder)
-    }
+    let mut folder = ParamIndexRemapper { tcx, remap_table };
+    args.fold_with(&mut folder)
 }
 
 fn create_generic_args<'tcx>(
@@ -314,8 +257,6 @@ fn create_generic_args<'tcx>(
     def_id: LocalDefId,
     sig_id: DefId,
 ) -> ty::GenericArgsRef<'tcx> {
-    let builder = GenericArgsBuilder::new(tcx, sig_id, def_id);
-
     let caller_kind = fn_kind(tcx, def_id.into());
     let callee_kind = fn_kind(tcx, sig_id);
     match (caller_kind, callee_kind) {
@@ -325,7 +266,7 @@ fn create_generic_args<'tcx>(
         | (FnKind::AssocTrait, FnKind::Free)
         | (FnKind::AssocTrait, FnKind::AssocTrait) => {
             let args = ty::GenericArgs::identity_for_item(tcx, sig_id);
-            builder.build_from_args(args)
+            build_generic_args(tcx, sig_id, def_id, args)
         }
 
         (FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
@@ -335,8 +276,9 @@ fn create_generic_args<'tcx>(
                 tcx.impl_trait_header(parent).unwrap().trait_ref.instantiate_identity().args;
 
             let trait_args = ty::GenericArgs::identity_for_item(tcx, sig_id);
-            let method_args = tcx.mk_args_from_iter(trait_args.iter().skip(callee_generics.parent_count));
-            let method_args = builder.build_from_args(method_args);
+            let method_args =
+                tcx.mk_args_from_iter(trait_args.iter().skip(callee_generics.parent_count));
+            let method_args = build_generic_args(tcx, sig_id, def_id, method_args);
 
             tcx.mk_args_from_iter(parent_args.iter().chain(method_args))
         }
@@ -347,16 +289,16 @@ fn create_generic_args<'tcx>(
             let generic_self_ty = ty::GenericArg::from(self_ty);
 
             let trait_args = ty::GenericArgs::identity_for_item(tcx, sig_id);
-            let trait_args = builder.build_from_args(trait_args);
+            let trait_args = build_generic_args(tcx, sig_id, def_id, trait_args);
 
             let args = std::iter::once(generic_self_ty).chain(trait_args.iter().skip(1));
             tcx.mk_args_from_iter(args)
         }
 
         // For trait impl's `sig_id` is always equal to the corresponding trait method.
+        // For inherent methods delegation is not yet supported.
         (FnKind::AssocTraitImpl, _)
         | (_, FnKind::AssocTraitImpl)
-        // Delegation to inherent methods is not yet supported.
         | (_, FnKind::AssocInherentImpl) => unreachable!(),
     }
 }
@@ -377,39 +319,31 @@ pub(crate) fn inherit_generics_for_delegation_item<'tcx>(
     def_id: LocalDefId,
     sig_id: DefId,
 ) -> ty::Generics {
-    let builder = GenericsBuilder::new(tcx, sig_id);
-
     let caller_kind = fn_kind(tcx, def_id.into());
     let callee_kind = fn_kind(tcx, sig_id);
     match (caller_kind, callee_kind) {
-        (FnKind::Free, FnKind::Free)
-        | (FnKind::Free, FnKind::AssocTrait) => builder.with_inheritance_kind(InheritanceKind::WithParent(true)).build(),
+        (FnKind::Free, FnKind::Free) | (FnKind::Free, FnKind::AssocTrait) => {
+            build_generics(tcx, sig_id, None, InheritanceKind::WithParent(true))
+        }
 
         (FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
-            builder
-            .with_parent(tcx.parent(def_id.into()))
-            .with_inheritance_kind(InheritanceKind::Own)
-            .build()
+            build_generics(tcx, sig_id, Some(tcx.parent(def_id.into())), InheritanceKind::Own)
         }
 
         (FnKind::AssocInherentImpl, FnKind::AssocTrait)
-        | (FnKind::AssocTrait, FnKind::AssocTrait) => {
-            builder
-            .with_parent(tcx.parent(def_id.into()))
-            .build()
-        }
-
-        (FnKind::AssocInherentImpl, FnKind::Free)
-        | (FnKind::AssocTrait, FnKind::Free) => {
-            builder
-            .with_parent(tcx.parent(def_id.into()))
-            .build()
-        }
+        | (FnKind::AssocTrait, FnKind::AssocTrait)
+        | (FnKind::AssocInherentImpl, FnKind::Free)
+        | (FnKind::AssocTrait, FnKind::Free) => build_generics(
+            tcx,
+            sig_id,
+            Some(tcx.parent(def_id.into())),
+            InheritanceKind::WithParent(false),
+        ),
 
         // For trait impl's `sig_id` is always equal to the corresponding trait method.
+        // For inherent methods delegation is not yet supported.
         (FnKind::AssocTraitImpl, _)
         | (_, FnKind::AssocTraitImpl)
-        // Delegation to inherent methods is not yet supported.
         | (_, FnKind::AssocInherentImpl) => unreachable!(),
     }
 }
@@ -420,36 +354,36 @@ pub(crate) fn inherit_predicates_for_delegation_item<'tcx>(
     sig_id: DefId,
 ) -> ty::GenericPredicates<'tcx> {
     let args = create_generic_args(tcx, def_id, sig_id);
-    let builder = PredicatesBuilder::new(tcx, args, sig_id);
-
     let caller_kind = fn_kind(tcx, def_id.into());
     let callee_kind = fn_kind(tcx, sig_id);
     match (caller_kind, callee_kind) {
-        (FnKind::Free, FnKind::Free)
-        | (FnKind::Free, FnKind::AssocTrait) => {
-            builder.with_inheritance_kind(InheritanceKind::WithParent(true)).build()
+        (FnKind::Free, FnKind::Free) | (FnKind::Free, FnKind::AssocTrait) => {
+            build_predicates(tcx, sig_id, None, InheritanceKind::WithParent(true), args)
         }
 
-        (FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
-            builder
-            .with_parent(tcx.parent(def_id.into()))
-            .with_inheritance_kind(InheritanceKind::Own)
-            .build()
-        }
+        (FnKind::AssocTraitImpl, FnKind::AssocTrait) => build_predicates(
+            tcx,
+            sig_id,
+            Some(tcx.parent(def_id.into())),
+            InheritanceKind::Own,
+            args,
+        ),
 
         (FnKind::AssocInherentImpl, FnKind::AssocTrait)
         | (FnKind::AssocTrait, FnKind::AssocTrait)
         | (FnKind::AssocInherentImpl, FnKind::Free)
-        | (FnKind::AssocTrait, FnKind::Free) => {
-            builder
-                .with_parent(tcx.parent(def_id.into()))
-                .build()
-        }
+        | (FnKind::AssocTrait, FnKind::Free) => build_predicates(
+            tcx,
+            sig_id,
+            Some(tcx.parent(def_id.into())),
+            InheritanceKind::WithParent(false),
+            args,
+        ),
 
         // For trait impl's `sig_id` is always equal to the corresponding trait method.
+        // For inherent methods delegation is not yet supported.
         (FnKind::AssocTraitImpl, _)
         | (_, FnKind::AssocTraitImpl)
-        // Delegation to inherent methods is not yet supported.
         | (_, FnKind::AssocInherentImpl) => unreachable!(),
     }
 }
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 67407349729..b2501d647a5 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
@@ -495,6 +495,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
                         .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/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
index fe3dcb35639..43137397870 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
@@ -273,7 +273,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
 
                             // We lower to an infer even when the feature gate is not enabled
                             // as it is useful for diagnostics to be able to see a `ConstKind::Infer`
-                            args.push(ctx.provided_kind(&args, param, arg));
+                            args.push(ctx.provided_kind(param, arg));
                             args_iter.next();
                             params.next();
                         }
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 61d5869c19f..b4cab3330af 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -296,7 +296,6 @@ pub trait GenericArgsLowerer<'a, 'tcx> {
 
     fn provided_kind(
         &mut self,
-        preceding_args: &[ty::GenericArg<'tcx>],
         param: &ty::GenericParamDef,
         arg: &GenericArg<'tcx>,
     ) -> ty::GenericArg<'tcx>;
@@ -480,7 +479,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
             fn provided_kind(
                 &mut self,
-                _preceding_args: &[ty::GenericArg<'tcx>],
                 param: &ty::GenericParamDef,
                 arg: &GenericArg<'tcx>,
             ) -> ty::GenericArg<'tcx> {
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 ee55e1bc21a..af1107b499f 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
@@ -34,7 +34,7 @@
 //! impl<T, I: Iterator<Item=T>> SpecExtend<T> for I { /* default impl */ }
 //! ```
 //!
-//! We get that the generic pamameters for `impl2` are `[T, std::vec::IntoIter<T>]`.
+//! We get that the generic parameters for `impl2` are `[T, std::vec::IntoIter<T>]`.
 //! `T` is constrained to be `<I as Iterator>::Item`, so we check only
 //! `std::vec::IntoIter<T>` for repeated parameters, which it doesn't have. The
 //! predicates of `impl1` are only `T: Sized`, which is also a predicate of
@@ -68,7 +68,6 @@
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_infer::infer::TyCtxtInferExt;
-use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::traits::ObligationCause;
 use rustc_infer::traits::specialization_graph::Node;
 use rustc_middle::ty::trait_def::TraitSpecializationKind;
@@ -77,7 +76,6 @@ use rustc_middle::ty::{
 };
 use rustc_span::{ErrorGuaranteed, Span};
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
-use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
 use rustc_trait_selection::traits::{self, ObligationCtxt, translate_args_with_cause, wf};
 use tracing::{debug, instrument};
 
@@ -121,7 +119,6 @@ fn check_always_applicable(
     impl2_node: Node,
 ) -> Result<(), ErrorGuaranteed> {
     let span = tcx.def_span(impl1_def_id);
-    let mut res = check_has_items(tcx, impl1_def_id, impl2_node, span);
 
     let (impl1_args, impl2_args) = get_impl_args(tcx, impl1_def_id, impl2_node)?;
     let impl2_def_id = impl2_node.def_id();
@@ -133,11 +130,10 @@ fn check_always_applicable(
         unconstrained_parent_impl_args(tcx, impl2_def_id, impl2_args)
     };
 
-    res = res.and(check_static_lifetimes(tcx, &parent_args, span));
-    res = res.and(check_duplicate_params(tcx, impl1_args, parent_args, span));
-    res = res.and(check_predicates(tcx, impl1_def_id, impl1_args, impl2_node, impl2_args, span));
-
-    res
+    check_has_items(tcx, impl1_def_id, impl2_node, span)
+        .and(check_static_lifetimes(tcx, &parent_args, span))
+        .and(check_duplicate_params(tcx, impl1_args, parent_args, span))
+        .and(check_predicates(tcx, impl1_def_id, impl1_args, impl2_node, impl2_args, span))
 }
 
 fn check_has_items(
@@ -176,7 +172,6 @@ fn get_impl_args(
     let ocx = ObligationCtxt::new_with_diagnostics(infcx);
     let param_env = tcx.param_env(impl1_def_id);
     let impl1_span = tcx.def_span(impl1_def_id);
-    let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl1_def_id)?;
 
     let impl1_args = GenericArgs::identity_for_item(tcx, impl1_def_id);
     let impl2_args = translate_args_with_cause(
@@ -194,9 +189,8 @@ fn get_impl_args(
         return Err(guar);
     }
 
-    let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_def_id, &assumed_wf_types);
-    let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
-    let _ = ocx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env);
+    let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl1_def_id)?;
+    let _ = ocx.resolve_regions_and_report_errors(impl1_def_id, param_env, assumed_wf_types);
     let Ok(impl2_args) = infcx.fully_resolve(impl2_args) else {
         let span = tcx.def_span(impl1_def_id);
         let guar = tcx.dcx().emit_err(GenericArgsOnOverriddenImpl { span });
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index bc7d4365eee..ae054a9eaeb 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -83,12 +83,11 @@ pub mod autoderef;
 mod bounds;
 mod check_unused;
 mod coherence;
-mod delegation;
-pub mod hir_ty_lowering;
-// FIXME: This module shouldn't be public.
-pub mod collect;
+mod collect;
 mod constrained_generic_params;
+mod delegation;
 mod errors;
+pub mod hir_ty_lowering;
 pub mod hir_wf_check;
 mod impl_wf_check;
 mod outlives;
@@ -104,7 +103,8 @@ use rustc_middle::ty::{self, Const, Ty, TyCtxt};
 use rustc_span::Span;
 use rustc_trait_selection::traits;
 
-use self::hir_ty_lowering::{FeedConstTy, HirTyLowerer};
+pub use crate::collect::suggest_impl_trait;
+use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer};
 
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
@@ -152,11 +152,14 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
     });
 
     if tcx.features().rustc_attrs() {
-        tcx.sess.time("outlives_dumping", || outlives::dump::inferred_outlives(tcx));
-        tcx.sess.time("variance_dumping", || variance::dump::variances(tcx));
-        collect::dump::opaque_hidden_types(tcx);
-        collect::dump::predicates_and_item_bounds(tcx);
-        collect::dump::def_parents(tcx);
+        tcx.sess.time("dumping_rustc_attr_data", || {
+            outlives::dump::inferred_outlives(tcx);
+            variance::dump::variances(tcx);
+            collect::dump::opaque_hidden_types(tcx);
+            collect::dump::predicates_and_item_bounds(tcx);
+            collect::dump::def_parents(tcx);
+            collect::dump::vtables(tcx);
+        });
     }
 
     // Make sure we evaluate all static and (non-associated) const items, even if unused.
diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
index c2377b4781c..036163b9f14 100644
--- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
@@ -24,7 +24,7 @@ pub(super) fn infer_predicates(
 
     // If new predicates were added then we need to re-calculate
     // all crates since there could be new implied predicates.
-    'outer: loop {
+    loop {
         let mut predicates_added = false;
 
         // Visit all the crates and infer predicates
@@ -90,7 +90,7 @@ pub(super) fn infer_predicates(
         }
 
         if !predicates_added {
-            break 'outer;
+            break;
         }
     }
 
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index 02cfb57b836..a7760326bb4 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -27,9 +27,6 @@ mod solve;
 
 pub(crate) mod dump;
 
-/// Code for transforming variances.
-mod xform;
-
 pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { variances_of, crate_variances, ..*providers };
 }
diff --git a/compiler/rustc_hir_analysis/src/variance/solve.rs b/compiler/rustc_hir_analysis/src/variance/solve.rs
index d0bdca86779..4106c1a5b63 100644
--- a/compiler/rustc_hir_analysis/src/variance/solve.rs
+++ b/compiler/rustc_hir_analysis/src/variance/solve.rs
@@ -12,8 +12,26 @@ use tracing::debug;
 use super::constraints::*;
 use super::terms::VarianceTerm::*;
 use super::terms::*;
-use super::xform::*;
 
+fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance {
+    // Greatest lower bound of the variance lattice as defined in The Paper:
+    //
+    //       *
+    //    -     +
+    //       o
+    match (v1, v2) {
+        (ty::Invariant, _) | (_, ty::Invariant) => ty::Invariant,
+
+        (ty::Covariant, ty::Contravariant) => ty::Invariant,
+        (ty::Contravariant, ty::Covariant) => ty::Invariant,
+
+        (ty::Covariant, ty::Covariant) => ty::Covariant,
+
+        (ty::Contravariant, ty::Contravariant) => ty::Contravariant,
+
+        (x, ty::Bivariant) | (ty::Bivariant, x) => x,
+    }
+}
 struct SolveContext<'a, 'tcx> {
     terms_cx: TermsContext<'a, 'tcx>,
     constraints: Vec<Constraint<'a>>,
diff --git a/compiler/rustc_hir_analysis/src/variance/xform.rs b/compiler/rustc_hir_analysis/src/variance/xform.rs
deleted file mode 100644
index 2e9964788e6..00000000000
--- a/compiler/rustc_hir_analysis/src/variance/xform.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-use rustc_middle::ty;
-
-pub(crate) fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance {
-    // Greatest lower bound of the variance lattice as
-    // defined in The Paper:
-    //
-    //       *
-    //    -     +
-    //       o
-    match (v1, v2) {
-        (ty::Invariant, _) | (_, ty::Invariant) => ty::Invariant,
-
-        (ty::Covariant, ty::Contravariant) => ty::Invariant,
-        (ty::Contravariant, ty::Covariant) => ty::Invariant,
-
-        (ty::Covariant, ty::Covariant) => ty::Covariant,
-
-        (ty::Contravariant, ty::Contravariant) => ty::Contravariant,
-
-        (x, ty::Bivariant) | (ty::Bivariant, x) => x,
-    }
-}