summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs70
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs105
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs3
-rw-r--r--tests/rustdoc-ui/issues/issue-105742.rs8
-rw-r--r--tests/rustdoc-ui/issues/issue-105742.stderr198
-rw-r--r--tests/ui/associated-type-bounds/duplicate.rs3
-rw-r--r--tests/ui/associated-type-bounds/duplicate.stderr60
-rw-r--r--tests/ui/associated-type-bounds/supertrait-defines-ty.rs26
-rw-r--r--tests/ui/const-generics/assoc_const_eq_diagnostic.rs1
-rw-r--r--tests/ui/const-generics/assoc_const_eq_diagnostic.stderr16
-rw-r--r--tests/ui/error-codes/E0719.rs1
-rw-r--r--tests/ui/error-codes/E0719.stderr12
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr8
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr8
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs1
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr4
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr4
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr10
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr8
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs1
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr2
-rw-r--r--tests/ui/traits/issue-38404.rs1
-rw-r--r--tests/ui/traits/issue-38404.stderr16
-rw-r--r--tests/ui/typeck/typeck-builtin-bound-type-parameters.rs1
-rw-r--r--tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr18
26 files changed, 445 insertions, 146 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 709dea43d84..6cb008bc5f8 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -56,6 +56,9 @@ use std::slice;
 #[derive(Debug)]
 pub struct PathSeg(pub DefId, pub usize);
 
+#[derive(Copy, Clone, Debug)]
+pub struct OnlySelfBounds(pub bool);
+
 pub trait AstConv<'tcx> {
     fn tcx(&self) -> TyCtxt<'tcx>;
 
@@ -670,6 +673,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         args: &GenericArgs<'_>,
         infer_args: bool,
         self_ty: Ty<'tcx>,
+        only_self_bounds: OnlySelfBounds,
     ) -> GenericArgCountResult {
         let (substs, arg_count) = self.create_substs_for_ast_path(
             trait_ref_span,
@@ -706,6 +710,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 &mut dup_bindings,
                 binding_span.unwrap_or(binding.span),
                 constness,
+                only_self_bounds,
             );
             // Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
         }
@@ -741,6 +746,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         self_ty: Ty<'tcx>,
         bounds: &mut Bounds<'tcx>,
         speculative: bool,
+        only_self_bounds: OnlySelfBounds,
     ) -> GenericArgCountResult {
         let hir_id = trait_ref.hir_ref_id;
         let binding_span = None;
@@ -766,6 +772,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             args,
             infer_args,
             self_ty,
+            only_self_bounds,
         )
     }
 
@@ -777,6 +784,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         args: &GenericArgs<'_>,
         self_ty: Ty<'tcx>,
         bounds: &mut Bounds<'tcx>,
+        only_self_bounds: OnlySelfBounds,
     ) {
         let binding_span = Some(span);
         let constness = ty::BoundConstness::NotConst;
@@ -799,6 +807,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             args,
             infer_args,
             self_ty,
+            only_self_bounds,
         );
     }
 
@@ -947,6 +956,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         ast_bounds: I,
         bounds: &mut Bounds<'tcx>,
         bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
+        only_self_bounds: OnlySelfBounds,
     ) {
         for ast_bound in ast_bounds {
             match ast_bound {
@@ -964,11 +974,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         param_ty,
                         bounds,
                         false,
+                        only_self_bounds,
                     );
                 }
                 &hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
                     self.instantiate_lang_item_trait_ref(
-                        lang_item, span, hir_id, args, param_ty, bounds,
+                        lang_item,
+                        span,
+                        hir_id,
+                        args,
+                        param_ty,
+                        bounds,
+                        only_self_bounds,
                     );
                 }
                 hir::GenericBound::Outlives(lifetime) => {
@@ -1006,8 +1023,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         &self,
         param_ty: Ty<'tcx>,
         ast_bounds: &[hir::GenericBound<'_>],
+        only_self_bounds: OnlySelfBounds,
     ) -> Bounds<'tcx> {
-        self.compute_bounds_inner(param_ty, ast_bounds)
+        let mut bounds = Bounds::default();
+        self.add_bounds(
+            param_ty,
+            ast_bounds.iter(),
+            &mut bounds,
+            ty::List::empty(),
+            only_self_bounds,
+        );
+        debug!(?bounds);
+
+        bounds
     }
 
     /// Convert the bounds in `ast_bounds` that refer to traits which define an associated type
@@ -1029,17 +1057,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             }
         }
 
