about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-07-26 08:26:17 +0000
committerbors <bors@rust-lang.org>2024-07-26 08:26:17 +0000
commit83d67685acb520fe68d5d5adde4b25fb725490de (patch)
treec9d069da3bff063adb089082f8703c2c4c993d83
parent6ef11b81c2c02c3c4b7556d1991a98572fe9af87 (diff)
parent97eade42f73f9ba081df3811e0ecfd2510e79aff (diff)
downloadrust-83d67685acb520fe68d5d5adde4b25fb725490de.tar.gz
rust-83d67685acb520fe68d5d5adde4b25fb725490de.zip
Auto merge of #128222 - tgross35:rollup-fk7qdo3, r=tgross35
Rollup of 7 pull requests

Successful merges:

 - #126575 (Make it crystal clear what lint `type_alias_bounds` actually signifies)
 - #127017 (Extend rules of dead code analysis for impls for adts to impls for types refer to adts)
 - #127523 (Migrate `dump-ice-to-disk` and `panic-abort-eh_frame` `run-make` tests to rmake)
 - #127557 (Add a label to point to the lacking macro name definition)
 - #127989 (Migrate `interdependent-c-libraries`, `compiler-rt-works-on-mingw` and `incr-foreign-head-span` `run-make` tests to rmake)
 - #128099 (migrate tests/run-make/extern-flag-disambiguates to rmake)
 - #128170 (Make Clone::clone a lang item)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_hir/src/lang_items.rs1
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl13
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs31
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs127
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs77
-rw-r--r--compiler/rustc_lint/messages.ftl19
-rw-r--r--compiler/rustc_lint/src/builtin.rs139
-rw-r--r--compiler/rustc_lint/src/lints.rs141
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs4
-rw-r--r--compiler/rustc_passes/src/dead.rs32
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs5
-rw-r--r--compiler/rustc_resolve/src/errors.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_type_ir/src/visit.rs4
-rw-r--r--library/core/src/clone.rs3
-rw-r--r--src/tools/compiletest/src/command-list.rs1
-rw-r--r--src/tools/run-make-support/src/external_deps/cc.rs23
-rw-r--r--src/tools/run-make-support/src/lib.rs2
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt6
-rw-r--r--tests/run-make/README.md5
-rw-r--r--tests/run-make/compiler-rt-works-on-mingw/Makefile9
-rw-r--r--tests/run-make/compiler-rt-works-on-mingw/rmake.rs15
-rw-r--r--tests/run-make/dump-ice-to-disk/Makefile10
-rw-r--r--tests/run-make/dump-ice-to-disk/check.sh64
-rw-r--r--tests/run-make/dump-ice-to-disk/lib.rs (renamed from tests/run-make/dump-ice-to-disk/src/lib.rs)0
-rw-r--r--tests/run-make/dump-ice-to-disk/rmake.rs81
-rw-r--r--tests/run-make/extern-flag-disambiguates/Makefile26
-rw-r--r--tests/run-make/extern-flag-disambiguates/rmake.rs30
-rw-r--r--tests/run-make/incr-foreign-head-span/Makefile21
-rw-r--r--tests/run-make/incr-foreign-head-span/rmake.rs25
-rw-r--r--tests/run-make/interdependent-c-libraries/Makefile15
-rw-r--r--tests/run-make/interdependent-c-libraries/rmake.rs21
-rw-r--r--tests/run-make/panic-abort-eh_frame/Makefile10
-rw-r--r--tests/run-make/panic-abort-eh_frame/rmake.rs24
-rw-r--r--tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs20
-rw-r--r--tests/ui/associated-inherent-types/type-alias-bounds.rs29
-rw-r--r--tests/ui/associated-inherent-types/type-alias-bounds.stderr16
-rw-r--r--tests/ui/associated-type-bounds/type-alias.stderr204
-rw-r--r--tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr63
-rw-r--r--tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs71
-rw-r--r--tests/ui/lint/dead-code/unused-impl-for-non-adts.rs45
-rw-r--r--tests/ui/lint/dead-code/unused-impl-for-non-adts.stderr20
-rw-r--r--tests/ui/macros/issue-118786.rs1
-rw-r--r--tests/ui/macros/issue-118786.stderr6
-rw-r--r--tests/ui/privacy/private-in-public-warn.rs4
-rw-r--r--tests/ui/privacy/private-in-public-warn.stderr34
-rw-r--r--tests/ui/resolve/issue-118295.rs6
-rw-r--r--tests/ui/resolve/issue-118295.stderr18
-rw-r--r--tests/ui/resolve/issue-55673.stderr2
-rw-r--r--tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr17
-rw-r--r--tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr36
-rw-r--r--tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr40
-rw-r--r--tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs26
-rw-r--r--tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs2
-rw-r--r--tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr15
-rw-r--r--tests/ui/type/type-alias-bounds.rs21
-rw-r--r--tests/ui/type/type-alias-bounds.stderr163
58 files changed, 1198 insertions, 657 deletions
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index 58cc0f62111..1821387e85f 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -162,6 +162,7 @@ language_item_table! {
     StructuralPeq,           sym::structural_peq,      structural_peq_trait,       Target::Trait,          GenericRequirement::None;
     Copy,                    sym::copy,                copy_trait,                 Target::Trait,          GenericRequirement::Exact(0);
     Clone,                   sym::clone,               clone_trait,                Target::Trait,          GenericRequirement::None;
+    CloneFn,                 sym::clone_fn,            clone_fn,                   Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
     Sync,                    sym::sync,                sync_trait,                 Target::Trait,          GenericRequirement::Exact(0);
     DiscriminantKind,        sym::discriminant_kind,   discriminant_kind_trait,    Target::Trait,          GenericRequirement::None;
     /// The associated item of the `DiscriminantKind` trait.
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index cc404daa51f..367f6e17e7f 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -1,4 +1,4 @@
-hir_analysis_ambiguous_assoc_item = ambiguous associated {$assoc_kind} `{$assoc_name}` in bounds of `{$ty_param_name}`
+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_lifetime_bound =
@@ -12,16 +12,21 @@ 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 `{$ty_param_name}`
+hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_name}` 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_other_sugg = `{$ty_param_name}` has the following associated {$assoc_kind}
+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 ->
+        [true] {""}
+        *[false] {" "}and renaming
+    } the associated {$assoc_kind}
 hir_analysis_assoc_item_not_found_similar_in_other_trait_sugg = change the associated {$assoc_kind} name to use `{$suggested_name}` from `{$trait_name}`
-hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg = and also change the associated {$assoc_kind} name
+hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg = ...and changing the associated {$assoc_kind} name
 hir_analysis_assoc_item_not_found_similar_sugg = there is an associated {$assoc_kind} with a similar name
 
 hir_analysis_assoc_kind_mismatch = expected {$expected}, found {$got}
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index c83788928a9..c364a561631 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -22,7 +22,7 @@ pub struct AmbiguousAssocItem<'a> {
     pub span: Span,
     pub assoc_kind: &'static str,
     pub assoc_name: Ident,
-    pub ty_param_name: &'a str,
+    pub qself: &'a str,
 }
 
 #[derive(Diagnostic)]
@@ -75,7 +75,7 @@ pub struct AssocItemNotFound<'a> {
     pub span: Span,
     pub assoc_name: Ident,
     pub assoc_kind: &'static str,
-    pub ty_param_name: &'a str,
+    pub qself: &'a str,
     #[subdiagnostic]
     pub label: Option<AssocItemNotFoundLabel<'a>>,
     #[subdiagnostic]
@@ -126,13 +126,32 @@ pub enum AssocItemNotFoundSugg<'a> {
         assoc_kind: &'static str,
         suggested_name: Symbol,
     },
-    #[suggestion(hir_analysis_assoc_item_not_found_other_sugg, code = "{suggested_name}")]
+    #[multipart_suggestion(
+        hir_analysis_assoc_item_not_found_similar_in_other_trait_qpath_sugg,
+        style = "verbose"
+    )]
+    SimilarInOtherTraitQPath {
+        #[suggestion_part(code = "<")]
+        lo: Span,
+        #[suggestion_part(code = " as {trait_ref}>")]
+        mi: Span,
+        #[suggestion_part(code = "{suggested_name}")]
+        hi: Option<Span>,
+        trait_ref: String,
+        suggested_name: Symbol,
+        identically_named: bool,
+        #[applicability]
+        applicability: Applicability,
+    },
+    #[suggestion(
+        hir_analysis_assoc_item_not_found_other_sugg,
+        code = "{suggested_name}",
+        applicability = "maybe-incorrect"
+    )]
     Other {
         #[primary_span]
         span: Span,
-        #[applicability]
-        applicability: Applicability,
-        ty_param_name: &'a str,
+        qself: &'a str,
         assoc_kind: &'static str,
         suggested_name: Symbol,
     },
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 6f9c481650b..214eb6b2f06 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -6,7 +6,6 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::bug;
-use rustc_middle::ty::print::PrintTraitRefExt as _;
 use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt};
 use rustc_span::symbol::Ident;
 use rustc_span::{ErrorGuaranteed, Span, Symbol};
@@ -16,9 +15,8 @@ use smallvec::SmallVec;
 
 use crate::bounds::Bounds;
 use crate::errors;
-use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};
-
-use super::RegionInferReason;
+use crate::hir_ty_lowering::HirTyLowerer;
+use crate::hir_ty_lowering::{AssocItemQSelf, OnlySelfBounds, PredicateFilter, RegionInferReason};
 
 impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     /// Add a `Sized` bound to the `bounds` if appropriate.
@@ -288,8 +286,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             // one that does define it.
             self.probe_single_bound_for_assoc_item(
                 || traits::supertraits(tcx, trait_ref),
-                trait_ref.skip_binder().print_only_trait_name(),
-                None,
+                AssocItemQSelf::Trait(trait_ref.def_id()),
                 assoc_kind,
                 constraint.ident,
                 path_span,
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 8ff6ced8b39..56f508a2d43 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -3,7 +3,7 @@ use crate::errors::{
     ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits,
 };
 use crate::fluent_generated as fluent;
-use crate::hir_ty_lowering::HirTyLowerer;
+use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer};
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_data_structures::sorted_map::SortedMap;
 use rustc_data_structures::unord::UnordMap;
@@ -11,9 +11,9 @@ use rustc_errors::MultiSpan;
 use rustc_errors::{
     codes::*, pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed,
 };
+use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::{self as hir, Node};
+use rustc_hir::def_id::DefId;
 use rustc_middle::bug;
 use rustc_middle::query::Key;
 use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
@@ -116,8 +116,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     pub(super) fn complain_about_assoc_item_not_found<I>(
         &self,
         all_candidates: impl Fn() -> I,
-        ty_param_name: &str,
-        ty_param_def_id: Option<LocalDefId>,
+        qself: AssocItemQSelf,
         assoc_kind: ty::AssocKind,
         assoc_name: Ident,
         span: Span,
@@ -139,7 +138,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             );
         }
 
-        let assoc_kind_str = super::assoc_kind_str(assoc_kind);
+        let assoc_kind_str = assoc_kind_str(assoc_kind);
+        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.
@@ -149,7 +149,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             span: if is_dummy { span } else { assoc_name.span },
             assoc_name,
             assoc_kind: assoc_kind_str,
-            ty_param_name,
+            qself: &qself_str,
             label: None,
             sugg: None,
         };
@@ -219,19 +219,28 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     suggested_name,
                     identically_named: suggested_name == assoc_name.name,
                 });
-                let hir = tcx.hir();
-                if let Some(def_id) = ty_param_def_id
-                    && let parent = hir.get_parent_item(tcx.local_def_id_to_hir_id(def_id))
-                    && let Some(generics) = hir.get_generics(parent.def_id)
+                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
+                    // inside an opaque type while we're interested in the overarching type alias (TAIT).
+                    // FIXME: However, for trait aliases, this incorrectly returns the enclosing module...
+                    && let item_def_id =
+                        tcx.hir().get_parent_item(tcx.local_def_id_to_hir_id(ty_param_def_id))
+                    // FIXME: ...which obviously won't have any generics.
+                    && let Some(generics) = tcx.hir().get_generics(item_def_id.def_id)
                 {
-                    if generics.bounds_for_param(def_id).flat_map(|pred| pred.bounds.iter()).any(
-                        |b| match b {
+                    // FIXME: Suggest adding supertrait bounds if we have a `Self` type param.
+                    // FIXME(trait_alias): Suggest adding `Self: Trait` to
+                    // `trait Alias = where Self::Proj:;` with `trait Trait { type Proj; }`.
+                    if generics
+                        .bounds_for_param(ty_param_def_id)
+                        .flat_map(|pred| pred.bounds.iter())
+                        .any(|b| match b {
                             hir::GenericBound::Trait(t, ..) => {
                                 t.trait_ref.trait_def_id() == Some(best_trait)
                             }
                             _ => false,
-                        },
-                    ) {
+                        })
+                    {
                         // The type param already has a bound for `trait_name`, we just need to
                         // change the associated item.
                         err.sugg = Some(errors::AssocItemNotFoundSugg::SimilarInOtherTrait {
@@ -242,48 +251,60 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         return self.dcx().emit_err(err);
                     }
 
-                    let mut err = self.dcx().create_err(err);
-                    if suggest_constraining_type_param(
-                        tcx,
-                        generics,
-                        &mut err,
-                        &ty_param_name,
-                        &trait_name,
-                        None,
-                        None,
-                    ) && suggested_name != assoc_name.name
+                    let trait_args = &ty::GenericArgs::identity_for_item(tcx, best_trait)[1..];
+                    let mut trait_ref = trait_name.clone();
+                    let applicability = if let [arg, args @ ..] = trait_args {
+                        use std::fmt::Write;
+                        write!(trait_ref, "</* {arg}").unwrap();
+                        args.iter().try_for_each(|arg| write!(trait_ref, ", {arg}")).unwrap();
+                        trait_ref += " */>";
+                        Applicability::HasPlaceholders
+                    } else {
+                        Applicability::MaybeIncorrect
+                    };
+
+                    let identically_named = suggested_name == assoc_name.name;
+
+                    if let DefKind::TyAlias = tcx.def_kind(item_def_id)
+                        && !tcx.type_alias_is_lazy(item_def_id)
                     {
-                        // 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,
-                            fluent::hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg,
+                        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),
+                            trait_ref,
+                            identically_named,
                             suggested_name,
-                            Applicability::MaybeIncorrect,
-                        );
+                            applicability,
+                        });
+                    } else {
+                        let mut err = self.dcx().create_err(err);
+                        if suggest_constraining_type_param(
+                            tcx, generics, &mut err, &qself_str, &trait_ref, None, None,
+                        ) && !identically_named
+                        {
+                            // 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,
+                                fluent::hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg,
+                                suggested_name,
+                                Applicability::MaybeIncorrect,
+                            );
+                        }
+                        return err.emit();
                     }
-                    return err.emit();
                 }
                 return self.dcx().emit_err(err);
             }
         }
 
         // If we still couldn't find any associated item, and only one associated item exists,
-        // suggests using it.
+        // suggest using it.
         if let [candidate_name] = all_candidate_names.as_slice() {
-            // This should still compile, except on `#![feature(associated_type_defaults)]`
-            // where it could suggests `type A = Self::A`, thus recursing infinitely.
-            let applicability =
-                if assoc_kind == ty::AssocKind::Type && tcx.features().associated_type_defaults {
-                    Applicability::Unspecified
-                } else {
-                    Applicability::MaybeIncorrect
-                };
-
             err.sugg = Some(errors::AssocItemNotFoundSugg::Other {
                 span: assoc_name.span,
-                applicability,
-                ty_param_name,
+                qself: &qself_str,
                 assoc_kind: assoc_kind_str,
                 suggested_name: *candidate_name,
             });
