From fdf8f024ad71c6e9c46867fb31b74df0fcaaf3f2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= <me@fmease.dev>
Date: Sat, 15 Jun 2024 21:34:44 +0200
Subject: [PATCH] Improve the impl and diag output of lint type_alias_bounds

---
 compiler/rustc_lint/messages.ftl              |  19 +-
 compiler/rustc_lint/src/builtin.rs            |  92 +++++----
 compiler/rustc_lint/src/lints.rs              | 154 ++++++++-------
 .../type-alias-bounds.rs                      |   2 +-
 .../type-alias-bounds.stderr                  |  15 +-
 .../associated-type-bounds/type-alias.stderr  | 180 ++++++++++--------
 tests/ui/privacy/private-in-public-warn.rs    |   4 +-
 .../ui/privacy/private-in-public-warn.stderr  |  30 +--
 .../trivial-bounds-inconsistent.stderr        |  15 +-
 ...67690-type-alias-bound-diagnostic-crash.rs |   2 +-
 ...0-type-alias-bound-diagnostic-crash.stderr |  15 +-
 tests/ui/type/type-alias-bounds.rs            |  21 +-
 tests/ui/type/type-alias-bounds.stderr        | 155 ++++++++-------
 13 files changed, 385 insertions(+), 319 deletions(-)

diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 7d7b97e2eb1..ce99c8686ba 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -139,13 +139,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 90555007607..a8c8c71927a 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -31,12 +31,12 @@ use crate::{
         BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures, BuiltinKeywordIdents,
         BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc,
         BuiltinMutablesTransmutes, BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns,
-        BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasGenericBounds,
-        BuiltinTypeAliasGenericBoundsSuggestion, BuiltinTypeAliasWhereClause,
-        BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit,
-        BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnsafe,
-        BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub,
-        BuiltinWhileTrue, InvalidAsmLabel, SuggestChangingAssocTypes,
+        BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasBounds,
+        BuiltinTypeAliasParamBoundsSuggestion, BuiltinUngatedAsyncFnTrackCaller,
+        BuiltinUnpermittedTypeInit, BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub,
+        BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment,
+        BuiltinUnusedDocCommentSub, BuiltinWhileTrue, InvalidAsmLabel,
+        TypeAliasBoundsQualifyAssocTysSugg,
     },
     EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext,
 };
@@ -1406,23 +1406,6 @@ 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,
-        }
-    }
-}
-
 impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
         let hir::ItemKind::TyAlias(hir_ty, generics) = &item.kind else { return };
@@ -1437,7 +1420,6 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
             return;
         }
 
-
         // 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();
@@ -1455,6 +1437,8 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
         let mut where_spans = Vec::new();
         let mut inline_spans = Vec::new();
         let mut inline_sugg = Vec::new();
+        let mut affects_object_lifetime_defaults = false;
+
         for p in generics.predicates {
             let span = p.span();
             if p.in_where_clause() {
@@ -1465,31 +1449,61 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
                 }
                 inline_sugg.push((span, String::new()));
             }
+
+            // FIXME(fmease): Move this into a "diagnostic decorator" for increased laziness
+            // Bounds of the form `T: 'a` where `T` is a type param of
+            // the type alias affect object lifetime defaults.
+            if !affects_object_lifetime_defaults
+                && let hir::WherePredicate::BoundPredicate(pred) = p
+                && pred.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Outlives(_)))
+                && pred.bound_generic_params.is_empty()
+                && let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = pred.bounded_ty.kind
+                && let Res::Def(DefKind::TyParam, _) = path.res
+            {
+                affects_object_lifetime_defaults = true;
+            }
         }
 