-        self.compute_bounds_inner(param_ty, &result)
-    }
-
-    fn compute_bounds_inner(
-        &self,
-        param_ty: Ty<'tcx>,
-        ast_bounds: &[hir::GenericBound<'_>],
-    ) -> Bounds<'tcx> {
         let mut bounds = Bounds::default();
-
-        self.add_bounds(param_ty, ast_bounds.iter(), &mut bounds, ty::List::empty());
+        self.add_bounds(
+            param_ty,
+            result.iter(),
+            &mut bounds,
+            ty::List::empty(),
+            OnlySelfBounds(true),
+        );
         debug!(?bounds);
 
         bounds
@@ -1062,6 +1087,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         dup_bindings: &mut FxHashMap<DefId, Span>,
         path_span: Span,
         constness: ty::BoundConstness,
+        only_self_bounds: OnlySelfBounds,
     ) -> Result<(), ErrorGuaranteed> {
         // Given something like `U: SomeTrait<T = X>`, we want to produce a
         // predicate like `<U as SomeTrait>::T = X`. This is somewhat
@@ -1361,8 +1387,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 //
                 // Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
                 // parameter to have a skipped binder.
-                let param_ty = tcx.mk_alias(ty::Projection, projection_ty.skip_binder());
-                self.add_bounds(param_ty, ast_bounds.iter(), bounds, projection_ty.bound_vars());
+                //
+                // NOTE: If `only_self_bounds` is true, do NOT expand this associated
+                // type bound into a trait predicate, since we only want to add predicates
+                // for the `Self` type.
+                if !only_self_bounds.0 {
+                    let param_ty = tcx.mk_alias(ty::Projection, projection_ty.skip_binder());
+                    self.add_bounds(
+                        param_ty,
+                        ast_bounds.iter(),
+                        bounds,
+                        projection_ty.bound_vars(),
+                        only_self_bounds,
+                    );
+                }
             }
         }
         Ok(())
@@ -1403,6 +1441,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 dummy_self,
                 &mut bounds,
                 false,
+                // FIXME: This should be `true`, but we don't really handle
+                // associated type bounds or type aliases in objects in a way
+                // that makes this meaningful, I think.
+                OnlySelfBounds(false),
             ) {
                 potential_assoc_types.extend(cur_potential_assoc_types);
             }
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 80d6bc7db9e..948b903e509 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -1,5 +1,5 @@
 use super::ItemCtxt;
-use crate::astconv::AstConv;
+use crate::astconv::{AstConv, OnlySelfBounds};
 use rustc_hir as hir;
 use rustc_infer::traits::util;
 use rustc_middle::ty::subst::InternalSubsts;
@@ -26,7 +26,7 @@ fn associated_type_bounds<'tcx>(
     );
 
     let icx = ItemCtxt::new(tcx, assoc_item_def_id);
-    let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds);
+    let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, OnlySelfBounds(false));
     // Associated types are implicitly sized unless a `?Sized` bound is found
     icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
 
@@ -67,7 +67,7 @@ fn opaque_type_bounds<'tcx>(
 ) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
     ty::print::with_no_queries!({
         let icx = ItemCtxt::new(tcx, opaque_def_id);
-        let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds);
+        let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, OnlySelfBounds(false));
         // Opaque types are implicitly sized unless a `?Sized` bound is found
         icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
         debug!(?bounds);
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 8c414521b76..83470342a76 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -1,4 +1,4 @@
-use crate::astconv::AstConv;
+use crate::astconv::{AstConv, OnlySelfBounds};
 use crate::bounds::Bounds;
 use crate::collect::ItemCtxt;
 use crate::constrained_generic_params as cgp;
@@ -14,9 +14,6 @@ use rustc_middle::ty::{GenericPredicates, ToPredicate};
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::{Span, DUMMY_SP};
 
-#[derive(Debug)]
-struct OnlySelfBounds(bool);
-
 /// Returns a list of all type predicates (explicit and implicit) for the definition with
 /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
 /// `Self: Trait` predicates for traits.
@@ -99,8 +96,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
             | ItemKind::Struct(_, generics)
             | ItemKind::Union(_, generics) => generics,
 
-            ItemKind::Trait(_, _, generics, ..) | ItemKind::TraitAlias(generics, _) => {
-                is_trait = Some(ty::TraitRef::identity(tcx, def_id.to_def_id()));
+            ItemKind::Trait(_, _, generics, self_bounds, ..)
+            | ItemKind::TraitAlias(generics, self_bounds) => {
+                is_trait = Some(self_bounds);
                 generics
             }
             ItemKind::OpaqueTy(OpaqueTy { generics, .. }) => generics,
@@ -122,10 +120,14 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
 
     // Below we'll consider the bounds on the type parameters (including `Self`)
     // and the explicit where-clauses, but to get the full set of predicates
-    // on a trait we need to add in the supertrait bounds and bounds found on
-    // associated types.
-    if let Some(_trait_ref) = is_trait {
-        predicates.extend(tcx.implied_predicates_of(def_id).predicates.iter().cloned());
+    // on a trait we must also consider the bounds that follow the trait's name,
+    // like `trait Foo: A + B + C`.
+    if let Some(self_bounds) = is_trait {
+        predicates.extend(
+            icx.astconv()
+                .compute_bounds(tcx.types.self_param, self_bounds, OnlySelfBounds(false))
+                .predicates(),
+        );
     }
 
     // In default impls, we can assume that the self type implements
@@ -225,7 +227,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
                 }
 
                 let mut bounds = Bounds::default();
-                icx.astconv().add_bounds(ty, bound_pred.bounds.iter(), &mut bounds, bound_vars);
+                icx.astconv().add_bounds(
+                    ty,
+                    bound_pred.bounds.iter(),
+                    &mut bounds,
+                    bound_vars,
+                    OnlySelfBounds(false),
+                );
                 predicates.extend(bounds.predicates());
             }
 