@@ -349,10 +370,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         self.dcx().emit_err(errors::AssocKindMismatch {
             span,
-            expected: super::assoc_kind_str(expected),
-            got: super::assoc_kind_str(got),
+            expected: assoc_kind_str(expected),
+            got: assoc_kind_str(got),
             expected_because_label,
-            assoc_kind: super::assoc_kind_str(assoc_item.kind),
+            assoc_kind: assoc_kind_str(assoc_item.kind),
             def_span: tcx.def_span(assoc_item.def_id),
             bound_on_assoc_const_label,
             wrap_in_braces_sugg,
@@ -746,7 +767,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) {
             let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.trait_ref.hir_ref_id));
             in_expr_or_pat = match grandparent {
-                Node::Expr(_) | Node::Pat(_) => true,
+                hir::Node::Expr(_) | hir::Node::Pat(_) => true,
                 _ => false,
             };
             match bound.trait_ref.path.segments {
@@ -1612,3 +1633,11 @@ fn generics_args_err_extend<'a>(
         _ => {}
     }
 }
+
+pub(super) fn assoc_kind_str(kind: ty::AssocKind) -> &'static str {
+    match kind {
+        ty::AssocKind::Fn => "function",
+        ty::AssocKind::Const => "constant",
+        ty::AssocKind::Type => "type",
+    }
+}
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 d6eb1a66902..ce298641e60 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -55,7 +55,6 @@ use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::wf::object_region_bounds;
 use rustc_trait_selection::traits::{self, ObligationCtxt};
 
-use std::fmt::Display;
 use std::slice;
 
 /// A path segment that is semantically allowed to have generic arguments.
@@ -193,6 +192,25 @@ pub trait HirTyLowerer<'tcx> {
     }
 }
 
+/// The "qualified self" of an associated item path.
+///
+/// For diagnostic purposes only.
+enum AssocItemQSelf {
+    Trait(DefId),
+    TyParam(LocalDefId, Span),
+    SelfTyAlias,
+}
+
+impl AssocItemQSelf {
+    fn to_string(&self, tcx: TyCtxt<'_>) -> String {
+        match *self {
+            Self::Trait(def_id) => tcx.def_path_str(def_id),
+            Self::TyParam(def_id, _) => tcx.hir().ty_param_name(def_id).to_string(),
+            Self::SelfTyAlias => kw::SelfUpper.to_string(),
+        }
+    }
+}
+
 /// New-typed boolean indicating whether explicit late-bound lifetimes
 /// are present in a set of generic arguments.
 ///
@@ -802,6 +820,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     fn probe_single_ty_param_bound_for_assoc_ty(
         &self,
         ty_param_def_id: LocalDefId,
+        ty_param_span: Span,
         assoc_name: Ident,
         span: Span,
     ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
@@ -811,19 +830,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_name).predicates;
         debug!("predicates={:#?}", predicates);
 
-        let param_name = tcx.hir().ty_param_name(ty_param_def_id);
         self.probe_single_bound_for_assoc_item(
             || {
-                traits::transitive_bounds_that_define_assoc_item(
-                    tcx,
-                    predicates
-                        .iter()
-                        .filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref))),
-                    assoc_name,
-                )
+                let trait_refs = predicates
+                    .iter()
+                    .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)
             },
-            param_name,
-            Some(ty_param_def_id),
+            AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span),
             ty::AssocKind::Type,
             assoc_name,
             span,
@@ -835,12 +849,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     ///
     /// 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.
-    #[instrument(level = "debug", skip(self, all_candidates, ty_param_name, constraint), ret)]
+    #[instrument(level = "debug", skip(self, all_candidates, qself, constraint), ret)]
     fn probe_single_bound_for_assoc_item<I>(
         &self,
         all_candidates: impl Fn() -> I,
-        ty_param_name: impl Display,
-        ty_param_def_id: Option<LocalDefId>,
+        qself: AssocItemQSelf,
         assoc_kind: ty::AssocKind,
         assoc_name: Ident,
         span: Span,
@@ -858,8 +871,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let Some(bound) = matching_candidates.next() else {
             let reported = self.complain_about_assoc_item_not_found(
                 all_candidates,
-                &ty_param_name.to_string(),
-                ty_param_def_id,
+                qself,
                 assoc_kind,
                 assoc_name,
                 span,
@@ -872,13 +884,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         if let Some(bound2) = matching_candidates.next() {
             debug!(?bound2);
 
-            let assoc_kind_str = assoc_kind_str(assoc_kind);
-            let ty_param_name = &ty_param_name.to_string();
+            let assoc_kind_str = errors::assoc_kind_str(assoc_kind);
+            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,
-                ty_param_name,
+                qself: &qself_str,
             });
             // Provide a more specific error code index entry for equality bindings.
             err.code(
@@ -929,7 +941,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         err.span_suggestion_verbose(
                             span.with_hi(assoc_name.span.lo()),
                             "use fully-qualified syntax to disambiguate",
-                            format!("<{ty_param_name} as {}>::", bound.print_only_trait_path()),
+                            format!("<{qself_str} as {}>::", bound.print_only_trait_path()),
                             Applicability::MaybeIncorrect,
                         );
                     }
@@ -943,7 +955,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             if !where_bounds.is_empty() {
                 err.help(format!(
                     "consider introducing a new type parameter `T` and adding `where` constraints:\
-                     \n    where\n        T: {ty_param_name},\n{}",
+                     \n    where\n        T: {qself_str},\n{}",
                     where_bounds.join(",\n"),
                 ));
             }
@@ -997,11 +1009,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let tcx = self.tcx();
 
         let assoc_ident = assoc_segment.ident;
-        let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind {
-            path.res
-        } else {
-            Res::Err
-        };
 
         // Check if we have an enum variant or an inherent associated type.
         let mut variant_resolution = None;
@@ -1038,6 +1045,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             }
         }
 
+        let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind {
+            path.res
+        } else {
+            Res::Err
+        };
+
         // Find the type of the associated item, and the trait where the associated
         // item is declared.
         let bound = match (&qself_ty.kind(), qself_res) {
@@ -1056,8 +1069,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                             ty::Binder::dummy(trait_ref.instantiate_identity()),
                         )
                     },
-                    kw::SelfUpper,
-                    None,
+                    AssocItemQSelf::SelfTyAlias,
                     ty::AssocKind::Type,
                     assoc_ident,
                     span,
@@ -1069,6 +1081,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
             ) => self.probe_single_ty_param_bound_for_assoc_ty(
                 param_did.expect_local(),
+                qself.span,
                 assoc_ident,
                 span,
             )?,
@@ -2522,11 +2535,3 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         Some(r)
     }
 }
-
-fn assoc_kind_str(kind: ty::AssocKind) -> &'static str {
-    match kind {
-        ty::AssocKind::Fn => "function",
-        ty::AssocKind::Const => "constant",
-        ty::AssocKind::Type => "type",
-    }
-}
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index a87b3c2c135..987dbf6db63 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -144,13 +144,18 @@ lint_builtin_special_module_name_used_main = found module declaration for main.r
 
 lint_builtin_trivial_bounds = {$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters
 
-lint_builtin_type_alias_bounds_help = use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
-
-lint_builtin_type_alias_generic_bounds = bounds on generic parameters are not enforced in type aliases
-    .suggestion = the bound will not be checked when the type alias is used, and should be removed
-
-lint_builtin_type_alias_where_clause = where clauses are not enforced in type aliases
-    .suggestion = the clause will not be checked when the type alias is used, and should be removed
+lint_builtin_type_alias_bounds_enable_feat_help = add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
+lint_builtin_type_alias_bounds_label = will not be checked at usage sites of the type alias
+lint_builtin_type_alias_bounds_limitation_note = this is a known limitation of the type checker that may be lifted in a future edition.
+    see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+lint_builtin_type_alias_bounds_param_bounds = bounds on generic parameters in type aliases are not enforced
+    .suggestion = remove {$count ->
+        [one] this bound
+        *[other] these bounds
+    }
+lint_builtin_type_alias_bounds_qualify_assoc_tys_sugg = fully qualify this associated type
+lint_builtin_type_alias_bounds_where_clause = where clauses on type aliases are not enforced
+    .suggestion = remove this where clause
 
 lint_builtin_unpermitted_type_init_label = this code causes undefined behavior when executed
 lint_builtin_unpermitted_type_init_label_suggestion = help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 9ebada0fff3..ab0b47d48e5 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -31,12 +31,11 @@ use crate::{
         BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures, BuiltinKeywordIdents,
         BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc,
         BuiltinMutablesTransmutes, BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns,
-        BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasGenericBounds,
-        BuiltinTypeAliasGenericBoundsSuggestion, BuiltinTypeAliasWhereClause,
+        BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasBounds,
         BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit,
         BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnsafe,
         BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub,
-        BuiltinWhileTrue, InvalidAsmLabel, SuggestChangingAssocTypes,
+        BuiltinWhileTrue, InvalidAsmLabel,
     },
     EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext,
 };
@@ -1391,64 +1390,80 @@ declare_lint! {
     ///
     /// ### Explanation
     ///
-    /// The trait bounds in a type alias are currently ignored, and should not
-    /// be included to avoid confusion. This was previously allowed
-    /// unintentionally; this may become a hard error in the future.
+    /// Trait and lifetime bounds on generic parameters and in where clauses of
+    /// type aliases are not checked at usage sites of the type alias. Moreover,
+    /// they are not thoroughly checked for correctness at their definition site
+    /// either similar to the aliased type.
+    ///
+    /// This is a known limitation of the type checker that may be lifted in a
+    /// future edition. Permitting such bounds in light of this was unintentional.
+    ///
+    /// While these bounds may have secondary effects such as enabling the use of
+    /// "shorthand" associated type paths[^1] and affecting the default trait
+    /// object lifetime[^2] of trait object types passed to the type alias, this
+    /// should not have been allowed until the aforementioned restrictions of the
+    /// type checker have been lifted.
+    ///
+    /// Using such bounds is highly discouraged as they are actively misleading.
+    ///
+    /// [^1]: I.e., paths of the form `T::Assoc` where `T` is a type parameter
+    /// bounded by trait `Trait` which defines an associated type called `Assoc`
+    /// as opposed to a fully qualified path of the form `<T as Trait>::Assoc`.
+    /// [^2]: <https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes>
     TYPE_ALIAS_BOUNDS,
     Warn,
     "bounds in type aliases are not enforced"
 }
 