-        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 }
-            });
+        // FIXME(fmease): Add a disclaimer (in the form of a multi-span note) that the removal of
+        //                type-param-outlives-bounds affects OLDs and explicit object lifetime
+        //                bounds might be required [...].
+        // FIXME(fmease): The applicability should also depend on the outcome of the HIR walker
+        //                inside of `TypeAliasBoundsQualifyAssocTysSugg`: Whether it found a
+        //                shorthand projection or not.
+        let applicability = if affects_object_lifetime_defaults {
+            Applicability::MaybeIncorrect
+        } else {
+            Applicability::MachineApplicable
+        };
+
+        let mut qualify_assoc_tys_sugg = Some(TypeAliasBoundsQualifyAssocTysSugg { ty: hir_ty });
+        let enable_feat_help = cx.tcx.sess.is_nightly_build().then_some(());
+
+        if let [.., label_sp] = *where_spans {
             cx.emit_span_lint(
                 TYPE_ALIAS_BOUNDS,
                 where_spans,
-                BuiltinTypeAliasWhereClause { suggestion: generics.where_clause_span, sub },
+                BuiltinTypeAliasBounds::WhereClause {
+                    label: label_sp,
+                    enable_feat_help,
+                    suggestion: (generics.where_clause_span, applicability),
+                    qualify_assoc_tys_sugg: qualify_assoc_tys_sugg.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::ParamBounds {
+                    label: label_sp,
+                    enable_feat_help,
+                    suggestion: BuiltinTypeAliasParamBoundsSuggestion {
+                        suggestions: inline_sugg,
+                        applicability,
+                    },
+                    qualify_assoc_tys_sugg,
+                },
             );
         }
     }
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 6c5f366727f..6cf8b9330fc 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -9,7 +9,7 @@ use rustc_errors::{
     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,9 +22,7 @@ use rustc_span::{
     Span, Symbol,
 };
 
-use crate::{
-    builtin::InitError, builtin::TypeAliasBounds, errors::OverruledAttributeSub, LateContext,
-};
+use crate::{builtin::InitError, errors::OverruledAttributeSub, LateContext};
 
 // array_into_iter.rs
 #[derive(LintDiagnostic)]
@@ -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,97 @@ pub struct MacroExprFragment2024 {
     pub suggestion: Span,
 }
 
-pub struct BuiltinTypeAliasGenericBoundsSuggestion {
-    pub suggestions: Vec<(Span, String)>,
+#[derive(LintDiagnostic)]
+pub enum BuiltinTypeAliasBounds<'a, 'hir> {
+    #[diag(lint_builtin_type_alias_bounds_where_clause)]
+    #[note(lint_builtin_type_alias_bounds_limitation_note)]
+    WhereClause {
+        #[label(lint_builtin_type_alias_bounds_label)]
+        label: Span,
+        #[help(lint_builtin_type_alias_bounds_enable_feat_help)]
+        enable_feat_help: Option<()>,
+        #[suggestion(code = "")]
+        suggestion: (Span, Applicability),
+        #[subdiagnostic]
+        qualify_assoc_tys_sugg: Option<TypeAliasBoundsQualifyAssocTysSugg<'a, 'hir>>,
+    },
+    #[diag(lint_builtin_type_alias_bounds_param_bounds)]
+    #[note(lint_builtin_type_alias_bounds_limitation_note)]
+    ParamBounds {
+        #[label(lint_builtin_type_alias_bounds_label)]
+        label: Span,
+        #[help(lint_builtin_type_alias_bounds_enable_feat_help)]
+        enable_feat_help: Option<()>,
+        #[subdiagnostic]
+        suggestion: BuiltinTypeAliasParamBoundsSuggestion,
+        #[subdiagnostic]
+        qualify_assoc_tys_sugg: Option<TypeAliasBoundsQualifyAssocTysSugg<'a, 'hir>>,
+    },
 }
 
-impl Subdiagnostic for BuiltinTypeAliasGenericBoundsSuggestion {
+pub struct BuiltinTypeAliasParamBoundsSuggestion {
+    pub suggestions: Vec<(Span, String)>,
+    pub applicability: Applicability,
+}
+
+impl Subdiagnostic for BuiltinTypeAliasParamBoundsSuggestion {
     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,
-        );
+        diag.arg("count", self.suggestions.len());
+        diag.multipart_suggestion(fluent::lint_suggestion, self.suggestions, self.applicability);
+    }
+}
+
+pub struct TypeAliasBoundsQualifyAssocTysSugg<'a, 'hir> {
+    pub ty: &'a hir::Ty<'hir>,
+}
+
+impl<'a, 'hir> Subdiagnostic for TypeAliasBoundsQualifyAssocTysSugg<'a, 'hir> {
+    fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
+        self,
+        diag: &mut Diag<'_, G>,
+        _f: &F,
+    ) {
+        // 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.
+
+        use hir::intravisit::Visitor;
+        struct ProbeShorthandAssocTys<'a, 'b, G: EmissionGuarantee> {
+            diag: &'a mut Diag<'b, G>,
+        }
+        impl<'a, 'b, G: EmissionGuarantee> Visitor<'_> for ProbeShorthandAssocTys<'a, 'b, G> {
+            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.
+                // Suggest fully qualifying them via `<T as /* Trait */>::Assoc`.
+                //
+                // 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).
+                if let hir::QPath::TypeRelative(qself, _) = qpath
+                    && let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = qself.kind
+                    && let hir::def::Res::Def(hir::def::DefKind::TyParam, _) = path.res
+                {
+                    self.diag.multipart_suggestion(
+                        fluent::lint_builtin_type_alias_bounds_qualify_assoc_tys_sugg,
+                        vec![
+                            (qself.span.shrink_to_lo(), "<".into()),
+                            (qself.span.shrink_to_hi(), " as /* Trait */>".into()),
+                        ],
+                        Applicability::HasPlaceholders,
+                    );
+                }
+                hir::intravisit::walk_qpath(self, qpath, id)
+            }
+        }
+        ProbeShorthandAssocTys { diag }.visit_ty(self.ty);
     }
 }
 
diff --git a/tests/ui/associated-inherent-types/type-alias-bounds.rs b/tests/ui/associated-inherent-types/type-alias-bounds.rs
index c27bcbed43a..61641a83994 100644
--- a/tests/ui/associated-inherent-types/type-alias-bounds.rs
+++ b/tests/ui/associated-inherent-types/type-alias-bounds.rs
@@ -19,7 +19,7 @@
 // automatically lead to full wfchecking and lint TAB getting suppressed.
 
 pub type Alias<T: Bound> = (Source<T>::Assoc,);
-//~^ WARN bounds on generic parameters are not enforced in type aliases
+//~^ WARN bounds on generic parameters in type aliases are not enforced
 
 pub struct Source<T>(T);
 pub trait Bound {}
diff --git a/tests/ui/associated-inherent-types/type-alias-bounds.stderr b/tests/ui/associated-inherent-types/type-alias-bounds.stderr
index c5d0e9e5041..c56dd498f77 100644
--- a/tests/ui/associated-inherent-types/type-alias-bounds.stderr
+++ b/tests/ui/associated-inherent-types/type-alias-bounds.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/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
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - pub type Alias<T: Bound> = (Source<T>::Assoc,);
-LL + pub type Alias<T> = (Source<T>::Assoc,);
-   |
 
 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/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/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/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
-   |
-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;
-   |
-
-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:57:12
    |
+LL | type T5<U: Bound> = <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 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