@@ -608,7 +616,7 @@ pub(super) fn implied_predicates_with_filter(
     let (superbounds, where_bounds_that_match) = match filter {
         PredicateFilter::All => (
             // Convert the bounds that follow the colon (or equal in trait aliases)
-            icx.astconv().compute_bounds(self_param_ty, bounds),
+            icx.astconv().compute_bounds(self_param_ty, bounds, OnlySelfBounds(false)),
             // Also include all where clause bounds
             icx.type_parameter_bounds_in_generics(
                 generics,
@@ -620,7 +628,7 @@ pub(super) fn implied_predicates_with_filter(
         ),
         PredicateFilter::SelfOnly => (
             // Convert the bounds that follow the colon (or equal in trait aliases)
-            icx.astconv().compute_bounds(self_param_ty, bounds),
+            icx.astconv().compute_bounds(self_param_ty, bounds, OnlySelfBounds(true)),
             // Include where clause bounds for `Self`
             icx.type_parameter_bounds_in_generics(
                 generics,
@@ -774,32 +782,35 @@ impl<'tcx> ItemCtxt<'tcx> {
         only_self_bounds: OnlySelfBounds,
         assoc_name: Option<Ident>,
     ) -> Vec<(ty::Predicate<'tcx>, Span)> {
-        ast_generics
-            .predicates
-            .iter()
-            .filter_map(|wp| match wp {
-                hir::WherePredicate::BoundPredicate(bp) => Some(bp),
-                _ => None,
-            })
-            .flat_map(|bp| {
-                let bt = if bp.is_param_bound(param_def_id.to_def_id()) {
-                    Some(ty)
-                } else if !only_self_bounds.0 {
-                    Some(self.to_ty(bp.bounded_ty))
-                } else {
-                    None
-                };
-                let bvars = self.tcx.late_bound_vars(bp.hir_id);
-
-                bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b, bvars))).filter(
-                    |(_, b, _)| match assoc_name {
-                        Some(assoc_name) => self.bound_defines_assoc_item(b, assoc_name),
-                        None => true,
-                    },
-                )
-            })
-            .flat_map(|(bt, b, bvars)| predicates_from_bound(self, bt, b, bvars))
-            .collect()
+        let mut bounds = Bounds::default();
+
+        for predicate in ast_generics.predicates {
+            let hir::WherePredicate::BoundPredicate(predicate) = predicate else {
+                continue;
+            };
+
+            let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) {
+                ty
+            } else if !only_self_bounds.0 {
+                self.to_ty(predicate.bounded_ty)
+            } else {
+                continue;
+            };
+
+            let bound_vars = self.tcx.late_bound_vars(predicate.hir_id);
+            self.astconv().add_bounds(
+                bound_ty,
+                predicate.bounds.iter().filter(|bound| {
+                    assoc_name
+                        .map_or(true, |assoc_name| self.bound_defines_assoc_item(bound, assoc_name))
+                }),
+                &mut bounds,
+                bound_vars,
+                only_self_bounds,
+            );
+        }
+
+        bounds.predicates().collect()
     }
 
     #[instrument(level = "trace", skip(self))]
@@ -817,19 +828,3 @@ impl<'tcx> ItemCtxt<'tcx> {
         }
     }
 }
-
-/// Converts a specific `GenericBound` from the AST into a set of
-/// predicates that apply to the self type. A vector is returned
-/// because this can be anywhere from zero predicates (`T: ?Sized` adds no
-/// predicates) to one (`T: Foo`) to many (`T: Bar<X = i32>` adds `T: Bar`
-/// and `<T as Bar>::X == i32`).
-fn predicates_from_bound<'tcx>(
-    astconv: &dyn AstConv<'tcx>,
-    param_ty: Ty<'tcx>,
-    bound: &'tcx hir::GenericBound<'tcx>,
-    bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
-) -> Vec<(ty::Predicate<'tcx>, Span)> {
-    let mut bounds = Bounds::default();
-    astconv.add_bounds(param_ty, [bound].into_iter(), &mut bounds, bound_vars);
-    bounds.predicates().collect()
-}
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index a4b797f77f7..961457b7579 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -116,7 +116,7 @@ use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode,
 
 use std::ops::Not;
 
-use astconv::AstConv;
+use astconv::{AstConv, OnlySelfBounds};
 use bounds::Bounds;
 
 fluent_messages! { "../messages.ftl" }
@@ -531,6 +531,7 @@ pub fn hir_trait_to_predicates<'tcx>(
         self_ty,
         &mut bounds,
         true,
+        OnlySelfBounds(false),
     );
 
     bounds
diff --git a/tests/rustdoc-ui/issues/issue-105742.rs b/tests/rustdoc-ui/issues/issue-105742.rs
index 8f4172c0cbb..1fbb70c7808 100644
--- a/tests/rustdoc-ui/issues/issue-105742.rs
+++ b/tests/rustdoc-ui/issues/issue-105742.rs
@@ -19,6 +19,8 @@ pub trait SVec: Index<
     //~| missing generics for associated type `SVec::Item`
     //~| missing generics for associated type `SVec::Item`
     //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
     Output = <Index<<Self as SVec>::Item,
     //~^ expected 1 lifetime argument
     //~| expected 1 generic argument
@@ -26,6 +28,8 @@ pub trait SVec: Index<
     //~| missing generics for associated type `SVec::Item`
     //~| missing generics for associated type `SVec::Item`
     //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
     Output = <Self as SVec>::Item> as SVec>::Item,
     //~^ expected 1 lifetime argument
     //~| expected 1 generic argument