-declare_lint_pass!(
-    /// Lint for trait and lifetime bounds in type aliases being mostly ignored.
-    /// They are relevant when using associated types, but otherwise neither checked
-    /// at definition site nor enforced at use site.
-    TypeAliasBounds => [TYPE_ALIAS_BOUNDS]
-);
+declare_lint_pass!(TypeAliasBounds => [TYPE_ALIAS_BOUNDS]);
 
 impl TypeAliasBounds {
-    pub(crate) fn is_type_variable_assoc(qpath: &hir::QPath<'_>) -> bool {
-        match *qpath {
-            hir::QPath::TypeRelative(ty, _) => {
-                // If this is a type variable, we found a `T::Assoc`.
-                match ty.kind {
-                    hir::TyKind::Path(hir::QPath::Resolved(None, path)) => {
-                        matches!(path.res, Res::Def(DefKind::TyParam, _))
-                    }
-                    _ => false,
-                }
-            }
-            hir::QPath::Resolved(..) | hir::QPath::LangItem(..) => false,
+    pub(crate) fn affects_object_lifetime_defaults(pred: &hir::WherePredicate<'_>) -> bool {
+        // Bounds of the form `T: 'a` with `T` type param affect object lifetime defaults.
+        if let hir::WherePredicate::BoundPredicate(pred) = pred
+            && pred.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Outlives(_)))
+            && pred.bound_generic_params.is_empty() // indeed, even if absent from the RHS
+            && pred.bounded_ty.as_generic_param().is_some()
+        {
+            return true;
         }
+        false
     }
 }
 
 impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
-        let hir::ItemKind::TyAlias(hir_ty, type_alias_generics) = &item.kind else { return };
+        let hir::ItemKind::TyAlias(hir_ty, generics) = item.kind else { return };
 
-        // Bounds of lazy type aliases and TAITs are respected.
-        if cx.tcx.type_alias_is_lazy(item.owner_id) {
+        // There must not be a where clause.
+        if generics.predicates.is_empty() {
             return;
         }
 
-        let ty = cx.tcx.type_of(item.owner_id).skip_binder();
-        if ty.has_inherent_projections() {
-            // Bounds of type aliases that contain opaque types or inherent projections are
-            // respected. E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`, `type X =
-            // Type::Inherent;`.
+        // Bounds of lazy type aliases and TAITs are respected.
+        if cx.tcx.type_alias_is_lazy(item.owner_id) {
             return;
         }
 
-        // There must not be a where clause
-        if type_alias_generics.predicates.is_empty() {
+        // FIXME(generic_const_exprs): Revisit this before stabilization.
+        // See also `tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs`.
+        let ty = cx.tcx.type_of(item.owner_id).instantiate_identity();
+        if ty.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION)
+            && cx.tcx.features().generic_const_exprs
+        {
             return;
         }
 
+        // NOTE(inherent_associated_types): While we currently do take some bounds in type
+        // aliases into consideration during IAT *selection*, we don't perform full use+def
+        // site wfchecking for such type aliases. Therefore TAB should still trigger.
+        // See also `tests/ui/associated-inherent-types/type-alias-bounds.rs`.
+
         let mut where_spans = Vec::new();
         let mut inline_spans = Vec::new();
         let mut inline_sugg = Vec::new();
-        for p in type_alias_generics.predicates {
+
+        for p in generics.predicates {
             let span = p.span();
             if p.in_where_clause() {
                 where_spans.push(span);
@@ -1460,37 +1475,57 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
             }
         }
 
-        let mut suggested_changing_assoc_types = false;
-        if !where_spans.is_empty() {
-            let sub = (!suggested_changing_assoc_types).then(|| {
-                suggested_changing_assoc_types = true;
-                SuggestChangingAssocTypes { ty: hir_ty }
-            });
+        let mut ty = Some(hir_ty);
+        let enable_feat_help = cx.tcx.sess.is_nightly_build();
+
+        if let [.., label_sp] = *where_spans {
             cx.emit_span_lint(
                 TYPE_ALIAS_BOUNDS,
                 where_spans,
-                BuiltinTypeAliasWhereClause {
-                    suggestion: type_alias_generics.where_clause_span,
-                    sub,
+                BuiltinTypeAliasBounds {
+                    in_where_clause: true,
+                    label: label_sp,
+                    enable_feat_help,
+                    suggestions: vec![(generics.where_clause_span, String::new())],
+                    preds: generics.predicates,
+                    ty: ty.take(),
                 },
             );
         }
-
-        if !inline_spans.is_empty() {
-            let suggestion = BuiltinTypeAliasGenericBoundsSuggestion { suggestions: inline_sugg };
-            let sub = (!suggested_changing_assoc_types).then(|| {
-                suggested_changing_assoc_types = true;
-                SuggestChangingAssocTypes { ty: hir_ty }
-            });
+        if let [.., label_sp] = *inline_spans {
             cx.emit_span_lint(
                 TYPE_ALIAS_BOUNDS,
                 inline_spans,
-                BuiltinTypeAliasGenericBounds { suggestion, sub },
+                BuiltinTypeAliasBounds {
+                    in_where_clause: false,
+                    label: label_sp,
+                    enable_feat_help,
+                    suggestions: inline_sugg,
+                    preds: generics.predicates,
+                    ty,
+                },
             );
         }
     }
 }
 
+pub(crate) struct ShorthandAssocTyCollector {
+    pub(crate) qselves: Vec<Span>,
+}
+
+impl hir::intravisit::Visitor<'_> for ShorthandAssocTyCollector {
+    fn visit_qpath(&mut self, qpath: &hir::QPath<'_>, id: hir::HirId, _: Span) {
+        // Look for "type-parameter shorthand-associated-types". I.e., paths of the
+        // form `T::Assoc` with `T` type param. These are reliant on trait bounds.
+        if let hir::QPath::TypeRelative(qself, _) = qpath
+            && qself.as_generic_param().is_some()
+        {
+            self.qselves.push(qself.span);
+        }
+        hir::intravisit::walk_qpath(self, qpath, id)
+    }
+}
+
 declare_lint! {
     /// The `trivial_bounds` lint detects trait bounds that don't depend on
     /// any type parameters.
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 1f0954c6e9f..b669a3c6288 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -2,14 +2,16 @@
 #![allow(rustc::untranslatable_diagnostic)]
 use std::num::NonZero;
 
-use crate::errors::RequestedLevel;
+use crate::builtin::{InitError, ShorthandAssocTyCollector, TypeAliasBounds};
+use crate::errors::{OverruledAttributeSub, RequestedLevel};
 use crate::fluent_generated as fluent;
+use crate::LateContext;
 use rustc_errors::{
     codes::*, Applicability, Diag, DiagArgValue, DiagMessage, DiagStyledString,
     ElidedLifetimeInPathSubdiag, EmissionGuarantee, LintDiagnostic, MultiSpan, SubdiagMessageOp,
     Subdiagnostic, SuggestionStyle,
 };
-use rustc_hir::{def::Namespace, def_id::DefId};
+use rustc_hir::{self as hir, def::Namespace, def_id::DefId};
 use rustc_macros::{LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::{
     inhabitedness::InhabitedPredicate, Clause, PolyExistentialTraitRef, Ty, TyCtxt,
@@ -22,10 +24,6 @@ use rustc_span::{
     Span, Symbol,
 };
 
-use crate::{
-    builtin::InitError, builtin::TypeAliasBounds, errors::OverruledAttributeSub, LateContext,
-};
-
 // array_into_iter.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_shadowed_into_iter)]
@@ -263,62 +261,6 @@ pub struct BuiltinUnreachablePub<'a> {
     pub help: Option<()>,
 }
 
-pub struct SuggestChangingAssocTypes<'a, 'b> {
-    pub ty: &'a rustc_hir::Ty<'b>,
-}
-
-impl<'a, 'b> Subdiagnostic for SuggestChangingAssocTypes<'a, 'b> {
-    fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
-        self,
-        diag: &mut Diag<'_, G>,
-        _f: &F,
-    ) {
-        // Access to associates types should use `<T as Bound>::Assoc`, which does not need a
-        // bound. Let's see if this type does that.
-
-        // We use a HIR visitor to walk the type.
-        use rustc_hir::intravisit::{self, Visitor};
-        struct WalkAssocTypes<'a, 'b, G: EmissionGuarantee> {
-            err: &'a mut Diag<'b, G>,
-        }
-        impl<'a, 'b, G: EmissionGuarantee> Visitor<'_> for WalkAssocTypes<'a, 'b, G> {
-            fn visit_qpath(
-                &mut self,
-                qpath: &rustc_hir::QPath<'_>,
-                id: rustc_hir::HirId,
-                span: Span,
-            ) {
-                if TypeAliasBounds::is_type_variable_assoc(qpath) {
-                    self.err.span_help(span, fluent::lint_builtin_type_alias_bounds_help);
-                }
-                intravisit::walk_qpath(self, qpath, id)
-            }
-        }
-
-        // Let's go for a walk!
-        let mut visitor = WalkAssocTypes { err: diag };
-        visitor.visit_ty(self.ty);
-    }
-}
-
-#[derive(LintDiagnostic)]
-#[diag(lint_builtin_type_alias_where_clause)]
-pub struct BuiltinTypeAliasWhereClause<'a, 'b> {
-    #[suggestion(code = "", applicability = "machine-applicable")]
-    pub suggestion: Span,
-    #[subdiagnostic]
-    pub sub: Option<SuggestChangingAssocTypes<'a, 'b>>,
-}
-
-#[derive(LintDiagnostic)]
-#[diag(lint_builtin_type_alias_generic_bounds)]
-pub struct BuiltinTypeAliasGenericBounds<'a, 'b> {
-    #[subdiagnostic]
-    pub suggestion: BuiltinTypeAliasGenericBoundsSuggestion,
-    #[subdiagnostic]
-    pub sub: Option<SuggestChangingAssocTypes<'a, 'b>>,
-}
-
 #[derive(LintDiagnostic)]
 #[diag(lint_macro_expr_fragment_specifier_2024_migration)]
 pub struct MacroExprFragment2024 {
@@ -326,21 +268,72 @@ pub struct MacroExprFragment2024 {
     pub suggestion: Span,
 }
 
-pub struct BuiltinTypeAliasGenericBoundsSuggestion {
+pub struct BuiltinTypeAliasBounds<'a, 'hir> {
+    pub in_where_clause: bool,
+    pub label: Span,
+    pub enable_feat_help: bool,
     pub suggestions: Vec<(Span, String)>,
+    pub preds: &'hir [hir::WherePredicate<'hir>],
+    pub ty: Option<&'a hir::Ty<'hir>>,
 }
 
-impl Subdiagnostic for BuiltinTypeAliasGenericBoundsSuggestion {
-    fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
-        self,
-        diag: &mut Diag<'_, G>,
-        _f: &F,
-    ) {
-        diag.multipart_suggestion(
-            fluent::lint_suggestion,
-            self.suggestions,
-            Applicability::MachineApplicable,
-        );
+impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_, '_> {
+    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
+        diag.primary_message(if self.in_where_clause {
+            fluent::lint_builtin_type_alias_bounds_where_clause
+        } else {
+            fluent::lint_builtin_type_alias_bounds_param_bounds
+        });
+        diag.span_label(self.label, fluent::lint_builtin_type_alias_bounds_label);
+        diag.note(fluent::lint_builtin_type_alias_bounds_limitation_note);
+        if self.enable_feat_help {
+            diag.help(fluent::lint_builtin_type_alias_bounds_enable_feat_help);
+        }
+
+        // We perform the walk in here instead of in `<TypeAliasBounds as LateLintPass>` to
+        // avoid doing throwaway work in case the lint ends up getting suppressed.
+        let mut collector = ShorthandAssocTyCollector { qselves: Vec::new() };
+        if let Some(ty) = self.ty {
+            hir::intravisit::Visitor::visit_ty(&mut collector, ty);
+        }
+
+        let affect_object_lifetime_defaults = self
+            .preds
+            .iter()
+            .filter(|pred| pred.in_where_clause() == self.in_where_clause)
+            .any(|pred| TypeAliasBounds::affects_object_lifetime_defaults(pred));
+
+        // If there are any shorthand assoc tys, then the bounds can't be removed automatically.
+        // The user first needs to fully qualify the assoc tys.
+        let applicability = if !collector.qselves.is_empty() || affect_object_lifetime_defaults {
+            Applicability::MaybeIncorrect
+        } else {
+            Applicability::MachineApplicable
+        };
+
+        diag.arg("count", self.suggestions.len());
+        diag.multipart_suggestion(fluent::lint_suggestion, self.suggestions, applicability);
+
+        // Suggest fully qualifying paths of the form `T::Assoc` with `T` type param via
+        // `<T as /* Trait */>::Assoc` to remove their reliance on any type param bounds.
+        //
+        // Instead of attempting to figure out the necessary trait ref, just use a
+        // placeholder. Since we don't record type-dependent resolutions for non-body
+        // items like type aliases, we can't simply deduce the corresp. trait from
+        // the HIR path alone without rerunning parts of HIR ty lowering here
+        // (namely `probe_single_ty_param_bound_for_assoc_ty`) which is infeasible.
+        //
+        // (We could employ some simple heuristics but that's likely not worth it).
+        for qself in collector.qselves {
+            diag.multipart_suggestion(
+                fluent::lint_builtin_type_alias_bounds_qualify_assoc_tys_sugg,
+                vec![
+                    (qself.shrink_to_lo(), "<".into()),
+                    (qself.shrink_to_hi(), " as /* Trait */>".into()),
+                ],
+                Applicability::HasPlaceholders,
+            );
+        }
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index 8209e5e2711..58fdc2d9e45 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -3,6 +3,7 @@
 use crate::simplify::simplify_duplicate_switch_targets;
 use crate::take_array;
 use rustc_ast::attr;
+use rustc_hir::LangItem;
 use rustc_middle::bug;
 use rustc_middle::mir::*;
 use rustc_middle::ty::layout;
@@ -271,8 +272,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
             return;
         }
 
-        let trait_def_id = self.tcx.trait_of_item(fn_def_id);
-        if trait_def_id.is_none() || trait_def_id != self.tcx.lang_items().clone_trait() {
+        if !self.tcx.is_lang_item(fn_def_id, LangItem::CloneFn) {
             return;
         }
 
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 55514883cb1..239bc8e7acc 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -54,7 +54,24 @@ impl Publicness {
     }
 }
 
-fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: DefId) -> bool {
+fn adt_of<'tcx>(ty: &hir::Ty<'tcx>) -> Option<(LocalDefId, DefKind)> {
+    match ty.kind {
+        TyKind::Path(hir::QPath::Resolved(_, path)) => {
+            if let Res::Def(def_kind, def_id) = path.res
+                && let Some(local_def_id) = def_id.as_local()
+            {
+                Some((local_def_id, def_kind))
+            } else {
+                None
+            }
+        }
+        TyKind::Slice(ty) | TyKind::Array(ty, _) => adt_of(ty),
+        TyKind::Ptr(ty) | TyKind::Ref(_, ty) => adt_of(ty.ty),
+        _ => None,
+    }
+}
+
+fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: LocalDefId) -> bool {
     // treat PhantomData and positional ZST as public,
     // we don't want to lint types which only have them,
     // cause it's a common way to use such types to check things like well-formedness
@@ -79,10 +96,7 @@ fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: DefId) -> bool {
 /// for enum and union, just check they are public,
 /// and doesn't solve types like &T for now, just skip them
 fn ty_ref_to_pub_struct(tcx: TyCtxt<'_>, ty: &hir::Ty<'_>) -> Publicness {
-    if let TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
-        && let Res::Def(def_kind, def_id) = path.res
-        && def_id.is_local()
-    {
+    if let Some((def_id, def_kind)) = adt_of(ty) {
         return match def_kind {
             DefKind::Enum | DefKind::Union => {
                 let ty_is_public = tcx.visibility(def_id).is_public();
@@ -565,10 +579,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
     }
 
     fn impl_item_with_used_self(&mut self, impl_id: hir::ItemId, impl_item_id: LocalDefId) -> bool {
-        if let TyKind::Path(hir::QPath::Resolved(_, path)) =
-            self.tcx.hir().item(impl_id).expect_impl().self_ty.kind
-            && let Res::Def(def_kind, def_id) = path.res
-            && let Some(local_def_id) = def_id.as_local()
+        if let Some((local_def_id, def_kind)) =
+            adt_of(self.tcx.hir().item(impl_id).expect_impl().self_ty)
             && matches!(def_kind, DefKind::Struct | DefKind::Enum | DefKind::Union)
         {
             if let Some(trait_item_id) = self.tcx.associated_item(impl_item_id).trait_item_def_id
@@ -915,7 +927,7 @@ fn create_and_seed_worklist(
                     match tcx.def_kind(id) {
                         DefKind::Impl { .. } => false,
                         DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn => !matches!(tcx.associated_item(id).container, AssocItemContainer::ImplContainer),
-                        DefKind::Struct => struct_all_fields_are_public(tcx, id.to_def_id()) || has_allow_dead_code_or_lang_attr(tcx, id).is_some(),
+                        DefKind::Struct => struct_all_fields_are_public(tcx, id) || has_allow_dead_code_or_lang_attr(tcx, id).is_some(),
                         _ => true
                     })
                 .map(|id| (id, ComesFromAllowExpect::No))
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 046ae5fc593..df80f4df5b9 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1448,7 +1448,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         );
 
         if macro_kind == MacroKind::Bang && ident.name == sym::macro_rules {
-            err.subdiagnostic(MaybeMissingMacroRulesName { span: ident.span });
+            let label_span = ident.span.shrink_to_hi();
+            let mut spans = MultiSpan::from_span(label_span);
+            spans.push_span_label(label_span, "put a macro name here");
+            err.subdiagnostic(MaybeMissingMacroRulesName { spans: spans });
             return;
         }
 
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index 0a68231c6fe..698147765b3 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -669,7 +669,7 @@ pub(crate) struct MacroSuggMovePosition {
 #[note(resolve_missing_macro_rules_name)]
 pub(crate) struct MaybeMissingMacroRulesName {
     #[primary_span]
-    pub(crate) span: Span,
+    pub(crate) spans: MultiSpan,
 }
 
 #[derive(Subdiagnostic)]
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 2b30ca8a894..6d58c4877cb 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -557,6 +557,7 @@ symbols! {
         clobber_abi,
         clone,
         clone_closures,
+        clone_fn,
         clone_from,
         closure,
         closure_lifetime_binder,
diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs
index 6ec38b78fc2..d5e114b2175 100644
--- a/compiler/rustc_type_ir/src/visit.rs
+++ b/compiler/rustc_type_ir/src/visit.rs
@@ -241,10 +241,6 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
         self.has_type_flags(TypeFlags::HAS_ALIAS)
     }
 
-    fn has_inherent_projections(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_TY_INHERENT)
-    }
-
     fn has_opaque_types(&self) -> bool {
         self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
     }
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index 939b2be6dfa..76a89eaaff8 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -160,6 +160,9 @@ pub trait Clone: Sized {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[must_use = "cloning is often expensive and is not expected to have side effects"]
+    // Clone::clone is special because the compiler generates MIR to implement it for some types.
+    // See InstanceKind::CloneShim.
+    #[cfg_attr(not(bootstrap), lang = "clone_fn")]
     fn clone(&self) -> Self;
 
     /// Performs copy-assignment from `source`.
diff --git a/src/tools/compiletest/src/command-list.rs b/src/tools/compiletest/src/command-list.rs
index 6735e9faa7a..c356f4266f0 100644
--- a/src/tools/compiletest/src/command-list.rs
+++ b/src/tools/compiletest/src/command-list.rs
@@ -201,6 +201,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "only-wasm32-wasip1",
     "only-watchos",
     "only-windows",
+    "only-windows-gnu",
     "only-x86",
     "only-x86_64",
     "only-x86_64-fortanix-unknown-sgx",
diff --git a/src/tools/run-make-support/src/external_deps/cc.rs b/src/tools/run-make-support/src/external_deps/cc.rs
index 840bfa0d2b4..19a89705acc 100644
--- a/src/tools/run-make-support/src/external_deps/cc.rs
+++ b/src/tools/run-make-support/src/external_deps/cc.rs
@@ -15,6 +15,13 @@ pub fn cc() -> Cc {
     Cc::new()
 }
 
+/// Construct a new platform-specific CXX compiler invocation.
+/// CXX_DEFAULT_FLAGS is passed from compiletest.
+#[track_caller]
+pub fn cxx() -> Cc {
+    Cc::new_cxx()
+}
+
 /// A platform-specific C compiler invocation builder. The specific C compiler used is
 /// passed down from compiletest.
 #[derive(Debug)]
@@ -44,6 +51,22 @@ impl Cc {
         Self { cmd }
     }
 
+    /// Construct a new platform-specific CXX compiler invocation.
+    /// CXX_DEFAULT_FLAGS is passed from compiletest.
+    #[track_caller]
+    pub fn new_cxx() -> Self {
+        let compiler = env_var("CXX");
+
+        let mut cmd = Command::new(compiler);
+
+        let default_cflags = env_var("CXX_DEFAULT_FLAGS");
+        for flag in default_cflags.split(char::is_whitespace) {
+            cmd.arg(flag);
+        }
+
+        Self { cmd }
+    }
+
     /// Specify path of the input file.
     pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
         self.cmd.arg(path.as_ref());
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index a4bb9056346..085120764b4 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -44,7 +44,7 @@ pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rust
 
 // These rely on external dependencies.
 pub use c_build::{build_native_dynamic_lib, build_native_static_lib};
-pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc};
+pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc};
 pub use clang::{clang, Clang};
 pub use htmldocck::htmldocck;
 pub use llvm::{
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 36f7f68ef7b..fa340a02213 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -2,7 +2,6 @@ run-make/branch-protection-check-IBT/Makefile
 run-make/c-unwind-abi-catch-lib-panic/Makefile
 run-make/cat-and-grep-sanity-check/Makefile
 run-make/cdylib-dylib-linkage/Makefile
-run-make/compiler-rt-works-on-mingw/Makefile
 run-make/cross-lang-lto-clang/Makefile
 run-make/cross-lang-lto-pgo-smoketest/Makefile
 run-make/cross-lang-lto-upstream-rlibs/Makefile
@@ -10,18 +9,14 @@ run-make/cross-lang-lto/Makefile
 run-make/dep-info-doesnt-run-much/Makefile
 run-make/dep-info-spaces/Makefile
 run-make/dep-info/Makefile
-run-make/dump-ice-to-disk/Makefile
 run-make/emit-to-stdout/Makefile
 run-make/export-executable-symbols/Makefile
-run-make/extern-flag-disambiguates/Makefile
 run-make/extern-fn-reachable/Makefile
 run-make/fmt-write-bloat/Makefile
 run-make/foreign-double-unwind/Makefile
 run-make/foreign-exceptions/Makefile
 run-make/foreign-rust-exceptions/Makefile
 run-make/incr-add-rust-src-component/Makefile
-run-make/incr-foreign-head-span/Makefile
-run-make/interdependent-c-libraries/Makefile
 run-make/issue-35164/Makefile
 run-make/issue-36710/Makefile
 run-make/issue-47551/Makefile
@@ -42,7 +37,6 @@ run-make/native-link-modifier-bundle/Makefile
 run-make/native-link-modifier-whole-archive/Makefile
 run-make/no-alloc-shim/Makefile
 run-make/no-builtins-attribute/Makefile
-run-make/panic-abort-eh_frame/Makefile
 run-make/pdb-buildinfo-cl-cmd/Makefile
 run-make/pgo-gen-lto/Makefile
 run-make/pgo-indirect-call-promotion/Makefile
diff --git a/tests/run-make/README.md b/tests/run-make/README.md
index a6c1b4b7db7..40359903473 100644
--- a/tests/run-make/README.md
+++ b/tests/run-make/README.md
@@ -41,3 +41,8 @@ The setup for the `rmake.rs` version is a 3-stage process:
 
 [`run_make_support`]: ../../src/tools/run-make-support
 [extern_prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude
+
+### Formatting
+
+Note that files under `tests/` are not formatted by `./x fmt`,
+use `rustfmt tests/path/to/file.rs` to format a specific file if desired.
diff --git a/tests/run-make/compiler-rt-works-on-mingw/Makefile b/tests/run-make/compiler-rt-works-on-mingw/Makefile
deleted file mode 100644
index 74917570a01..00000000000
--- a/tests/run-make/compiler-rt-works-on-mingw/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-include ../tools.mk
-
-# only-windows-gnu
-
-all:
-	$(CXX) foo.cpp -c -o $(TMPDIR)/foo.o
-	$(AR) crus $(TMPDIR)/libfoo.a $(TMPDIR)/foo.o
-	$(RUSTC) foo.rs -lfoo -lstdc++
-	$(call RUN,foo)
diff --git a/tests/run-make/compiler-rt-works-on-mingw/rmake.rs b/tests/run-make/compiler-rt-works-on-mingw/rmake.rs
new file mode 100644
index 00000000000..f1b41f96312
--- /dev/null
+++ b/tests/run-make/compiler-rt-works-on-mingw/rmake.rs
@@ -0,0 +1,15 @@
+// `compiler-rt` ("runtime") is a suite of LLVM features compatible with rustc.
+// After building it was enabled on Windows-gnu in #29874, this test is a basic smoke test to
+// check if building and linking to it can work at all.
+// See https://github.com/rust-lang/rust/pull/29478
+
+//@ only-windows-gnu
+
+use run_make_support::{cxx, is_msvc, llvm_ar, run, rustc, static_lib_name};
+
+fn main() {
+    cxx().input("foo.cpp").arg("-c").out_exe("foo.o").run();
+    llvm_ar().obj_to_ar().output_input(static_lib_name("foo"), "foo.o").run();
+    rustc().input("foo.rs").arg("-lfoo").arg("-lstdc++").run();
+    run("foo");
+}
diff --git a/tests/run-make/dump-ice-to-disk/Makefile b/tests/run-make/dump-ice-to-disk/Makefile
deleted file mode 100644
index 23006fc09e2..00000000000
--- a/tests/run-make/dump-ice-to-disk/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-include ../tools.mk
-
-# ignore-windows
-
-export RUSTC := $(RUSTC_ORIGINAL)
-export LD_LIBRARY_PATH := $(HOST_RPATH_DIR)
-export TMPDIR := $(TMPDIR)
-
-all:
-	bash check.sh
diff --git a/tests/run-make/dump-ice-to-disk/check.sh b/tests/run-make/dump-ice-to-disk/check.sh
deleted file mode 100644
index ff6e4be35af..00000000000
--- a/tests/run-make/dump-ice-to-disk/check.sh
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/bin/sh
-
-# Default nightly behavior (write ICE to current directory)
-# FIXME(estebank): these are failing on CI, but passing locally.
-# $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-default.log 2>&1
-# default=$(cat ./rustc-ice-*.txt | wc -l)
-# rm ./rustc-ice-*.txt
-
-# Explicit directory set
-export RUSTC_ICE=$TMPDIR
-$RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-default-set.log 2>&1
-default_set=$(cat $TMPDIR/rustc-ice-*.txt | wc -l)
-content=$(cat $TMPDIR/rustc-ice-*.txt)
-# Ensure that the ICE dump path doesn't contain `:` because they cause problems on Windows
-windows_safe=$(echo rustc-ice-*.txt | grep ':')
-if [ ! -z "$windows_safe" ]; then
-    exit 1
-fi
-
-rm $TMPDIR/rustc-ice-*.txt
-RUST_BACKTRACE=short $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-short.log 2>&1
-short=$(cat $TMPDIR/rustc-ice-*.txt | wc -l)
-rm $TMPDIR/rustc-ice-*.txt
-RUST_BACKTRACE=full $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-full.log 2>&1
-full=$(cat $TMPDIR/rustc-ice-*.txt | wc -l)
-rm $TMPDIR/rustc-ice-*.txt
-
-# Explicitly disabling ICE dump
-export RUSTC_ICE=0
-$RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-disabled.log 2>&1
-should_be_empty_tmp=$(ls -l $TMPDIR/rustc-ice-*.txt 2>/dev/null | wc -l)
-should_be_empty_dot=$(ls -l ./rustc-ice-*.txt 2>/dev/null | wc -l)
-
-echo "#### ICE Dump content:"
-echo $content
-echo "#### default length:"
-echo $default
-echo "#### short length:"
-echo $short
-echo "#### default_set length:"
-echo $default_set
-echo "#### full length:"
-echo $full
-echo "#### should_be_empty_dot length:"
-echo $should_be_empty_dot
-echo "#### should_be_empty_tmp length:"
-echo $should_be_empty_tmp
-
-## Verify that a the ICE dump file is created in the appropriate directories, that
-## their lengths are the same regardless of other backtrace configuration options,
-## that the file is not created when asked to (RUSTC_ICE=0) and that the file
-## contains at least part of the expected content.
-if [ $short -eq $default_set ] &&
-    #[ $default -eq $short ] &&
-    [ $default_set -eq $full ] &&
-    [[ $content == *"thread 'rustc' panicked at "* ]] &&
-    [[ $content == *"stack backtrace:"* ]] &&
-    #[ $default -gt 0 ] &&
-    [ $should_be_empty_dot -eq 0 ] &&
-    [ $should_be_empty_tmp -eq 0 ]; then
-    exit 0
-else
-    exit 1
-fi
diff --git a/tests/run-make/dump-ice-to-disk/src/lib.rs b/tests/run-make/dump-ice-to-disk/lib.rs
index b23b7f830d7..b23b7f830d7 100644
--- a/tests/run-make/dump-ice-to-disk/src/lib.rs
+++ b/tests/run-make/dump-ice-to-disk/lib.rs
diff --git a/tests/run-make/dump-ice-to-disk/rmake.rs b/tests/run-make/dump-ice-to-disk/rmake.rs
new file mode 100644
index 00000000000..2fb5c825064
--- /dev/null
+++ b/tests/run-make/dump-ice-to-disk/rmake.rs
@@ -0,0 +1,81 @@
+// This test checks if internal compilation error (ICE) log files work as expected.
+// - Get the number of lines from the log files without any configuration options,
+// then check that the line count doesn't change if the backtrace gets configured to be short
+// or full.
+// - Check that disabling ICE logging results in zero files created.
+// - Check that the ICE files contain some of the expected strings.
+// See https://github.com/rust-lang/rust/pull/108714
+
+use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_files};
+
+fn main() {
+    rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
+    let default = get_text_from_ice(".").lines().count();
+    clear_ice_files();
+
+    rustc().env("RUSTC_ICE", cwd()).input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
+    let ice_text = get_text_from_ice(cwd());
+    let default_set = ice_text.lines().count();
+    let content = ice_text;
+    let ice_files = shallow_find_files(cwd(), |path| {
+        has_prefix(path, "rustc-ice") && has_extension(path, "txt")
+    });
+    assert_eq!(ice_files.len(), 1); // There should only be 1 ICE file.
+    let ice_file_name =
+        ice_files.first().and_then(|f| f.file_name()).and_then(|n| n.to_str()).unwrap();
+    // Ensure that the ICE dump path doesn't contain `:`, because they cause problems on Windows.
+    assert!(!ice_file_name.contains(":"), "{ice_file_name}");
+
+    clear_ice_files();
+    rustc()
+        .env("RUSTC_ICE", cwd())
+        .input("lib.rs")
+        .env("RUST_BACKTRACE", "short")
+        .arg("-Ztreat-err-as-bug=1")
+        .run_fail();
+    let short = get_text_from_ice(cwd()).lines().count();
+    clear_ice_files();
+    rustc()
+        .env("RUSTC_ICE", cwd())
+        .input("lib.rs")
+        .env("RUST_BACKTRACE", "full")
+        .arg("-Ztreat-err-as-bug=1")
+        .run_fail();
+    let full = get_text_from_ice(cwd()).lines().count();
+    clear_ice_files();
+
+    // The ICE dump is explicitly disabled. Therefore, this should produce no files.
+    rustc().env("RUSTC_ICE", "0").input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
+    let ice_files = shallow_find_files(cwd(), |path| {
+        has_prefix(path, "rustc-ice") && has_extension(path, "txt")
+    });
+    assert!(ice_files.is_empty()); // There should be 0 ICE files.
+
+    // The line count should not change.
+    assert_eq!(short, default_set);
+    assert_eq!(short, default);
+    assert_eq!(full, default_set);
+    assert!(default > 0);
+    // Some of the expected strings in an ICE file should appear.
+    assert!(content.contains("thread 'rustc' panicked at"));
+    assert!(content.contains("stack backtrace:"));
+}
+
+fn clear_ice_files() {
+    let ice_files = shallow_find_files(cwd(), |path| {
+        has_prefix(path, "rustc-ice") && has_extension(path, "txt")
+    });
+    for file in ice_files {
+        rfs::remove_file(file);
+    }
+}
+
+#[track_caller]
+fn get_text_from_ice(dir: impl AsRef<std::path::Path>) -> String {
+    let ice_files =
+        shallow_find_files(dir, |path| has_prefix(path, "rustc-ice") && has_extension(path, "txt"));
+    assert_eq!(ice_files.len(), 1); // There should only be 1 ICE file.
+    let ice_file = ice_files.get(0).unwrap();
+    let output = rfs::read_to_string(ice_file);
+    output
+}
diff --git a/tests/run-make/extern-flag-disambiguates/Makefile b/tests/run-make/extern-flag-disambiguates/Makefile
deleted file mode 100644
index e54a537ecd0..00000000000
--- a/tests/run-make/extern-flag-disambiguates/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-# Attempt to build this dependency tree:
-#
-#	A.1   A.2
-#	 |\    |
-#	 | \   |
-#        B  \  C
-#         \ | /
-#          \|/
-#           D
-#
-# Note that A.1 and A.2 are crates with the same name.
-
-all:
-	$(RUSTC) -C metadata=1 -C extra-filename=-1 a.rs
-	$(RUSTC) -C metadata=2 -C extra-filename=-2 a.rs
-	$(RUSTC) b.rs --extern a=$(TMPDIR)/liba-1.rlib
-	$(RUSTC) c.rs --extern a=$(TMPDIR)/liba-2.rlib
-	@echo before
-	$(RUSTC) --cfg before d.rs --extern a=$(TMPDIR)/liba-1.rlib
-	$(call RUN,d)
-	@echo after
-	$(RUSTC) --cfg after  d.rs --extern a=$(TMPDIR)/liba-1.rlib
-	$(call RUN,d)
diff --git a/tests/run-make/extern-flag-disambiguates/rmake.rs b/tests/run-make/extern-flag-disambiguates/rmake.rs
new file mode 100644
index 00000000000..2d7d7f69f66
--- /dev/null
+++ b/tests/run-make/extern-flag-disambiguates/rmake.rs
@@ -0,0 +1,30 @@
+//@ ignore-cross-compile
+
+use run_make_support::{cwd, run, rustc};
+
+// Attempt to build this dependency tree:
+//
+//    A.1   A.2
+//     |\    |
+//     | \   |
+//     B  \  C
+//      \ | /
+//       \|/
+//        D
+//
+// Note that A.1 and A.2 are crates with the same name.
+
+// original Makefile at https://github.com/rust-lang/rust/issues/14469
+
+fn main() {
+    rustc().metadata("1").extra_filename("-1").input("a.rs").run();
+    rustc().metadata("2").extra_filename("-2").input("a.rs").run();
+    rustc().input("b.rs").extern_("a", "liba-1.rlib").run();
+    rustc().input("c.rs").extern_("a", "liba-2.rlib").run();
+    println!("before");
+    rustc().cfg("before").input("d.rs").extern_("a", "liba-1.rlib").run();
+    run("d");
+    println!("after");
+    rustc().cfg("after").input("d.rs").extern_("a", "liba-1.rlib").run();
+    run("d");
+}
diff --git a/tests/run-make/incr-foreign-head-span/Makefile b/tests/run-make/incr-foreign-head-span/Makefile
deleted file mode 100644
index 9be4b0f601c..00000000000
--- a/tests/run-make/incr-foreign-head-span/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-include ../tools.mk
-
-# ignore-none no-std is not supported
-# ignore-nvptx64-nvidia-cuda FIXME: can't find crate for 'std'
-
-# Ensure that modifying a crate on disk (without recompiling it)
-# does not cause ICEs in downstream crates.
-# Previously, we would call `SourceMap.guess_head_span` on a span
-# from an external crate, which would cause us to read an upstream
-# source file from disk during compilation of a downstream crate
-# See #86480 for more details
-
-INCR=$(TMPDIR)/incr
-
-all:
-	cp first_crate.rs second_crate.rs $(TMPDIR)
-	$(RUSTC) $(TMPDIR)/first_crate.rs  -C incremental=$(INCR) --target $(TARGET) --crate-type lib
-	$(RUSTC) $(TMPDIR)/second_crate.rs -C incremental=$(INCR) --target $(TARGET)  --extern first_crate=$(TMPDIR)/libfirst_crate.rlib --crate-type lib
-	rm $(TMPDIR)/first_crate.rs
-	$(RUSTC) $(TMPDIR)/second_crate.rs  -C incremental=$(INCR) --target $(TARGET) --cfg second_run --crate-type lib
-
diff --git a/tests/run-make/incr-foreign-head-span/rmake.rs b/tests/run-make/incr-foreign-head-span/rmake.rs
new file mode 100644
index 00000000000..92e2ed5f879
--- /dev/null
+++ b/tests/run-make/incr-foreign-head-span/rmake.rs
@@ -0,0 +1,25 @@
+// Ensure that modifying a crate on disk (without recompiling it)
+// does not cause ICEs (internal compiler errors) in downstream crates.
+// Previously, we would call `SourceMap.guess_head_span` on a span
+// from an external crate, which would cause us to read an upstream
+// source file from disk during compilation of a downstream crate.
+// See https://github.com/rust-lang/rust/issues/86480
+
+//@ ignore-none
+// Reason: no-std is not supported
+//@ ignore-nvptx64-nvidia-cuda
+// Reason: can't find crate for 'std'
+
+use run_make_support::{rfs, rust_lib_name, rustc};
+
+fn main() {
+    rustc().input("first_crate.rs").incremental("incr").crate_type("lib").run();
+    rustc()
+        .input("second_crate.rs")
+        .incremental("incr")
+        .extern_("first_crate", rust_lib_name("first_crate"))
+        .crate_type("lib")
+        .run();
+    rfs::remove_file("first_crate.rs");
+    rustc().input("second_crate.rs").incremental("incr").cfg("second_run").crate_type("lib").run();
+}
diff --git a/tests/run-make/interdependent-c-libraries/Makefile b/tests/run-make/interdependent-c-libraries/Makefile
deleted file mode 100644
index 53a696d82bf..00000000000
--- a/tests/run-make/interdependent-c-libraries/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-# The rust crate foo will link to the native library foo, while the rust crate
-# bar will link to the native library bar. There is also a dependency between
-# the native library bar to the natibe library foo.
-#
-# This test ensures that the ordering of -lfoo and -lbar on the command line is
-# correct to complete the linkage. If passed as "-lfoo -lbar", then the 'foo'
-# library will be stripped out, and the linkage will fail.
-
-all: $(call NATIVE_STATICLIB,foo) $(call NATIVE_STATICLIB,bar)
-	$(RUSTC) foo.rs
-	$(RUSTC) bar.rs
-	$(RUSTC) main.rs --print link-args
diff --git a/tests/run-make/interdependent-c-libraries/rmake.rs b/tests/run-make/interdependent-c-libraries/rmake.rs
new file mode 100644
index 00000000000..ee8cc76c9cc
--- /dev/null
+++ b/tests/run-make/interdependent-c-libraries/rmake.rs
@@ -0,0 +1,21 @@
+// The rust crate foo will link to the native library foo, while the rust crate
+// bar will link to the native library bar. There is also a dependency between
+// the native library bar to the natibe library foo.
+// This test ensures that the ordering of -lfoo and -lbar on the command line is
+// correct to complete the linkage. If passed as "-lfoo -lbar", then the 'foo'
+// library will be stripped out, and the linkage will fail.
+// See https://github.com/rust-lang/rust/commit/e6072fa0c4c22d62acf3dcb78c8ee260a1368bd7
+
+//@ ignore-cross-compile
+// Reason: linkage still fails as the object files produced are not in the correct
+// format in the `build_native_static_lib` step
+
+use run_make_support::{build_native_static_lib, rustc};
+
+fn main() {
+    build_native_static_lib("foo");
+    build_native_static_lib("bar");
+    rustc().input("foo.rs").run();
+    rustc().input("bar.rs").run();
+    rustc().input("main.rs").print("link-args").run();
+}
diff --git a/tests/run-make/panic-abort-eh_frame/Makefile b/tests/run-make/panic-abort-eh_frame/Makefile
deleted file mode 100644
index 7020455b742..00000000000
--- a/tests/run-make/panic-abort-eh_frame/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# only-linux
-#
-# This test ensures that `panic=abort` code (without `C-unwind`, that is) should not have any
-# unwinding related `.eh_frame` sections emitted.
-
-include ../tools.mk
-
-all:
-	$(RUSTC) foo.rs --crate-type=lib --emit=obj=$(TMPDIR)/foo.o -Cpanic=abort --edition 2021 -Z validate-mir
-	objdump --dwarf=frames $(TMPDIR)/foo.o | $(CGREP) -v 'DW_CFA'
diff --git a/tests/run-make/panic-abort-eh_frame/rmake.rs b/tests/run-make/panic-abort-eh_frame/rmake.rs
new file mode 100644
index 00000000000..23d95dc5774
--- /dev/null
+++ b/tests/run-make/panic-abort-eh_frame/rmake.rs
@@ -0,0 +1,24 @@
+// An `.eh_frame` section in an object file is a symptom of an UnwindAction::Terminate
+// being inserted, useful for determining whether or not unwinding is necessary.
+// This is useless when panics would NEVER unwind due to -C panic=abort. This section should
+// therefore never appear in the emit file of a -C panic=abort compilation, and this test
+// checks that this is respected.
+// See https://github.com/rust-lang/rust/pull/112403
+
+//@ only-linux
+// FIXME(Oneirical): the DW_CFA symbol appears on Windows-gnu, because uwtable
+// is forced to true on Windows targets (see #128136).
+
+use run_make_support::{llvm_objdump, rustc};
+
+fn main() {
+    rustc()
+        .input("foo.rs")
+        .crate_type("lib")
+        .emit("obj=foo.o")
+        .panic("abort")
+        .edition("2021")
+        .arg("-Zvalidate-mir")
+        .run();
+    llvm_objdump().arg("--dwarf=frames").input("foo.o").run().assert_stdout_not_contains("DW_CFA");
+}
diff --git a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs
deleted file mode 100644
index 5ac7e1e58b8..00000000000
--- a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//@ compile-flags: --crate-type=lib
-//@ check-pass
-
-#![feature(inherent_associated_types)]
-#![allow(incomplete_features)]
-
-// Bounds on the self type play a major role in the resolution of inherent associated types (*).
-// As a result of that, if a type alias contains any then its bounds have to be respected and the
-// lint `type_alias_bounds` should not fire.
-
-#![deny(type_alias_bounds)]
-
-pub type Alias<T: Bound> = (Source<T>::Assoc,);
-
-pub struct Source<T>(T);
-pub trait Bound {}
-
-impl<T: Bound> Source<T> {
-    pub type Assoc = ();
-}
diff --git a/tests/ui/associated-inherent-types/type-alias-bounds.rs b/tests/ui/associated-inherent-types/type-alias-bounds.rs
new file mode 100644
index 00000000000..61641a83994
--- /dev/null
+++ b/tests/ui/associated-inherent-types/type-alias-bounds.rs
@@ -0,0 +1,29 @@
+//@ compile-flags: --crate-type=lib
+//@ check-pass
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+// FIXME(inherent_associated_types):
+// While we currently do take some clauses of the ParamEnv into consideration
+// when performing IAT selection, we do not perform full well-formedness checking
+// for (eager) type alias definition and usage sites.
+//
+// Therefore it's *correct* for lint `type_alias_bounds` to fire here despite the
+// fact that removing `Bound` from `T` in `Alias` would lead to an error!
+//
+// Obviously, the present situation isn't ideal and we should fix it in one way
+// or another. Either we somehow delay IAT selection until after HIR ty lowering
+// to avoid the need to specify any bounds inside (eager) type aliases or we
+// force the overarching type alias to be *lazy* (similar to TAITs) which would
+// automatically lead to full wfchecking and lint TAB getting suppressed.
+
+pub type Alias<T: Bound> = (Source<T>::Assoc,);
+//~^ WARN bounds on generic parameters in type aliases are not enforced
+
+pub struct Source<T>(T);
+pub trait Bound {}
+
+impl<T: Bound> Source<T> {
+    pub type Assoc = ();
+}
diff --git a/tests/ui/associated-inherent-types/type-alias-bounds.stderr b/tests/ui/associated-inherent-types/type-alias-bounds.stderr
new file mode 100644
index 00000000000..c56dd498f77
--- /dev/null
+++ b/tests/ui/associated-inherent-types/type-alias-bounds.stderr
@@ -0,0 +1,16 @@
+warning: bounds on generic parameters in type aliases are not enforced
+  --> $DIR/type-alias-bounds.rs:21:19
+   |
+LL | pub type Alias<T: Bound> = (Source<T>::Assoc,);
+   |                 --^^^^^
+   |                 | |
+   |                 | will not be checked at usage sites of the type alias
+   |                 help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
+   = note: `#[warn(type_alias_bounds)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/associated-type-bounds/type-alias.stderr b/tests/ui/associated-type-bounds/type-alias.stderr
index 072c471467c..d59952b4a14 100644
--- a/tests/ui/associated-type-bounds/type-alias.stderr
+++ b/tests/ui/associated-type-bounds/type-alias.stderr
@@ -1,147 +1,159 @@
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias.rs:3:25
    |
 LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^
-   |
+   |                   ------^^^^^^^^^^^^^^^^^^^^^^^
+   |                   |     |
+   |                   |     will not be checked at usage sites of the type alias
+   |                   help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
    = note: `#[warn(type_alias_bounds)]` on by default
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
-LL + type _TaWhere1<T>  = T;
-   |
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias.rs:4:25
    |
 LL | type _TaWhere2<T> where T: Iterator<Item: 'static> = T;
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaWhere2<T> where T: Iterator<Item: 'static> = T;
-LL + type _TaWhere2<T>  = T;
-   |
+   |                   ------^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                   |     |
+   |                   |     will not be checked at usage sites of the type alias
+   |                   help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias.rs:5:25
    |
 LL | type _TaWhere3<T> where T: Iterator<Item: 'static> = T;
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaWhere3<T> where T: Iterator<Item: 'static> = T;
-LL + type _TaWhere3<T>  = T;
-   |
+   |                   ------^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                   |     |
+   |                   |     will not be checked at usage sites of the type alias
+   |                   help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias.rs:6:25
    |
 LL | type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + Send> = T;
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + Send> = T;
-LL + type _TaWhere4<T>  = T;
-   |
+   |                   ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                   |     |
+   |                   |     will not be checked at usage sites of the type alias
+   |                   help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias.rs:7:25
    |
 LL | type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T;
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T;
-LL + type _TaWhere5<T>  = T;
-   |
+   |                   ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                   |     |
+   |                   |     will not be checked at usage sites of the type alias
+   |                   help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias.rs:8:25
    |
 LL | type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T;
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T;
-LL + type _TaWhere6<T>  = T;
-   |
+   |                   ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                   |     |
+   |                   |     will not be checked at usage sites of the type alias
+   |                   help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias.rs:10:20
    |
 LL | type _TaInline1<T: Iterator<Item: Copy>> = T;
-   |                    ^^^^^^^^^^^^^^^^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaInline1<T: Iterator<Item: Copy>> = T;
-LL + type _TaInline1<T> = T;
-   |
+   |                  --^^^^^^^^^^^^^^^^^^^^
+   |                  | |
+   |                  | will not be checked at usage sites of the type alias
+   |                  help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias.rs:11:20
    |
 LL | type _TaInline2<T: Iterator<Item: 'static>> = T;
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaInline2<T: Iterator<Item: 'static>> = T;
-LL + type _TaInline2<T> = T;
-   |
+   |                  --^^^^^^^^^^^^^^^^^^^^^^^
+   |                  | |
+   |                  | will not be checked at usage sites of the type alias
+   |                  help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias.rs:12:20
    |
 LL | type _TaInline3<T: Iterator<Item: 'static>> = T;
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaInline3<T: Iterator<Item: 'static>> = T;
-LL + type _TaInline3<T> = T;
-   |
+   |                  --^^^^^^^^^^^^^^^^^^^^^^^
+   |                  | |
+   |                  | will not be checked at usage sites of the type alias
+   |                  help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias.rs:13:20
    |
 LL | type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T;
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T;
-LL + type _TaInline4<T> = T;
-   |
+   |                  --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  | |
+   |                  | will not be checked at usage sites of the type alias
+   |                  help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias.rs:14:20
    |
 LL | type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T;
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T;
-LL + type _TaInline5<T> = T;
-   |
+   |                  --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  | |
+   |                  | will not be checked at usage sites of the type alias
+   |                  help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias.rs:15:20
    |
 LL | type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T;
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T;
-LL + type _TaInline6<T> = T;
-   |
+   |                  --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  | |
+   |                  | will not be checked at usage sites of the type alias
+   |                  help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
 warning: 12 warnings emitted
 
diff --git a/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr
new file mode 100644
index 00000000000..fa12dd14753
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr
@@ -0,0 +1,63 @@
+error[E0277]: the trait bound `String: Copy` is not satisfied
+  --> $DIR/type-alias-bounds.rs:23:12
+   |
+LL |     let _: AliasConstUnused<String>;
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |
+note: required by a bound in `ct_unused_0::AliasConstUnused`
+  --> $DIR/type-alias-bounds.rs:20:30
+   |
+LL |     type AliasConstUnused<T: Copy> = (T, I32<{ DATA }>);
+   |                              ^^^^ required by this bound in `AliasConstUnused`
+
+error[E0277]: the trait bound `String: Copy` is not satisfied
+  --> $DIR/type-alias-bounds.rs:31:12
+   |
+LL |     let _: AliasConstUnused;
+   |            ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |
+note: required by a bound in `ct_unused_1::AliasConstUnused`
+  --> $DIR/type-alias-bounds.rs:29:41
+   |
+LL |     type AliasConstUnused where String: Copy = I32<{ 0; 0 }>;
+   |                                         ^^^^ required by this bound in `AliasConstUnused`
+
+error[E0277]: the trait bound `String: Copy` is not satisfied
+  --> $DIR/type-alias-bounds.rs:39:12
+   |
+LL |     let _: AliasFnUnused<String>;
+   |            ^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |
+note: required by a bound in `AliasFnUnused`
+  --> $DIR/type-alias-bounds.rs:36:27
+   |
+LL |     type AliasFnUnused<T: Copy> = (T, I32<{ code() }>);
+   |                           ^^^^ required by this bound in `AliasFnUnused`
+
+error[E0277]: the trait bound `String: Copy` is not satisfied
+  --> $DIR/type-alias-bounds.rs:57:12
+   |
+LL |     let _: AliasAssocConstUsed<String>;
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |
+note: required by a bound in `AliasAssocConstUsed`
+  --> $DIR/type-alias-bounds.rs:55:41
+   |
+LL |     type AliasAssocConstUsed<T: Trait + Copy> = I32<{ T::DATA }>;
+   |                                         ^^^^ required by this bound in `AliasAssocConstUsed`
+
+error[E0277]: the trait bound `String: Copy` is not satisfied
+  --> $DIR/type-alias-bounds.rs:65:12
+   |
+LL |     let _: AliasFnUsed<String>;
+   |            ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |
+note: required by a bound in `AliasFnUsed`
+  --> $DIR/type-alias-bounds.rs:62:33
+   |
+LL |     type AliasFnUsed<T: Trait + Copy> = I32<{ code::<T>() }>;
+   |                                 ^^^^ required by this bound in `AliasFnUsed`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs
new file mode 100644
index 00000000000..f16e646129c
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs
@@ -0,0 +1,71 @@
+//@ revisions: pos neg
+//@[pos] check-pass
+
+#![feature(generic_const_exprs)]
+#![feature(trivial_bounds)] // only used in test case `ct_unused_1`
+#![allow(incomplete_features)]
+
+// FIXME(generic_const_exprs): Revisit this before stabilization.
+// Check that we don't emit the lint `type_alias_bounds` for (eager) type aliases
+// whose RHS contains a const projection (aka uneval'ed const).
+// Since anon consts inherit the parent generics and predicates and we effectively
+// check them before and after instantiaton for well-formedness, the type alias
+// bounds are in every sense "enforced".
+// Note that the test cases whose name ends in "unused" just demonstrate that this
+// holds even if the const projections don't "visibly" capture any generics and/or
+// predicates.
+#![deny(type_alias_bounds)]
+
+fn ct_unused_0() {
+    type AliasConstUnused<T: Copy> = (T, I32<{ DATA }>);
+    const DATA: i32 = 0;
+    #[cfg(neg)]
+    let _: AliasConstUnused<String>;
+    //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
+}
+
+fn ct_unused_1() {
+    #[allow(trivial_bounds)]
+    type AliasConstUnused where String: Copy = I32<{ 0; 0 }>;
+    #[cfg(neg)]
+    let _: AliasConstUnused;
+    //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
+}
+
+fn fn_unused() {
+    type AliasFnUnused<T: Copy> = (T, I32<{ code() }>);
+    const fn code() -> i32 { 0 }
+    #[cfg(neg)]
+    let _: AliasFnUnused<String>;
+    //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
+}
+
+trait Trait {
+    type Proj;
+    const DATA: i32;
+}
+
+impl Trait for String {
+    type Proj = i32;
+    const DATA: i32 = 0;
+}
+
+// Regression test for issue #94398.
+fn assoc_ct_used() {
+    type AliasAssocConstUsed<T: Trait + Copy> = I32<{ T::DATA }>;
+    #[cfg(neg)]
+    let _: AliasAssocConstUsed<String>;
+    //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
+}
+
+fn fn_used() {
+    type AliasFnUsed<T: Trait + Copy> = I32<{ code::<T>() }>;
+    const fn code<T: Trait>() -> i32 { T::DATA }
+    #[cfg(neg)]
+    let _: AliasFnUsed<String>;
+    //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
+}
+
+struct I32<const N: i32>;
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/unused-impl-for-non-adts.rs b/tests/ui/lint/dead-code/unused-impl-for-non-adts.rs
new file mode 100644
index 00000000000..46065dcee81
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-impl-for-non-adts.rs
@@ -0,0 +1,45 @@
+#![deny(dead_code)]
+
+struct Foo; //~ ERROR struct `Foo` is never constructed
+
+trait Trait { //~ ERROR trait `Trait` is never used
+    fn foo(&self) {}
+}
+
+impl Trait for Foo {}
+
+impl Trait for [Foo] {}
+impl<const N: usize> Trait for [Foo; N] {}
+
+impl Trait for *const Foo {}
+impl Trait for *mut Foo {}
+
+impl Trait for &Foo {}
+impl Trait for &&Foo {}
+impl Trait for &mut Foo {}
+
+impl Trait for [&Foo] {}
+impl Trait for &[Foo] {}
+impl Trait for &*const Foo {}
+
+pub trait Trait2 {
+    fn foo(&self) {}
+}
+
+impl Trait2 for Foo {}
+
+impl Trait2 for [Foo] {}
+impl<const N: usize> Trait2 for [Foo; N] {}
+
+impl Trait2 for *const Foo {}
+impl Trait2 for *mut Foo {}
+
+impl Trait2 for &Foo {}
+impl Trait2 for &&Foo {}
+impl Trait2 for &mut Foo {}
+
+impl Trait2 for [&Foo] {}
+impl Trait2 for &[Foo] {}
+impl Trait2 for &*const Foo {}
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/unused-impl-for-non-adts.stderr b/tests/ui/lint/dead-code/unused-impl-for-non-adts.stderr
new file mode 100644
index 00000000000..e61fc403e81
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-impl-for-non-adts.stderr
@@ -0,0 +1,20 @@
+error: struct `Foo` is never constructed
+  --> $DIR/unused-impl-for-non-adts.rs:3:8
+   |
+LL | struct Foo;
+   |        ^^^
+   |
+note: the lint level is defined here
+  --> $DIR/unused-impl-for-non-adts.rs:1:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: trait `Trait` is never used
+  --> $DIR/unused-impl-for-non-adts.rs:5:7
+   |
+LL | trait Trait {
+   |       ^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/macros/issue-118786.rs b/tests/ui/macros/issue-118786.rs
index 97454c9de07..a41372e4ea8 100644
--- a/tests/ui/macros/issue-118786.rs
+++ b/tests/ui/macros/issue-118786.rs
@@ -7,6 +7,7 @@ macro_rules! make_macro {
         macro_rules! $macro_name {
         //~^ ERROR macro expansion ignores token `{` and any following
         //~| ERROR cannot find macro `macro_rules` in this scope
+        //~| put a macro name here
             () => {}
         }
     }
diff --git a/tests/ui/macros/issue-118786.stderr b/tests/ui/macros/issue-118786.stderr
index 03e65c94ba7..256b742ee16 100644
--- a/tests/ui/macros/issue-118786.stderr
+++ b/tests/ui/macros/issue-118786.stderr
@@ -1,5 +1,5 @@
 error: macros that expand to items must be delimited with braces or followed by a semicolon
-  --> $DIR/issue-118786.rs:15:13
+  --> $DIR/issue-118786.rs:16:13
    |
 LL | make_macro!((meow));
    |             ^^^^^^
@@ -34,10 +34,10 @@ LL | make_macro!((meow));
    | ------------------- in this macro invocation
    |
 note: maybe you have forgotten to define a name for this `macro_rules!`
-  --> $DIR/issue-118786.rs:7:9
+  --> $DIR/issue-118786.rs:7:20
    |
 LL |         macro_rules! $macro_name {
-   |         ^^^^^^^^^^^
+   |                    ^ put a macro name here
 ...
 LL | make_macro!((meow));
    | ------------------- in this macro invocation
diff --git a/tests/ui/privacy/private-in-public-warn.rs b/tests/ui/privacy/private-in-public-warn.rs
index 99d318e36be..746b98fbd07 100644
--- a/tests/ui/privacy/private-in-public-warn.rs
+++ b/tests/ui/privacy/private-in-public-warn.rs
@@ -39,7 +39,7 @@ mod traits {
     pub trait PubTr {}
 
     pub type Alias<T: PrivTr> = T; //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Alias`
-    //~^ WARNING bounds on generic parameters are not enforced in type aliases
+    //~^ WARNING bounds on generic parameters in type aliases are not enforced
     pub trait Tr1: PrivTr {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr1`
     pub trait Tr2<T: PrivTr> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr2`
     pub trait Tr3 {
@@ -58,7 +58,7 @@ mod traits_where {
 
     pub type Alias<T> where T: PrivTr = T;
         //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Alias`
-        //~| WARNING where clauses are not enforced in type aliases
+        //~| WARNING where clauses on type aliases are not enforced
     pub trait Tr2<T> where T: PrivTr {}
         //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2`
     pub trait Tr3 {
diff --git a/tests/ui/privacy/private-in-public-warn.stderr b/tests/ui/privacy/private-in-public-warn.stderr
index ac7e5547de9..3f7b8c281e7 100644
--- a/tests/ui/privacy/private-in-public-warn.stderr
+++ b/tests/ui/privacy/private-in-public-warn.stderr
@@ -395,30 +395,32 @@ note: but type `Priv2` is only usable at visibility `pub(self)`
 LL |     struct Priv2;
    |     ^^^^^^^^^^^^
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/private-in-public-warn.rs:41:23
    |
 LL |     pub type Alias<T: PrivTr> = T;
-   |                       ^^^^^^
-   |
+   |                     --^^^^^^
+   |                     | |
+   |                     | will not be checked at usage sites of the type alias
+   |                     help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
    = note: `#[warn(type_alias_bounds)]` on by default
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL -     pub type Alias<T: PrivTr> = T;
-LL +     pub type Alias<T> = T;
-   |
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/private-in-public-warn.rs:59:29
    |
 LL |     pub type Alias<T> where T: PrivTr = T;
-   |                             ^^^^^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL -     pub type Alias<T> where T: PrivTr = T;
-LL +     pub type Alias<T>  = T;
-   |
+   |                       ------^^^^^^^^^
+   |                       |     |
+   |                       |     will not be checked at usage sites of the type alias
+   |                       help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
 error: aborting due to 34 previous errors; 2 warnings emitted
 
diff --git a/tests/ui/resolve/issue-118295.rs b/tests/ui/resolve/issue-118295.rs
index b97681d9563..37a49baee80 100644
--- a/tests/ui/resolve/issue-118295.rs
+++ b/tests/ui/resolve/issue-118295.rs
@@ -1,5 +1,11 @@
 macro_rules! {}
 //~^ ERROR cannot find macro `macro_rules` in this scope
 //~| NOTE maybe you have forgotten to define a name for this `macro_rules!`
+//~| put a macro name here
+
+macro_rules!{}
+//~^ ERROR cannot find macro `macro_rules` in this scope
+//~| NOTE maybe you have forgotten to define a name for this `macro_rules!`
+//~| put a macro name here
 
 fn main() {}
diff --git a/tests/ui/resolve/issue-118295.stderr b/tests/ui/resolve/issue-118295.stderr
index d60d7d9185d..06a37e81d6c 100644
--- a/tests/ui/resolve/issue-118295.stderr
+++ b/tests/ui/resolve/issue-118295.stderr
@@ -1,14 +1,26 @@
 error: cannot find macro `macro_rules` in this scope
-  --> $DIR/issue-118295.rs:1:1
+  --> $DIR/issue-118295.rs:6:1
    |
-LL | macro_rules! {}
+LL | macro_rules!{}
    | ^^^^^^^^^^^
    |
 note: maybe you have forgotten to define a name for this `macro_rules!`
+  --> $DIR/issue-118295.rs:6:12
+   |
+LL | macro_rules!{}
+   |            ^ put a macro name here
+
+error: cannot find macro `macro_rules` in this scope
   --> $DIR/issue-118295.rs:1:1
    |
 LL | macro_rules! {}
    | ^^^^^^^^^^^
+   |
+note: maybe you have forgotten to define a name for this `macro_rules!`
+  --> $DIR/issue-118295.rs:1:12
+   |
+LL | macro_rules! {}
+   |            ^ put a macro name here
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/resolve/issue-55673.stderr b/tests/ui/resolve/issue-55673.stderr
index ffc3252230a..4069b35a998 100644
--- a/tests/ui/resolve/issue-55673.stderr
+++ b/tests/ui/resolve/issue-55673.stderr
@@ -19,7 +19,7 @@ help: consider further restricting type parameter `T`
    |
 LL |     T::Baa: std::fmt::Debug, T: Foo
    |                            ~~~~~~~~
-help: and also change the associated type name
+help: ...and changing the associated type name
    |
 LL |     T::Bar: std::fmt::Debug,
    |        ~~~
diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr b/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr
index d66e468873b..0eae68bfcf0 100644
--- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr
+++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr
@@ -24,18 +24,19 @@ warning: trait bound i32: Foo does not depend on any type or lifetime parameters
 LL | union U where i32: Foo { f: i32 }
    |                    ^^^
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/trivial-bounds-inconsistent.rs:22:14
    |
 LL | type Y where i32: Foo = ();
-   |              ^^^^^^^^
-   |
+   |        ------^^^^^^^^
+   |        |     |
+   |        |     will not be checked at usage sites of the type alias
+   |        help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
    = note: `#[warn(type_alias_bounds)]` on by default
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type Y where i32: Foo = ();
-LL + type Y  = ();
-   |
 
 warning: trait bound i32: Foo does not depend on any type or lifetime parameters
   --> $DIR/trivial-bounds-inconsistent.rs:22:19
diff --git a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr
new file mode 100644
index 00000000000..e891ff10fda
--- /dev/null
+++ b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr
@@ -0,0 +1,36 @@
+error[E0220]: associated type `Assoc` not found for `T`
+  --> $DIR/unresolved-assoc-ty-suggest-trait.rs:9:22
+   |
+LL | type AssocOf<T> = T::Assoc;
+   |                      ^^^^^ there is an associated type `Assoc` in the trait `Trait`
+   |
+help: consider fully qualifying the associated type
+   |
+LL | type AssocOf<T> = <T as Trait>::Assoc;
+   |                   +  +++++++++
+
+error[E0220]: associated type `Assok` not found for `T`
+  --> $DIR/unresolved-assoc-ty-suggest-trait.rs:13:22
+   |
+LL | type AssokOf<T> = T::Assok;
+   |                      ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait`
+   |
+help: consider fully qualifying and renaming the associated type
+   |
+LL | type AssokOf<T> = <T as Trait>::Assoc;
+   |                   +  +++++++++  ~~~~~
+
+error[E0220]: associated type `Proj` not found for `T`
+  --> $DIR/unresolved-assoc-ty-suggest-trait.rs:22:21
+   |
+LL | type ProjOf<T> = T::Proj;
+   |                     ^^^^ there is an associated type `Proj` in the trait `Parametrized`
+   |
+help: consider fully qualifying the associated type
+   |
+LL | type ProjOf<T> = <T as Parametrized</* 'a, T, N */>>::Proj;
+   |                  +  ++++++++++++++++++++++++++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0220`.
diff --git a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr
new file mode 100644
index 00000000000..96179a7b484
--- /dev/null
+++ b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr
@@ -0,0 +1,40 @@
+error[E0220]: associated type `Assoc` not found for `T`
+  --> $DIR/unresolved-assoc-ty-suggest-trait.rs:9:22
+   |
+LL | type AssocOf<T> = T::Assoc;
+   |                      ^^^^^ there is an associated type `Assoc` in the trait `Trait`
+   |
+help: consider restricting type parameter `T`
+   |
+LL | type AssocOf<T: Trait> = T::Assoc;
+   |               +++++++
+
+error[E0220]: associated type `Assok` not found for `T`
+  --> $DIR/unresolved-assoc-ty-suggest-trait.rs:13:22
+   |
+LL | type AssokOf<T> = T::Assok;
+   |                      ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait`
+   |
+help: consider restricting type parameter `T`
+   |
+LL | type AssokOf<T: Trait> = T::Assok;
+   |               +++++++
+help: ...and changing the associated type name
+   |
+LL | type AssokOf<T> = T::Assoc;
+   |                      ~~~~~
+
+error[E0220]: associated type `Proj` not found for `T`
+  --> $DIR/unresolved-assoc-ty-suggest-trait.rs:22:21
+   |
+LL | type ProjOf<T> = T::Proj;
+   |                     ^^^^ there is an associated type `Proj` in the trait `Parametrized`
+   |
+help: consider restricting type parameter `T`
+   |
+LL | type ProjOf<T: Parametrized</* 'a, T, N */>> = T::Proj;
+   |              ++++++++++++++++++++++++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0220`.
diff --git a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs
new file mode 100644
index 00000000000..2c8d448f308
--- /dev/null
+++ b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs
@@ -0,0 +1,26 @@
+// Ensure that we don't suggest *type alias bounds* for **eager** type aliases.
+// issue: rust-lang/rust#125789
+
+//@ revisions: eager lazy
+#![cfg_attr(lazy, feature(lazy_type_alias), allow(incomplete_features))]
+
+trait Trait { type Assoc; }
+
+type AssocOf<T> = T::Assoc; //~ ERROR associated type `Assoc` not found for `T`
+//[eager]~^ HELP consider fully qualifying the associated type
+//[lazy]~| HELP consider restricting type parameter `T`
+
+type AssokOf<T> = T::Assok; //~ ERROR associated type `Assok` not found for `T`
+//[eager]~^ HELP consider fully qualifying and renaming the associated type
+//[lazy]~| HELP consider restricting type parameter `T`
+//[lazy]~| HELP and changing the associated type name
+
+trait Parametrized<'a, T, const N: usize> {
+    type Proj;
+}
+
+type ProjOf<T> = T::Proj; //~ ERROR associated type `Proj` not found for `T`
+//[eager]~^ HELP consider fully qualifying the associated type
+//[lazy]~| HELP consider restricting type parameter `T`
+
+fn main() {}
diff --git a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs
index 5ee3c027f40..52e0887175d 100644
--- a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs
+++ b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs
@@ -3,6 +3,6 @@
 
 //@ check-pass
 pub type T<P: Send + Send + Send> = P;
-//~^ WARN bounds on generic parameters are not enforced in type aliases
+//~^ WARN bounds on generic parameters in type aliases are not enforced
 
 fn main() {}
diff --git a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr
index 125ffbbb417..9fd0fe4913b 100644
--- a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr
+++ b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr
@@ -1,15 +1,16 @@
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/issue-67690-type-alias-bound-diagnostic-crash.rs:5:15
    |
 LL | pub type T<P: Send + Send + Send> = P;
-   |               ^^^^   ^^^^   ^^^^
+   |             --^^^^---^^^^---^^^^
+   |             |               |
+   |             |               will not be checked at usage sites of the type alias
+   |             help: remove this bound
    |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
    = note: `#[warn(type_alias_bounds)]` on by default
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - pub type T<P: Send + Send + Send> = P;
-LL + pub type T<P> = P;
-   |
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/type/type-alias-bounds.rs b/tests/ui/type/type-alias-bounds.rs
index 6d63c0c7e1b..37c073fe1f9 100644
--- a/tests/ui/type/type-alias-bounds.rs
+++ b/tests/ui/type/type-alias-bounds.rs
@@ -6,15 +6,15 @@
 use std::rc::Rc;
 
 type SVec<T: Send + Send> = Vec<T>;
-//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]
+//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds]
 type S2Vec<T> where T: Send = Vec<T>;
-//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds]
+//~^ WARN where clauses on type aliases are not enforced [type_alias_bounds]
 type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>);
-//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]
+//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds]
 type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>);
-//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]
+//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds]
 type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
-//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds]
+//~^ WARN where clauses on type aliases are not enforced [type_alias_bounds]
 
 static STATIC: u32 = 0;
 
@@ -42,10 +42,11 @@ fn foo<'a>(y: &'a i32) {
 struct Sendable<T: Send>(T);
 type MySendable<T> = Sendable<T>; // no error here!
 
-// However, bounds *are* taken into account when accessing associated types
+// Bounds on type params do enable shorthand type alias paths.
+// However, that doesn't actually mean that they are properly enforced.
 trait Bound { type Assoc; }
-type T1<U: Bound> = U::Assoc; //~ WARN not enforced in type aliases
-type T2<U> where U: Bound = U::Assoc;  //~ WARN not enforced in type aliases
+type T1<U: Bound> = U::Assoc; //~ WARN are not enforced
+type T2<U> where U: Bound = U::Assoc;  //~ WARN are not enforced
 
 // This errors:
 // `type T3<U> = U::Assoc;`
@@ -53,7 +54,7 @@ type T2<U> where U: Bound = U::Assoc;  //~ WARN not enforced in type aliases
 type T4<U> = <U as Bound>::Assoc;
 
 // Make sure the help about associated types is not shown incorrectly
-type T5<U: Bound> = <U as Bound>::Assoc;  //~ WARN not enforced in type aliases
-type T6<U: Bound> = ::std::vec::Vec<U>;  //~ WARN not enforced in type aliases
+type T5<U: Bound> = <U as Bound>::Assoc;  //~ WARN are not enforced
+type T6<U: Bound> = ::std::vec::Vec<U>;  //~ WARN are not enforced
 
 fn main() {}
diff --git a/tests/ui/type/type-alias-bounds.stderr b/tests/ui/type/type-alias-bounds.stderr
index 92e573393c9..15c00901066 100644
--- a/tests/ui/type/type-alias-bounds.stderr
+++ b/tests/ui/type/type-alias-bounds.stderr
@@ -1,121 +1,132 @@
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias-bounds.rs:8:14
    |
 LL | type SVec<T: Send + Send> = Vec<T>;
-   |              ^^^^   ^^^^
-   |
+   |            --^^^^---^^^^
+   |            |        |
+   |            |        will not be checked at usage sites of the type alias
+   |            help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
    = note: `#[warn(type_alias_bounds)]` on by default
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type SVec<T: Send + Send> = Vec<T>;
-LL + type SVec<T> = Vec<T>;
-   |
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias-bounds.rs:10:21
    |
 LL | type S2Vec<T> where T: Send = Vec<T>;
-   |                     ^^^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type S2Vec<T> where T: Send = Vec<T>;
-LL + type S2Vec<T>  = Vec<T>;
-   |
+   |               ------^^^^^^^
+   |               |     |
+   |               |     will not be checked at usage sites of the type alias
+   |               help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias-bounds.rs:12:19
    |
 LL | type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>);
-   |                   ^^   ^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>);
-LL + type VVec<'b, 'a> = (&'b u32, Vec<&'a i32>);
-   |
+   |                 --^^---^^
+   |                 |      |
+   |                 |      will not be checked at usage sites of the type alias
+   |                 help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias-bounds.rs:14:18
    |
 LL | type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>);
-   |                  ^^   ^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>);
-LL + type WVec<'b, T> = (&'b u32, Vec<T>);
-   |
+   |                --^^---^^
+   |                |      |
+   |                |      will not be checked at usage sites of the type alias
+   |                help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias-bounds.rs:16:25
    |
 LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
-   |                         ^^^^^  ^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
-LL + type W2Vec<'b, T>  = (&'b u32, Vec<T>);
-   |
+   |                   ------^^^^^--^^^^^
+   |                   |            |
+   |                   |            will not be checked at usage sites of the type alias
+   |                   help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
-  --> $DIR/type-alias-bounds.rs:47:12
+warning: bounds on generic parameters in type aliases are not enforced
+  --> $DIR/type-alias-bounds.rs:48:12
    |
 LL | type T1<U: Bound> = U::Assoc;
-   |            ^^^^^
+   |            ^^^^^ will not be checked at usage sites of the type alias
    |
-help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
-  --> $DIR/type-alias-bounds.rs:47:21
-   |
-LL | type T1<U: Bound> = U::Assoc;
-   |                     ^^^^^^^^
-help: the bound will not be checked when the type alias is used, and should be removed
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
+help: remove this bound
    |
 LL - type T1<U: Bound> = U::Assoc;
 LL + type T1<U> = U::Assoc;
    |
+help: fully qualify this associated type
+   |
+LL | type T1<U: Bound> = <U as /* Trait */>::Assoc;
+   |                     +  +++++++++++++++
 
-warning: where clauses are not enforced in type aliases
-  --> $DIR/type-alias-bounds.rs:48:18
+warning: where clauses on type aliases are not enforced
+  --> $DIR/type-alias-bounds.rs:49:18
    |
 LL | type T2<U> where U: Bound = U::Assoc;
-   |                  ^^^^^^^^
+   |                  ^^^^^^^^ will not be checked at usage sites of the type alias
    |
-help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
-  --> $DIR/type-alias-bounds.rs:48:29
-   |
-LL | type T2<U> where U: Bound = U::Assoc;
-   |                             ^^^^^^^^
-help: the clause will not be checked when the type alias is used, and should be removed
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
+help: remove this where clause
    |
 LL - type T2<U> where U: Bound = U::Assoc;
 LL + type T2<U>  = U::Assoc;
    |
+help: fully qualify this associated type
+   |
+LL | type T2<U> where U: Bound = <U as /* Trait */>::Assoc;
+   |                             +  +++++++++++++++
 
-warning: bounds on generic parameters are not enforced in type aliases
-  --> $DIR/type-alias-bounds.rs:56:12
+warning: bounds on generic parameters in type aliases are not enforced
+  --> $DIR/type-alias-bounds.rs:57:12
    |
 LL | type T5<U: Bound> = <U as Bound>::Assoc;
-   |            ^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type T5<U: Bound> = <U as Bound>::Assoc;
-LL + type T5<U> = <U as Bound>::Assoc;
-   |
+   |          --^^^^^
+   |          | |
+   |          | will not be checked at usage sites of the type alias
+   |          help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
-  --> $DIR/type-alias-bounds.rs:57:12
+warning: bounds on generic parameters in type aliases are not enforced
+  --> $DIR/type-alias-bounds.rs:58:12
    |
 LL | type T6<U: Bound> = ::std::vec::Vec<U>;
-   |            ^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type T6<U: Bound> = ::std::vec::Vec<U>;
-LL + type T6<U> = ::std::vec::Vec<U>;
-   |
+   |          --^^^^^
+   |          | |
+   |          | will not be checked at usage sites of the type alias
+   |          help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
 warning: 9 warnings emitted