@@ -34,11 +38,15 @@ pub trait SVec: Index<
     //~| missing generics for associated type `SVec::Item`
     //~| missing generics for associated type `SVec::Item`
     //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
     //~| expected 1 generic argument
     //~| missing generics for associated type `SVec::Item`
     //~| missing generics for associated type `SVec::Item`
     //~| missing generics for associated type `SVec::Item`
     //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
 > {
     type Item<'a, T>;
 
diff --git a/tests/rustdoc-ui/issues/issue-105742.stderr b/tests/rustdoc-ui/issues/issue-105742.stderr
index cd53762ef9b..b63176c9149 100644
--- a/tests/rustdoc-ui/issues/issue-105742.stderr
+++ b/tests/rustdoc-ui/issues/issue-105742.stderr
@@ -5,7 +5,7 @@ LL |     <Self as SVec>::Item,
    |                     ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -21,7 +21,7 @@ LL |     <Self as SVec>::Item,
    |                     ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -31,13 +31,13 @@ LL |     <Self as SVec>::Item<T>,
    |                         +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:22:37
+  --> $DIR/issue-105742.rs:24:37
    |
 LL |     Output = <Index<<Self as SVec>::Item,
    |                                     ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -47,13 +47,13 @@ LL |     Output = <Index<<Self as SVec>::Item<'a>,
    |                                         ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:22:37
+  --> $DIR/issue-105742.rs:24:37
    |
 LL |     Output = <Index<<Self as SVec>::Item,
    |                                     ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -63,13 +63,13 @@ LL |     Output = <Index<<Self as SVec>::Item<T>,
    |                                         +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:29:30
+  --> $DIR/issue-105742.rs:33:30
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                              ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -79,13 +79,13 @@ LL |     Output = <Self as SVec>::Item<'a>> as SVec>::Item,
    |                                  ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:29:30
+  --> $DIR/issue-105742.rs:33:30
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                              ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -95,13 +95,13 @@ LL |     Output = <Self as SVec>::Item<T>> as SVec>::Item,
    |                                  +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:29:46
+  --> $DIR/issue-105742.rs:33:46
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                                              ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -111,13 +111,13 @@ LL |     Output = <Self as SVec>::Item> as SVec>::Item<'a>,
    |                                                  ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:29:46
+  --> $DIR/issue-105742.rs:33:46
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                                              ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -133,7 +133,7 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) {
    |                                        ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -149,7 +149,7 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) {
    |                                        ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -165,7 +165,7 @@ LL |     <Self as SVec>::Item,
    |                     ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -181,7 +181,7 @@ LL |     <Self as SVec>::Item,
    |                     ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -191,13 +191,13 @@ LL |     <Self as SVec>::Item<T>,
    |                         +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:22:37
+  --> $DIR/issue-105742.rs:24:37
    |
 LL |     Output = <Index<<Self as SVec>::Item,
    |                                     ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -207,13 +207,13 @@ LL |     Output = <Index<<Self as SVec>::Item<'a>,
    |                                         ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:22:37
+  --> $DIR/issue-105742.rs:24:37
    |
 LL |     Output = <Index<<Self as SVec>::Item,
    |                                     ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -223,13 +223,13 @@ LL |     Output = <Index<<Self as SVec>::Item<T>,
    |                                         +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:29:30
+  --> $DIR/issue-105742.rs:33:30
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                              ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -239,13 +239,13 @@ LL |     Output = <Self as SVec>::Item<'a>> as SVec>::Item,
    |                                  ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:29:30
+  --> $DIR/issue-105742.rs:33:30
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                              ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -255,13 +255,13 @@ LL |     Output = <Self as SVec>::Item<T>> as SVec>::Item,
    |                                  +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:29:46
+  --> $DIR/issue-105742.rs:33:46
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                                              ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -271,13 +271,13 @@ LL |     Output = <Self as SVec>::Item> as SVec>::Item<'a>,
    |                                                  ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:29:46
+  --> $DIR/issue-105742.rs:33:46
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                                              ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -317,13 +317,141 @@ LL | |  > {
    | |__^ ...because it uses `Self` as a type parameter
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:45:38
+  --> $DIR/issue-105742.rs:15:21
+   |
+LL |     <Self as SVec>::Item,
+   |                     ^^^^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/issue-105742.rs:51:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^ --
+help: add missing lifetime argument
+   |
+LL |     <Self as SVec>::Item<'a>,
+   |                         ++++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:15:21
+   |
+LL |     <Self as SVec>::Item,
+   |                     ^^^^ expected 1 generic argument
+   |
+note: associated type defined here, with 1 generic parameter: `T`
+  --> $DIR/issue-105742.rs:51:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^     -
+help: add missing generic argument
+   |
+LL |     <Self as SVec>::Item<T>,
+   |                         +++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:24:37
+   |
+LL |     Output = <Index<<Self as SVec>::Item,
+   |                                     ^^^^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/issue-105742.rs:51:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^ --
+help: add missing lifetime argument
+   |
+LL |     Output = <Index<<Self as SVec>::Item<'a>,
+   |                                         ++++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:24:37
+   |
+LL |     Output = <Index<<Self as SVec>::Item,
+   |                                     ^^^^ expected 1 generic argument
+   |
+note: associated type defined here, with 1 generic parameter: `T`
+  --> $DIR/issue-105742.rs:51:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^     -
+help: add missing generic argument
+   |
+LL |     Output = <Index<<Self as SVec>::Item<T>,
+   |                                         +++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:33:30
+   |
+LL |     Output = <Self as SVec>::Item> as SVec>::Item,
+   |                              ^^^^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/issue-105742.rs:51:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^ --
+help: add missing lifetime argument
+   |
+LL |     Output = <Self as SVec>::Item<'a>> as SVec>::Item,
+   |                                  ++++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:33:30
+   |
+LL |     Output = <Self as SVec>::Item> as SVec>::Item,
+   |                              ^^^^ expected 1 generic argument
+   |
+note: associated type defined here, with 1 generic parameter: `T`
+  --> $DIR/issue-105742.rs:51:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^     -
+help: add missing generic argument
+   |
+LL |     Output = <Self as SVec>::Item<T>> as SVec>::Item,
+   |                                  +++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:33:46
+   |
+LL |     Output = <Self as SVec>::Item> as SVec>::Item,
+   |                                              ^^^^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/issue-105742.rs:51:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^ --
+help: add missing lifetime argument
+   |
+LL |     Output = <Self as SVec>::Item> as SVec>::Item<'a>,
+   |                                                  ++++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:33:46
+   |
+LL |     Output = <Self as SVec>::Item> as SVec>::Item,
+   |                                              ^^^^ expected 1 generic argument
+   |
+note: associated type defined here, with 1 generic parameter: `T`
+  --> $DIR/issue-105742.rs:51:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^     -
+help: add missing generic argument
+   |
+LL |     Output = <Self as SVec>::Item> as SVec>::Item<T>,
+   |                                                  +++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:53:38
    |
 LL |     fn len(&self) -> <Self as SVec>::Item;
    |                                      ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -333,13 +461,13 @@ LL |     fn len(&self) -> <Self as SVec>::Item<'_>;
    |                                          ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:45:38
+  --> $DIR/issue-105742.rs:53:38
    |
 LL |     fn len(&self) -> <Self as SVec>::Item;
    |                                      ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:43:10
+  --> $DIR/issue-105742.rs:51:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -348,7 +476,7 @@ help: add missing generic argument
 LL |     fn len(&self) -> <Self as SVec>::Item<T>;
    |                                          +++
 
-error: aborting due to 21 previous errors
+error: aborting due to 29 previous errors
 
 Some errors have detailed explanations: E0038, E0107.
 For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/associated-type-bounds/duplicate.rs b/tests/ui/associated-type-bounds/duplicate.rs
index f67410986e5..4b8bf52c374 100644
--- a/tests/ui/associated-type-bounds/duplicate.rs
+++ b/tests/ui/associated-type-bounds/duplicate.rs
@@ -193,10 +193,13 @@ trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
 //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
 trait TRS1: Iterator<Item: Copy, Item: Send> {}
 //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
+//~| ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
 trait TRS2: Iterator<Item: Copy, Item: Copy> {}
 //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
+//~| ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
 trait TRS3: Iterator<Item: 'static, Item: 'static> {}
 //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
+//~| ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
 trait TRW1<T>
 where
     T: Iterator<Item: Copy, Item: Send>,
diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr
index c3061327f56..08721eff7b0 100644
--- a/tests/ui/associated-type-bounds/duplicate.stderr
+++ b/tests/ui/associated-type-bounds/duplicate.stderr
@@ -367,7 +367,23 @@ LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:196:34
+  --> $DIR/duplicate.rs:194:34
+   |
+LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
+   |                      ----------  ^^^^^^^^^^ re-bound here
+   |                      |
+   |                      `Item` bound here first
+
+error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
+  --> $DIR/duplicate.rs:197:34
+   |
+LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
+   |                      ----------  ^^^^^^^^^^ re-bound here
+   |                      |
+   |                      `Item` bound here first
+
+error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
+  --> $DIR/duplicate.rs:197:34
    |
 LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -375,7 +391,15 @@ LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:198:37
+  --> $DIR/duplicate.rs:200:37
+   |
+LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
+   |                      -------------  ^^^^^^^^^^^^^ re-bound here
+   |                      |
+   |                      `Item` bound here first
+
+error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
+  --> $DIR/duplicate.rs:200:37
    |
 LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
    |                      -------------  ^^^^^^^^^^^^^ re-bound here
@@ -383,7 +407,7 @@ LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:202:29
+  --> $DIR/duplicate.rs:205:29
    |
 LL |     T: Iterator<Item: Copy, Item: Send>,
    |                 ----------  ^^^^^^^^^^ re-bound here
@@ -391,7 +415,7 @@ LL |     T: Iterator<Item: Copy, Item: Send>,
    |                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:208:29
+  --> $DIR/duplicate.rs:211:29
    |
 LL |     T: Iterator<Item: Copy, Item: Copy>,
    |                 ----------  ^^^^^^^^^^ re-bound here
@@ -399,7 +423,7 @@ LL |     T: Iterator<Item: Copy, Item: Copy>,
    |                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:214:32
+  --> $DIR/duplicate.rs:217:32
    |
 LL |     T: Iterator<Item: 'static, Item: 'static>,
    |                 -------------  ^^^^^^^^^^^^^ re-bound here
@@ -407,7 +431,7 @@ LL |     T: Iterator<Item: 'static, Item: 'static>,
    |                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:220:32
+  --> $DIR/duplicate.rs:223:32
    |
 LL |     Self: Iterator<Item: Copy, Item: Send>,
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -415,7 +439,7 @@ LL |     Self: Iterator<Item: Copy, Item: Send>,
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:220:32
+  --> $DIR/duplicate.rs:223:32
    |
 LL |     Self: Iterator<Item: Copy, Item: Send>,
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -423,7 +447,7 @@ LL |     Self: Iterator<Item: Copy, Item: Send>,
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:227:32
+  --> $DIR/duplicate.rs:230:32
    |
 LL |     Self: Iterator<Item: Copy, Item: Copy>,
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -431,7 +455,7 @@ LL |     Self: Iterator<Item: Copy, Item: Copy>,
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:227:32
+  --> $DIR/duplicate.rs:230:32
    |
 LL |     Self: Iterator<Item: Copy, Item: Copy>,
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -439,7 +463,7 @@ LL |     Self: Iterator<Item: Copy, Item: Copy>,
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:234:35
+  --> $DIR/duplicate.rs:237:35
    |
 LL |     Self: Iterator<Item: 'static, Item: 'static>,
    |                    -------------  ^^^^^^^^^^^^^ re-bound here
@@ -447,7 +471,7 @@ LL |     Self: Iterator<Item: 'static, Item: 'static>,
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:234:35
+  --> $DIR/duplicate.rs:237:35
    |
 LL |     Self: Iterator<Item: 'static, Item: 'static>,
    |                    -------------  ^^^^^^^^^^^^^ re-bound here
@@ -455,7 +479,7 @@ LL |     Self: Iterator<Item: 'static, Item: 'static>,
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:252:40
+  --> $DIR/duplicate.rs:255:40
    |
 LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -463,7 +487,7 @@ LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:254:44
+  --> $DIR/duplicate.rs:257:44
    |
 LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -471,7 +495,7 @@ LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:256:43
+  --> $DIR/duplicate.rs:259:43
    |
 LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
    |                            -------------  ^^^^^^^^^^^^^ re-bound here
@@ -479,7 +503,7 @@ LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:240:34
+  --> $DIR/duplicate.rs:243:34
    |
 LL |     type A: Iterator<Item: Copy, Item: Send>;
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -487,7 +511,7 @@ LL |     type A: Iterator<Item: Copy, Item: Send>;
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:244:34
+  --> $DIR/duplicate.rs:247:34
    |
 LL |     type A: Iterator<Item: Copy, Item: Copy>;
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -495,13 +519,13 @@ LL |     type A: Iterator<Item: Copy, Item: Copy>;
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:248:37
+  --> $DIR/duplicate.rs:251:37
    |
 LL |     type A: Iterator<Item: 'static, Item: 'static>;
    |                      -------------  ^^^^^^^^^^^^^ re-bound here
    |                      |
    |                      `Item` bound here first
 
-error: aborting due to 63 previous errors
+error: aborting due to 66 previous errors
 
 For more information about this error, try `rustc --explain E0719`.
diff --git a/tests/ui/associated-type-bounds/supertrait-defines-ty.rs b/tests/ui/associated-type-bounds/supertrait-defines-ty.rs
new file mode 100644
index 00000000000..b6f37cb908e
--- /dev/null
+++ b/tests/ui/associated-type-bounds/supertrait-defines-ty.rs
@@ -0,0 +1,26 @@
+// check-pass
+
+// Make sure that we don't look into associated type bounds when looking for
+// supertraits that define an associated type. Fixes #76593.
+
+#![feature(associated_type_bounds)]
+
+trait Load: Sized {
+    type Blob;
+}
+
+trait Primitive: Load<Blob = Self> {}
+
+trait BlobPtr: Primitive {}
+
+trait CleanPtr: Load<Blob: BlobPtr> {
+    fn to_blob(&self) -> Self::Blob;
+}
+
+impl Load for () {
+    type Blob = Self;
+}
+impl Primitive for () {}
+impl BlobPtr for () {}
+
+fn main() {}
diff --git a/tests/ui/const-generics/assoc_const_eq_diagnostic.rs b/tests/ui/const-generics/assoc_const_eq_diagnostic.rs
index 4d0aaf88e40..bf8202ac152 100644
--- a/tests/ui/const-generics/assoc_const_eq_diagnostic.rs
+++ b/tests/ui/const-generics/assoc_const_eq_diagnostic.rs
@@ -10,6 +10,7 @@ pub trait Parse {
 
 pub trait CoolStuff: Parse<MODE = Mode::Cool> {}
 //~^ ERROR expected associated constant bound
+//~| ERROR expected associated constant bound
 //~| ERROR expected type
 
 fn no_help() -> Mode::Cool {}
diff --git a/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr b/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr
index ba727ee0ea3..d7e5e50cba8 100644
--- a/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr
+++ b/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr
@@ -8,7 +8,7 @@ LL | pub trait CoolStuff: Parse<MODE = Mode::Cool> {}
    |                                   help: try using the variant's enum: `Mode`
 
 error[E0573]: expected type, found variant `Mode::Cool`
-  --> $DIR/assoc_const_eq_diagnostic.rs:15:17
+  --> $DIR/assoc_const_eq_diagnostic.rs:16:17
    |
 LL | fn no_help() -> Mode::Cool {}
    |                 ^^^^^^^^^^
@@ -28,6 +28,18 @@ note: associated constant defined here
 LL |     const MODE: Mode;
    |     ^^^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: expected associated constant bound, found type
+  --> $DIR/assoc_const_eq_diagnostic.rs:11:28
+   |
+LL | pub trait CoolStuff: Parse<MODE = Mode::Cool> {}
+   |                            ^^^^^^^^^^^^^^^^^ help: if equating a const, try wrapping with braces: `MODE = { const }`
+   |
+note: associated constant defined here
+  --> $DIR/assoc_const_eq_diagnostic.rs:8:5
+   |
+LL |     const MODE: Mode;
+   |     ^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0573`.
diff --git a/tests/ui/error-codes/E0719.rs b/tests/ui/error-codes/E0719.rs
index 3311e190937..cbf1bb219a0 100644
--- a/tests/ui/error-codes/E0719.rs
+++ b/tests/ui/error-codes/E0719.rs
@@ -1,5 +1,6 @@
 trait Foo: Iterator<Item = i32, Item = i32> {}
 //~^ ERROR is already specified
+//~| ERROR is already specified
 
 type Unit = ();
 
diff --git a/tests/ui/error-codes/E0719.stderr b/tests/ui/error-codes/E0719.stderr
index b342d634334..e302f406d02 100644
--- a/tests/ui/error-codes/E0719.stderr
+++ b/tests/ui/error-codes/E0719.stderr
@@ -7,13 +7,21 @@ LL | trait Foo: Iterator<Item = i32, Item = i32> {}
    |                     `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/E0719.rs:6:42
+  --> $DIR/E0719.rs:1:33
+   |
+LL | trait Foo: Iterator<Item = i32, Item = i32> {}
+   |                     ----------  ^^^^^^^^^^ re-bound here
+   |                     |
+   |                     `Item` bound here first
+
+error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
+  --> $DIR/E0719.rs:7:42
    |
 LL | fn test() -> Box<dyn Iterator<Item = (), Item = Unit>> {
    |                               ---------  ^^^^^^^^^^^ re-bound here
    |                               |
    |                               `Item` bound here first
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0719`.
diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr
index d4f42b787e4..97f346e8c1d 100644
--- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr
+++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr
@@ -4,5 +4,11 @@ error: ~const can only be applied to `#[const_trait]` traits
 LL | trait Bar: ~const Foo {}
    |                   ^^^
 
-error: aborting due to previous error
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-2.rs:11:19
+   |
+LL | trait Bar: ~const Foo {}
+   |                   ^^^
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr
index d4f42b787e4..97f346e8c1d 100644
--- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr
+++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr
@@ -4,5 +4,11 @@ error: ~const can only be applied to `#[const_trait]` traits
 LL | trait Bar: ~const Foo {}
    |                   ^^^
 
-error: aborting due to previous error
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-2.rs:11:19
+   |
+LL | trait Bar: ~const Foo {}
+   |                   ^^^
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs
index d183efde2df..ecb06271cd9 100644
--- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs
+++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs
@@ -10,6 +10,7 @@ trait Foo {
 #[cfg_attr(any(yy, ny), const_trait)]
 trait Bar: ~const Foo {}
 //[ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]`
+//[ny,nn]~| ERROR: ~const can only be applied to `#[const_trait]`
 
 const fn foo<T: Bar>(x: &T) {
     x.a();
diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr
index 13fc719f28c..c9fa1955498 100644
--- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr
+++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `T: ~const Foo` is not satisfied
-  --> $DIR/super-traits-fail-2.rs:15:7
+  --> $DIR/super-traits-fail-2.rs:16:7
    |
 LL |     x.a();
    |       ^ the trait `~const Foo` is not implemented for `T`
    |
 note: the trait `Foo` is implemented for `T`, but that implementation is not `const`
-  --> $DIR/super-traits-fail-2.rs:15:5
+  --> $DIR/super-traits-fail-2.rs:16:5
    |
 LL |     x.a();
    |     ^
diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr
index 13fc719f28c..c9fa1955498 100644
--- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr
+++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `T: ~const Foo` is not satisfied
-  --> $DIR/super-traits-fail-2.rs:15:7
+  --> $DIR/super-traits-fail-2.rs:16:7
    |
 LL |     x.a();
    |       ^ the trait `~const Foo` is not implemented for `T`
    |
 note: the trait `Foo` is implemented for `T`, but that implementation is not `const`
-  --> $DIR/super-traits-fail-2.rs:15:5
+  --> $DIR/super-traits-fail-2.rs:16:5
    |
 LL |     x.a();
    |     ^
diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr
index d433e1cfa69..fdc6b805889 100644
--- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr
+++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr
@@ -5,10 +5,16 @@ LL | trait Bar: ~const Foo {}
    |                   ^^^
 
 error: ~const can only be applied to `#[const_trait]` traits
-  --> $DIR/super-traits-fail-3.rs:15:24
+  --> $DIR/super-traits-fail-3.rs:12:19
+   |
+LL | trait Bar: ~const Foo {}
+   |                   ^^^
+
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:16:24
    |
 LL | const fn foo<T: ~const Bar>(x: &T) {
    |                        ^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr
index 2a7e8e00bc7..7375b8c819c 100644
--- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr
+++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr
@@ -4,5 +4,11 @@ error: ~const can only be applied to `#[const_trait]` traits
 LL | trait Bar: ~const Foo {}
    |                   ^^^
 
-error: aborting due to previous error
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:12:19
+   |
+LL | trait Bar: ~const Foo {}
+   |                   ^^^
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs
index 70d2936d3b2..8cf64944ac1 100644
--- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs
+++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs
@@ -11,6 +11,7 @@ trait Foo {
 #[cfg_attr(any(yy, ny), const_trait)]
 trait Bar: ~const Foo {}
 //[ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]`
+//[ny,nn]~| ERROR: ~const can only be applied to `#[const_trait]`
 
 const fn foo<T: ~const Bar>(x: &T) {
     //[yn,nn]~^ ERROR: ~const can only be applied to `#[const_trait]`
diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr
index e5978c12a09..7a152914b69 100644
--- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr
+++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr
@@ -1,5 +1,5 @@
 error: ~const can only be applied to `#[const_trait]` traits
-  --> $DIR/super-traits-fail-3.rs:15:24
+  --> $DIR/super-traits-fail-3.rs:16:24
    |
 LL | const fn foo<T: ~const Bar>(x: &T) {
    |                        ^^^
diff --git a/tests/ui/traits/issue-38404.rs b/tests/ui/traits/issue-38404.rs
index 1a92acc3404..05921b2c36e 100644
--- a/tests/ui/traits/issue-38404.rs
+++ b/tests/ui/traits/issue-38404.rs
@@ -2,5 +2,6 @@ trait A<T>: std::ops::Add<Self> + Sized {}
 trait B<T>: A<T> {}
 trait C<T>: A<dyn B<T, Output=usize>> {}
 //~^ ERROR the trait `B` cannot be made into an object
+//~| ERROR the trait `B` cannot be made into an object
 
 fn main() {}
diff --git a/tests/ui/traits/issue-38404.stderr b/tests/ui/traits/issue-38404.stderr
index d7721d7e69c..f8625f53b78 100644
--- a/tests/ui/traits/issue-38404.stderr
+++ b/tests/ui/traits/issue-38404.stderr
@@ -12,6 +12,20 @@ LL | trait A<T>: std::ops::Add<Self> + Sized {}
 LL | trait B<T>: A<T> {}
    |       - this trait cannot be made into an object...
 
-error: aborting due to previous error
+error[E0038]: the trait `B` cannot be made into an object
+  --> $DIR/issue-38404.rs:3:15
+   |
+LL | trait C<T>: A<dyn B<T, Output=usize>> {}
+   |               ^^^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-38404.rs:1:13
+   |
+LL | trait A<T>: std::ops::Add<Self> + Sized {}
+   |             ^^^^^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter
+LL | trait B<T>: A<T> {}
+   |       - this trait cannot be made into an object...
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs b/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs
index 7ff9199f63c..e7e62c07739 100644
--- a/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs
+++ b/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs
@@ -3,6 +3,7 @@ fn foo1<T:Copy<U>, U>(x: T) {}
 
 trait Trait: Copy<dyn Send> {}
 //~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied
+//~| ERROR trait takes 0 generic arguments but 1 generic argument was supplied
 
 struct MyStruct1<T: Copy<T>>;
 //~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied
diff --git a/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr b/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr
index a71fd953658..a3517af877c 100644
--- a/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr
+++ b/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr
@@ -15,7 +15,15 @@ LL | trait Trait: Copy<dyn Send> {}
    |              expected 0 generic arguments
 
 error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
-  --> $DIR/typeck-builtin-bound-type-parameters.rs:7:21
+  --> $DIR/typeck-builtin-bound-type-parameters.rs:4:14
+   |
+LL | trait Trait: Copy<dyn Send> {}
+   |              ^^^^---------- help: remove these generics
+   |              |
+   |              expected 0 generic arguments
+
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/typeck-builtin-bound-type-parameters.rs:8:21
    |
 LL | struct MyStruct1<T: Copy<T>>;
    |                     ^^^^--- help: remove these generics
@@ -23,7 +31,7 @@ LL | struct MyStruct1<T: Copy<T>>;
    |                     expected 0 generic arguments
 
 error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied
-  --> $DIR/typeck-builtin-bound-type-parameters.rs:10:25
+  --> $DIR/typeck-builtin-bound-type-parameters.rs:11:25
    |
 LL | struct MyStruct2<'a, T: Copy<'a>>;
    |                         ^^^^---- help: remove these generics
@@ -31,7 +39,7 @@ LL | struct MyStruct2<'a, T: Copy<'a>>;
    |                         expected 0 lifetime arguments
 
 error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied
-  --> $DIR/typeck-builtin-bound-type-parameters.rs:13:15
+  --> $DIR/typeck-builtin-bound-type-parameters.rs:14:15
    |
 LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
    |               ^^^^ -- help: remove this lifetime argument
@@ -39,13 +47,13 @@ LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
    |               expected 0 lifetime arguments
 
 error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
-  --> $DIR/typeck-builtin-bound-type-parameters.rs:13:15
+  --> $DIR/typeck-builtin-bound-type-parameters.rs:14:15
    |
 LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
    |               ^^^^     - help: remove this generic argument
    |               |
    |               expected 0 generic arguments
 
-error: aborting due to 6 previous errors
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0107`.