about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-12-04 02:04:26 +0000
committerMichael Goulet <michael@errs.io>2025-01-15 01:26:24 +0000
commit824a867e82b540503f8ae1f589445d9f9a8ce941 (patch)
tree593d3ceef3b46a46865bdfc2ac310977eac70ceb
parent8361aef0d7c29b1501a316a208ed84cd8a2ae5da (diff)
downloadrust-824a867e82b540503f8ae1f589445d9f9a8ce941.tar.gz
rust-824a867e82b540503f8ae1f589445d9f9a8ce941.zip
Rework trait expansion to happen once explicitly
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs203
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs50
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs11
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs209
-rw-r--r--compiler/rustc_type_ir/src/visit.rs8
-rw-r--r--tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr4
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr8
-rw-r--r--tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr12
-rw-r--r--tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr4
-rw-r--r--tests/ui/error-codes/E0225.stderr4
-rw-r--r--tests/ui/issues/issue-26056.stderr4
-rw-r--r--tests/ui/traits/alias/generic-default-in-dyn.rs4
-rw-r--r--tests/ui/traits/alias/generic-default-in-dyn.stderr30
-rw-r--r--tests/ui/traits/alias/no-duplicates.stderr234
-rw-r--r--tests/ui/traits/alias/no-extra-traits.stderr328
-rw-r--r--tests/ui/traits/alias/object-fail.rs2
-rw-r--r--tests/ui/traits/alias/object-fail.stderr13
-rw-r--r--tests/ui/traits/alias/self-in-const-generics.stderr14
-rw-r--r--tests/ui/traits/alias/self-in-generics.stderr16
-rw-r--r--tests/ui/traits/bad-sized.stderr8
-rw-r--r--tests/ui/traits/issue-28576.stderr5
-rw-r--r--tests/ui/traits/issue-38404.stderr12
-rw-r--r--tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs1
-rw-r--r--tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr10
26 files changed, 561 insertions, 642 deletions
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index 71a5727ed6c..72ad190df7e 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -4,13 +4,12 @@ use rustc_errors::struct_span_code_err;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS;
-use rustc_middle::span_bug;
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::{
     self, DynKind, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable,
     TypeVisitableExt, Upcast,
 };
-use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
+use rustc_span::{ErrorGuaranteed, Span};
 use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
 use rustc_trait_selection::traits::{self, hir_ty_lowering_dyn_compatibility_violations};
 use rustc_type_ir::elaborate::ClauseWithSupertraitSpan;
@@ -30,16 +29,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         &self,
         span: Span,
         hir_id: hir::HirId,
-        hir_trait_bounds: &[hir::PolyTraitRef<'tcx>],
+        hir_bounds: &[hir::PolyTraitRef<'tcx>],
         lifetime: &hir::Lifetime,
         representation: DynKind,
     ) -> Ty<'tcx> {
         let tcx = self.tcx();
+        let dummy_self = tcx.types.trait_object_dummy_self;
 
-        let mut bounds = Bounds::default();
+        let mut user_written_bounds = Bounds::default();
         let mut potential_assoc_types = Vec::new();
-        let dummy_self = self.tcx().types.trait_object_dummy_self;
-        for trait_bound in hir_trait_bounds.iter().rev() {
+        for trait_bound in hir_bounds.iter() {
             if let hir::BoundPolarity::Maybe(_) = trait_bound.modifiers.polarity {
                 continue;
             }
@@ -53,92 +52,67 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 hir::BoundConstness::Never,
                 hir::BoundPolarity::Positive,
                 dummy_self,
-                &mut bounds,
+                &mut user_written_bounds,
                 PredicateFilter::SelfOnly,
             ) {
                 potential_assoc_types.extend(cur_potential_assoc_types);
             }
         }
 
-        let mut trait_bounds = vec![];
-        let mut projection_bounds = vec![];
-        for (pred, span) in bounds.clauses() {
-            let bound_pred = pred.kind();
-            match bound_pred.skip_binder() {
-                ty::ClauseKind::Trait(trait_pred) => {
-                    assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive);
-                    trait_bounds.push((bound_pred.rebind(trait_pred.trait_ref), span));
-                }
-                ty::ClauseKind::Projection(proj) => {
-                    projection_bounds.push((bound_pred.rebind(proj), span));
-                }
-                ty::ClauseKind::TypeOutlives(_) => {
-                    // Do nothing, we deal with regions separately
-                }
-                ty::ClauseKind::RegionOutlives(_)
-                | ty::ClauseKind::ConstArgHasType(..)
-                | ty::ClauseKind::WellFormed(_)
-                | ty::ClauseKind::ConstEvaluatable(_)
-                | ty::ClauseKind::HostEffect(..) => {
-                    span_bug!(span, "did not expect {pred} clause in object bounds");
-                }
-            }
-        }
-
-        // Expand trait aliases recursively and check that only one regular (non-auto) trait
-        // is used and no 'maybe' bounds are used.
-        let expanded_traits =
-            traits::expand_trait_aliases(tcx, trait_bounds.iter().map(|&(a, b)| (a, b)));
-
-        let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) =
-            expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id()));
+        let (trait_bounds, mut projection_bounds) =
+            traits::expand_trait_aliases(tcx, user_written_bounds.clauses());
+        let (regular_traits, mut auto_traits): (Vec<_>, Vec<_>) = trait_bounds
+            .into_iter()
+            .partition(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id()));
 
+        // We  don't support empty trait objects.
+        if regular_traits.is_empty() && auto_traits.is_empty() {
+            let guar =
+                self.report_trait_object_with_no_traits_error(span, user_written_bounds.clauses());
+            return Ty::new_error(tcx, guar);
+        }
         // We don't support >1 principal
         if regular_traits.len() > 1 {
             let guar = self.report_trait_object_addition_traits_error(&regular_traits);
             return Ty::new_error(tcx, guar);
         }
-        // We  don't support empty trait objects.
-        if regular_traits.is_empty() && auto_traits.is_empty() {
-            let guar = self.report_trait_object_with_no_traits_error(span, &trait_bounds);
-            return Ty::new_error(tcx, guar);
-        }
         // Don't create a dyn trait if we have errors in the principal.
-        if let Err(guar) = trait_bounds.error_reported() {
+        if let Err(guar) = regular_traits.error_reported() {
             return Ty::new_error(tcx, guar);
         }
 
         // Check that there are no gross dyn-compatibility violations;
         // most importantly, that the supertraits don't contain `Self`,
         // to avoid ICEs.
-        for item in &regular_traits {
-            let violations =
-                hir_ty_lowering_dyn_compatibility_violations(tcx, item.trait_ref().def_id());
-            if !violations.is_empty() {
-                let reported = report_dyn_incompatibility(
-                    tcx,
-                    span,
-                    Some(hir_id),
-                    item.trait_ref().def_id(),
-                    &violations,
-                )
-                .emit();
-                return Ty::new_error(tcx, reported);
+        for (clause, span) in user_written_bounds.clauses() {
+            if let Some(trait_pred) = clause.as_trait_clause() {
+                let violations =
+                    hir_ty_lowering_dyn_compatibility_violations(tcx, trait_pred.def_id());
+                if !violations.is_empty() {
+                    let reported = report_dyn_incompatibility(
+                        tcx,
+                        span,
+                        Some(hir_id),
+                        trait_pred.def_id(),
+                        &violations,
+                    )
+                    .emit();
+                    return Ty::new_error(tcx, reported);
+                }
             }
         }
 
-        let mut needed_associated_types = FxIndexSet::default();
-
-        let principal_span = regular_traits.first().map_or(DUMMY_SP, |info| info.bottom().1);
-        let regular_traits_refs_spans = trait_bounds
-            .into_iter()
-            .filter(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id()));
+        let principal_trait = regular_traits.into_iter().next();
 
-        for (base_trait_ref, original_span) in regular_traits_refs_spans {
-            let base_pred: ty::Predicate<'tcx> = base_trait_ref.upcast(tcx);
+        let mut needed_associated_types = FxIndexSet::default();
+        if let Some((principal_trait, spans)) = &principal_trait {
+            let pred: ty::Predicate<'tcx> = (*principal_trait).upcast(tcx);
             for ClauseWithSupertraitSpan { pred, supertrait_span } in
-                traits::elaborate(tcx, [ClauseWithSupertraitSpan::new(base_pred, original_span)])
-                    .filter_only_self()
+                traits::elaborate(tcx, [ClauseWithSupertraitSpan::new(
+                    pred,
+                    *spans.last().unwrap(),
+                )])
+                .filter_only_self()
             {
                 debug!("observing object predicate `{pred:?}`");
 
@@ -179,7 +153,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         //     }
                         // ```
                         //
-                        // Here, the user could theoretically write `dyn MyTrait<Output = X>`,
+                        // Here, the user could theoretically write `dyn MyTrait<MyOutput = X>`,
                         // but actually supporting that would "expand" to an infinitely-long type
                         // `fix $ τ → dyn MyTrait<MyOutput = X, Output = <τ as MyTrait>::MyOutput`.
                         //
@@ -188,12 +162,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         // the discussion in #56288 for alternatives.
                         if !references_self {
                             // Include projections defined on supertraits.
-                            projection_bounds.push((pred, original_span));
+                            projection_bounds.push((pred, supertrait_span));
                         }
 
                         self.check_elaborated_projection_mentions_input_lifetimes(
                             pred,
-                            original_span,
+                            *spans.first().unwrap(),
                             supertrait_span,
                         );
                     }
@@ -202,11 +176,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             }
         }
 
-        // `dyn Trait<Assoc = Foo>` desugars to (not Rust syntax) `dyn Trait where <Self as Trait>::Assoc = Foo`.
-        // So every `Projection` clause is an `Assoc = Foo` bound. `associated_types` contains all associated
-        // types's `DefId`, so the following loop removes all the `DefIds` of the associated types that have a
-        // corresponding `Projection` clause
-        for (projection_bound, span) in &projection_bounds {
+        // `dyn Trait<Assoc = Foo>` desugars to (not Rust syntax) `dyn Trait where
+        // <Self as Trait>::Assoc = Foo`. So every `Projection` clause is an
+        // `Assoc = Foo` bound. `needed_associated_types` contains all associated
+        // types that we expect to be provided by the user, so the following loop
+        // removes all the associated types that have a corresponding `Projection`
+        // clause, either from expanding trait aliases or written by the user.
+        for &(projection_bound, span) in &projection_bounds {
             let def_id = projection_bound.item_def_id();
             let trait_ref = tcx.anonymize_bound_vars(
                 projection_bound.map_bound(|p| p.projection_term.trait_ref(tcx)),
@@ -216,17 +192,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 tcx.emit_node_span_lint(
                     UNUSED_ASSOCIATED_TYPE_BOUNDS,
                     hir_id,
-                    *span,
-                    crate::errors::UnusedAssociatedTypeBounds { span: *span },
+                    span,
+                    crate::errors::UnusedAssociatedTypeBounds { span },
                 );
             }
         }
 
         if let Err(guar) = self.check_for_required_assoc_tys(
-            principal_span,
+            principal_trait.as_ref().map_or(smallvec![], |(_, spans)| spans.clone()),
             needed_associated_types,
             potential_assoc_types,
-            hir_trait_bounds,
+            hir_bounds,
         ) {
             return Ty::new_error(tcx, guar);
         }
@@ -236,32 +212,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // We remove duplicates by inserting into a `FxHashSet` to avoid re-ordering
         // the bounds
         let mut duplicates = FxHashSet::default();
-        auto_traits.retain(|i| duplicates.insert(i.trait_ref().def_id()));
-        debug!(?regular_traits);
+        auto_traits.retain(|(trait_pred, _)| duplicates.insert(trait_pred.def_id()));
+
+        debug!(?principal_trait);
         debug!(?auto_traits);
 
         // Erase the `dummy_self` (`trait_object_dummy_self`) used above.
-        let existential_trait_refs = regular_traits.iter().map(|i| {
-            i.trait_ref().map_bound(|trait_ref: ty::TraitRef<'tcx>| {
+        let principal_trait_ref = principal_trait.map(|(trait_pred, spans)| {
+            trait_pred.map_bound(|trait_pred| {
+                let trait_ref = trait_pred.trait_ref;
+                assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive);
                 assert_eq!(trait_ref.self_ty(), dummy_self);
 
+                let span = *spans.first().unwrap();
+
                 // Verify that `dummy_self` did not leak inside default type parameters. This
                 // could not be done at path creation, since we need to see through trait aliases.
                 let mut missing_type_params = vec![];
-                let mut references_self = false;
                 let generics = tcx.generics_of(trait_ref.def_id);
                 let args: Vec<_> = trait_ref
                     .args
                     .iter()
                     .enumerate()
-                    .skip(1) // Remove `Self` for `ExistentialPredicate`.
+                    // Skip `Self`
+                    .skip(1)
                     .map(|(index, arg)| {
                         if arg == dummy_self.into() {
                             let param = &generics.own_params[index];
                             missing_type_params.push(param.name);
                             Ty::new_misc_error(tcx).into()
                         } else if arg.walk().any(|arg| arg == dummy_self.into()) {
-                            references_self = true;
                             let guar = self.dcx().span_delayed_bug(
                                 span,
                                 "trait object trait bounds reference `Self`",
@@ -273,8 +253,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     })
                     .collect();
 
-                let span = i.bottom().1;
-                let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| {
+                let empty_generic_args = hir_bounds.iter().any(|hir_bound| {
                     hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id)
                         && hir_bound.span.contains(span)
                 });
@@ -285,26 +264,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     empty_generic_args,
                 );
 
-                if references_self {
-                    let def_id = i.bottom().0.def_id();
-                    struct_span_code_err!(
-                        self.dcx(),
-                        i.bottom().1,
-                        E0038,
-                        "the {} `{}` cannot be made into an object",
-                        tcx.def_descr(def_id),
-                        tcx.item_name(def_id),
-                    )
-                    .with_note(
-                        rustc_middle::traits::DynCompatibilityViolation::SupertraitSelf(
-                            smallvec![],
-                        )
-                        .error_msg(),
-                    )
-                    .emit();
-                }
-
-                ty::ExistentialTraitRef::new(tcx, trait_ref.def_id, args)
+                ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::new(
+                    tcx,
+                    trait_ref.def_id,
+                    args,
+                ))
             })
         });
 
@@ -327,21 +291,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     b.projection_term = replace_dummy_self_with_error(tcx, b.projection_term, guar);
                 }
 
-                ty::ExistentialProjection::erase_self_ty(tcx, b)
+                ty::ExistentialPredicate::Projection(ty::ExistentialProjection::erase_self_ty(
+                    tcx, b,
+                ))
             })
         });
 
-        let regular_trait_predicates = existential_trait_refs
-            .map(|trait_ref| trait_ref.map_bound(ty::ExistentialPredicate::Trait));
-        let auto_trait_predicates = auto_traits.into_iter().map(|trait_ref| {
-            ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_ref.trait_ref().def_id()))
+        let auto_trait_predicates = auto_traits.into_iter().map(|(trait_pred, _)| {
+            assert_eq!(trait_pred.polarity(), ty::PredicatePolarity::Positive);
+            assert_eq!(trait_pred.self_ty().skip_binder(), dummy_self);
+
+            ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_pred.def_id()))
         });
+
         // N.b. principal, projections, auto traits
         // FIXME: This is actually wrong with multiple principals in regards to symbol mangling
-        let mut v = regular_trait_predicates
-            .chain(
-                existential_projections.map(|x| x.map_bound(ty::ExistentialPredicate::Projection)),
-            )
+        let mut v = principal_trait_ref
+            .into_iter()
+            .chain(existential_projections)
             .chain(auto_trait_predicates)
             .collect::<SmallVec<[_; 8]>>();
         v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 7a3d921f00e..5d751a25080 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -11,7 +11,7 @@ use rustc_hir::def_id::DefId;
 use rustc_middle::bug;
 use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
 use rustc_middle::ty::{
-    self, AdtDef, Binder, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeVisitableExt,
+    self, AdtDef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt,
     suggest_constraining_type_param,
 };
 use rustc_session::parse::feature_err;
@@ -19,8 +19,9 @@ use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol, kw, sym};
 use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
 use rustc_trait_selection::traits::{
-    FulfillmentError, TraitAliasExpansionInfo, dyn_compatibility_violations_for_assoc_item,
+    FulfillmentError, dyn_compatibility_violations_for_assoc_item,
 };
+use smallvec::SmallVec;
 
 use crate::errors::{
     self, AssocItemConstraintsNotAllowedHere, ManualImplementation, MissingTypeParams,
@@ -720,7 +721,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     /// emit a generic note suggesting using a `where` clause to constraint instead.
     pub(crate) fn check_for_required_assoc_tys(
         &self,
-        principal_span: Span,
+        spans: SmallVec<[Span; 1]>,
         missing_assoc_types: FxIndexSet<(DefId, ty::PolyTraitRef<'tcx>)>,
         potential_assoc_types: Vec<usize>,
         trait_bounds: &[hir::PolyTraitRef<'_>],
@@ -729,6 +730,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             return Ok(());
         }
 
+        let principal_span = *spans.first().unwrap();
+
         let tcx = self.tcx();
         // FIXME: This logic needs some more care w.r.t handling of conflicts
         let missing_assoc_types: Vec<_> = missing_assoc_types
@@ -1124,29 +1127,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
     pub fn report_trait_object_addition_traits_error(
         &self,
-        regular_traits: &Vec<TraitAliasExpansionInfo<'_>>,
+        regular_traits: &Vec<(ty::PolyTraitPredicate<'tcx>, SmallVec<[Span; 1]>)>,
     ) -> ErrorGuaranteed {
-        let first_trait = &regular_traits[0];
-        let additional_trait = &regular_traits[1];
+        // we use the last span to point at the traits themselves,
+        // and all other preceding spans are trait alias expansions.
+        let (&first_span, first_alias_spans) = regular_traits[0].1.split_last().unwrap();
+        let (&second_span, second_alias_spans) = regular_traits[1].1.split_last().unwrap();
         let mut err = struct_span_code_err!(
             self.dcx(),
-            additional_trait.bottom().1,
+            *regular_traits[1].1.first().unwrap(),
             E0225,
             "only auto traits can be used as additional traits in a trait object"
         );
-        additional_trait.label_with_exp_info(
-            &mut err,
-            "additional non-auto trait",
-            "additional use",
-        );
-        first_trait.label_with_exp_info(&mut err, "first non-auto trait", "first use");
+        err.span_label(first_span, "first non-auto trait");
+        for &alias_span in first_alias_spans {
+            err.span_label(alias_span, "first non-auto trait comes from this alias");
+        }
+        err.span_label(second_span, "additional non-auto trait");
+        for &alias_span in second_alias_spans {
+            err.span_label(alias_span, "second non-auto trait comes from this alias");
+        }
         err.help(format!(
             "consider creating a new trait with all of these as supertraits and using that \
              trait here instead: `trait NewTrait: {} {{}}`",
             regular_traits
                 .iter()
                 // FIXME: This should `print_sugared`, but also needs to integrate projection bounds...
-                .map(|t| t.trait_ref().print_only_trait_path().to_string())
+                .map(|(pred, _)| pred
+                    .map_bound(|pred| pred.trait_ref)
+                    .print_only_trait_path()
+                    .to_string())
                 .collect::<Vec<_>>()
                 .join(" + "),
         ));
@@ -1161,14 +1171,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     pub fn report_trait_object_with_no_traits_error(
         &self,
         span: Span,
-        trait_bounds: &Vec<(Binder<'tcx, TraitRef<'tcx>>, Span)>,
+        user_written_clauses: impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>,
     ) -> ErrorGuaranteed {
         let tcx = self.tcx();
-        let trait_alias_span = trait_bounds
-            .iter()
-            .map(|&(trait_ref, _)| trait_ref.def_id())
-            .find(|&trait_ref| tcx.is_trait_alias(trait_ref))
-            .map(|trait_ref| tcx.def_span(trait_ref));
+        let trait_alias_span = user_written_clauses
+            .into_iter()
+            .filter_map(|(clause, _)| clause.as_trait_clause())
+            .find(|trait_ref| tcx.is_trait_alias(trait_ref.def_id()))
+            .map(|trait_ref| tcx.def_span(trait_ref.def_id()));
 
         self.dcx().emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span })
     }
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 116765325a9..b9d1f93bfb8 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -1,6 +1,5 @@
 use std::cell::{Cell, RefCell};
 use std::cmp::max;
-use std::iter;
 use std::ops::Deref;
 
 use rustc_data_structures::fx::FxHashSet;
@@ -1009,11 +1008,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
 
         if self.tcx.is_trait_alias(trait_def_id) {
             // For trait aliases, recursively assume all explicitly named traits are relevant
-            for expansion in traits::expand_trait_aliases(
-                self.tcx,
-                iter::once((ty::Binder::dummy(trait_ref), self.span)),
-            ) {
-                let bound_trait_ref = expansion.trait_ref();
+            for (bound_trait_pred, _) in
+                traits::expand_trait_aliases(self.tcx, [(trait_ref.upcast(self.tcx), self.span)]).0
+            {
+                assert_eq!(bound_trait_pred.polarity(), ty::PredicatePolarity::Positive);
+                let bound_trait_ref = bound_trait_pred.map_bound(|pred| pred.trait_ref);
                 for item in self.impl_or_trait_item(bound_trait_ref.def_id()) {
                     if !self.has_applicable_self(&item) {
                         self.record_static_candidate(CandidateSource::Trait(
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
index cd4f77bb4cf..592aee24ccc 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
@@ -437,7 +437,8 @@ pub fn report_dyn_incompatibility<'tcx>(
         tcx.dcx(),
         span,
         E0038,
-        "the trait `{}` cannot be made into an object",
+        "the {} `{}` cannot be made into an object",
+        tcx.def_descr(trait_def_id),
         trait_str
     );
     err.span_label(span, format!("`{trait_str}` cannot be made into an object"));
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index da16a742099..7a485419444 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -66,9 +66,9 @@ pub use self::specialize::{
 };
 pub use self::structural_normalize::StructurallyNormalizeExt;
 pub use self::util::{
-    BoundVarReplacer, PlaceholderReplacer, TraitAliasExpander, TraitAliasExpansionInfo, elaborate,
-    expand_trait_aliases, impl_item_is_final, supertraits,
-    transitive_bounds_that_define_assoc_item, upcast_choices, with_replaced_escaping_bound_vars,
+    BoundVarReplacer, PlaceholderReplacer, elaborate, expand_trait_aliases, impl_item_is_final,
+    supertraits, transitive_bounds_that_define_assoc_item, upcast_choices,
+    with_replaced_escaping_bound_vars,
 };
 use crate::error_reporting::InferCtxtErrorExt;
 use crate::infer::outlives::env::OutlivesEnvironment;
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index da1045b664a..c9fb2a757e1 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -1,162 +1,85 @@
-use std::collections::BTreeMap;
+use std::collections::{BTreeMap, VecDeque};
 
-use rustc_data_structures::fx::FxIndexMap;
-use rustc_errors::Diag;
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::InferCtxt;
 pub use rustc_infer::traits::util::*;
 use rustc_middle::bug;
 use rustc_middle::ty::{
-    self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, Upcast,
+    self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
 };
 use rustc_span::Span;
 use smallvec::{SmallVec, smallvec};
 use tracing::debug;
 
-///////////////////////////////////////////////////////////////////////////
-// `TraitAliasExpander` iterator
-///////////////////////////////////////////////////////////////////////////
-
-/// "Trait alias expansion" is the process of expanding a sequence of trait
-/// references into another sequence by transitively following all trait
-/// aliases. e.g. If you have bounds like `Foo + Send`, a trait alias
-/// `trait Foo = Bar + Sync;`, and another trait alias
-/// `trait Bar = Read + Write`, then the bounds would expand to
-/// `Read + Write + Sync + Send`.
-/// Expansion is done via a DFS (depth-first search), and the `visited` field
-/// is used to avoid cycles.
-pub struct TraitAliasExpander<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    stack: Vec<TraitAliasExpansionInfo<'tcx>>,
-}
-
-/// Stores information about the expansion of a trait via a path of zero or more trait aliases.
-#[derive(Debug, Clone)]
-pub struct TraitAliasExpansionInfo<'tcx> {
-    pub path: SmallVec<[(ty::PolyTraitRef<'tcx>, Span); 4]>,
-}
-
-impl<'tcx> TraitAliasExpansionInfo<'tcx> {
-    fn new(trait_ref: ty::PolyTraitRef<'tcx>, span: Span) -> Self {
-        Self { path: smallvec![(trait_ref, span)] }
-    }
-
-    /// Adds diagnostic labels to `diag` for the expansion path of a trait through all intermediate
-    /// trait aliases.
-    pub fn label_with_exp_info(
-        &self,
-        diag: &mut Diag<'_>,
-        top_label: &'static str,
-        use_desc: &str,
-    ) {
-        diag.span_label(self.top().1, top_label);
-        if self.path.len() > 1 {
-            for (_, sp) in self.path.iter().rev().skip(1).take(self.path.len() - 2) {
-                diag.span_label(*sp, format!("referenced here ({use_desc})"));
-            }
-        }
-        if self.top().1 != self.bottom().1 {
-            // When the trait object is in a return type these two spans match, we don't want
-            // redundant labels.
-            diag.span_label(
-                self.bottom().1,
-                format!("trait alias used in trait object type ({use_desc})"),
-            );
-        }
-    }
-
-    pub fn trait_ref(&self) -> ty::PolyTraitRef<'tcx> {
-        self.top().0
-    }
-
-    pub fn top(&self) -> &(ty::PolyTraitRef<'tcx>, Span) {
-        self.path.last().unwrap()
-    }
-
-    pub fn bottom(&self) -> &(ty::PolyTraitRef<'tcx>, Span) {
-        self.path.first().unwrap()
-    }
-
-    fn clone_and_push(&self, trait_ref: ty::PolyTraitRef<'tcx>, span: Span) -> Self {
-        let mut path = self.path.clone();
-        path.push((trait_ref, span));
-
-        Self { path }
-    }
-}
-
+/// Return the trait and projection predicates that come from eagerly expanding the
+/// trait aliases in the list of clauses. For each trait predicate, record a stack
+/// of spans that trace from the user-written trait alias bound. For projection predicates,
+/// just record the span of the projection itself.
+///
+/// For trait aliases, we don't deduplicte the predicates, since we currently do not
+/// consider duplicated traits as a single trait for the purposes of our "one trait principal"
+/// restriction; however, for projections we do deduplicate them.
+///
+/// ```rust,ignore (fails)
+/// trait Bar {}
+/// trait Foo = Bar + Bar;
+///
+/// let not_object_safe: dyn Foo; // bad, two `Bar` principals.
+/// ```
 pub fn expand_trait_aliases<'tcx>(
     tcx: TyCtxt<'tcx>,
-    trait_refs: impl Iterator<Item = (ty::PolyTraitRef<'tcx>, Span)>,
-) -> TraitAliasExpander<'tcx> {
-    let items: Vec<_> =
-        trait_refs.map(|(trait_ref, span)| TraitAliasExpansionInfo::new(trait_ref, span)).collect();
-    TraitAliasExpander { tcx, stack: items }
-}
-
-impl<'tcx> TraitAliasExpander<'tcx> {
-    /// If `item` is a trait alias and its predicate has not yet been visited, then expands `item`
-    /// to the definition, pushes the resulting expansion onto `self.stack`, and returns `false`.
-    /// Otherwise, immediately returns `true` if `item` is a regular trait, or `false` if it is a
-    /// trait alias.
-    /// The return value indicates whether `item` should be yielded to the user.
-    fn expand(&mut self, item: &TraitAliasExpansionInfo<'tcx>) -> bool {
-        let tcx = self.tcx;
-        let trait_ref = item.trait_ref();
-        let pred = trait_ref.upcast(tcx);
-
-        debug!("expand_trait_aliases: trait_ref={:?}", trait_ref);
-
-        // Don't recurse if this bound is not a trait alias.
-        let is_alias = tcx.is_trait_alias(trait_ref.def_id());
-        if !is_alias {
-            return true;
-        }
-
-        // Don't recurse if this trait alias is already on the stack for the DFS search.
-        let anon_pred = anonymize_predicate(tcx, pred);
-        if item
-            .path
-            .iter()
-            .rev()
-            .skip(1)
-            .any(|&(tr, _)| anonymize_predicate(tcx, tr.upcast(tcx)) == anon_pred)
-        {
-            return false;
-        }
-
-        // Get components of trait alias.
-        let predicates = tcx.explicit_super_predicates_of(trait_ref.def_id());
-        debug!(?predicates);
-
-        let items = predicates.skip_binder().iter().rev().filter_map(|(pred, span)| {
-            pred.instantiate_supertrait(tcx, trait_ref)
-                .as_trait_clause()
-                .map(|trait_ref| item.clone_and_push(trait_ref.map_bound(|t| t.trait_ref), *span))
-        });
-        debug!("expand_trait_aliases: items={:?}", items.clone().collect::<Vec<_>>());
-
-        self.stack.extend(items);
-
-        false
-    }
-}
-
-impl<'tcx> Iterator for TraitAliasExpander<'tcx> {
-    type Item = TraitAliasExpansionInfo<'tcx>;
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.stack.len(), None)
-    }
-
-    fn next(&mut self) -> Option<TraitAliasExpansionInfo<'tcx>> {
-        while let Some(item) = self.stack.pop() {
-            if self.expand(&item) {
-                return Some(item);
+    clauses: impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>,
+) -> (
+    Vec<(ty::PolyTraitPredicate<'tcx>, SmallVec<[Span; 1]>)>,
+    Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>,
+) {
+    let mut trait_preds = vec![];
+    let mut projection_preds = vec![];
+    let mut seen_projection_preds = FxHashSet::default();
+
+    let mut queue: VecDeque<_> = clauses.into_iter().map(|(p, s)| (p, smallvec![s])).collect();
+
+    while let Some((clause, spans)) = queue.pop_front() {
+        match clause.kind().skip_binder() {
+            ty::ClauseKind::Trait(trait_pred) => {
+                if tcx.is_trait_alias(trait_pred.def_id()) {
+                    queue.extend(
+                        tcx.explicit_super_predicates_of(trait_pred.def_id())
+                            .iter_identity_copied()
+                            .map(|(clause, span)| {
+                                let mut spans = spans.clone();
+                                spans.push(span);
+                                (
+                                    clause.instantiate_supertrait(
+                                        tcx,
+                                        clause.kind().rebind(trait_pred.trait_ref),
+                                    ),
+                                    spans,
+                                )
+                            }),
+                    );
+                } else {
+                    trait_preds.push((clause.kind().rebind(trait_pred), spans));
+                }
             }
+            ty::ClauseKind::Projection(projection_pred) => {
+                let projection_pred = clause.kind().rebind(projection_pred);
+                if !seen_projection_preds.insert(tcx.anonymize_bound_vars(projection_pred)) {
+                    continue;
+                }
+                projection_preds.push((projection_pred, *spans.last().unwrap()));
+            }
+            ty::ClauseKind::RegionOutlives(..)
+            | ty::ClauseKind::TypeOutlives(..)
+            | ty::ClauseKind::ConstArgHasType(_, _)
+            | ty::ClauseKind::WellFormed(_)
+            | ty::ClauseKind::ConstEvaluatable(_)
+            | ty::ClauseKind::HostEffect(..) => {}
         }
-        None
     }
+
+    (trait_preds, projection_preds)
 }
 
 ///////////////////////////////////////////////////////////////////////////
diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs
index 71c3646498b..3213638afb2 100644
--- a/compiler/rustc_type_ir/src/visit.rs
+++ b/compiler/rustc_type_ir/src/visit.rs
@@ -47,6 +47,7 @@ use std::ops::ControlFlow;
 use rustc_ast_ir::visit::VisitorResult;
 use rustc_ast_ir::{try_visit, walk_visitable_list};
 use rustc_index::{Idx, IndexVec};
+use smallvec::SmallVec;
 use thin_vec::ThinVec;
 
 use crate::data_structures::Lrc;
@@ -192,6 +193,13 @@ impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for ThinVec<T> {
     }
 }
 
+impl<I: Interner, T: TypeVisitable<I>, const N: usize> TypeVisitable<I> for SmallVec<[T; N]> {
+    fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
+        walk_visitable_list!(visitor, self.iter());
+        V::Result::output()
+    }
+}
+
 // `TypeFoldable` isn't impl'd for `&[T]`. It doesn't make sense in the general
 // case, because we can't return a new slice. But note that there are a couple
 // of trivial impls of `TypeFoldable` for specific slice types elsewhere.
diff --git a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr
index f9080bf0785..97bd44244f3 100644
--- a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr
+++ b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr
@@ -295,10 +295,10 @@ LL |     Output = <Self as SVec>::Item> as SVec>::Item<T>,
    |                                                  +++
 
 error[E0038]: the trait `SVec` cannot be made into an object
-  --> $DIR/ice-generic-type-alias-105742.rs:5:31
+  --> $DIR/ice-generic-type-alias-105742.rs:5:35
    |
 LL | pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) {
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SVec` cannot be made into an object
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^ `SVec` cannot be made into an object
    |
 note: for a trait to be "dyn-compatible" 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/ice-generic-type-alias-105742.rs:15:17
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr
index 84281eb53c9..7cd5754be8a 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr
@@ -1,8 +1,8 @@
 error[E0038]: the trait `ConstParamTy_` cannot be made into an object
-  --> $DIR/const_param_ty_dyn_compatibility.rs:6:12
+  --> $DIR/const_param_ty_dyn_compatibility.rs:6:16
    |
 LL | fn foo(a: &dyn ConstParamTy_) {}
-   |            ^^^^^^^^^^^^^^^^^ `ConstParamTy_` cannot be made into an object
+   |                ^^^^^^^^^^^^^ `ConstParamTy_` cannot be made into an object
    |
 note: for a trait to be "dyn-compatible" 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>
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
@@ -14,10 +14,10 @@ LL | fn foo(a: &impl ConstParamTy_) {}
    |            ~~~~
 
 error[E0038]: the trait `UnsizedConstParamTy` cannot be made into an object
-  --> $DIR/const_param_ty_dyn_compatibility.rs:9:12
+  --> $DIR/const_param_ty_dyn_compatibility.rs:9:16
    |
 LL | fn bar(a: &dyn UnsizedConstParamTy) {}
-   |            ^^^^^^^^^^^^^^^^^^^^^^^ `UnsizedConstParamTy` cannot be made into an object
+   |                ^^^^^^^^^^^^^^^^^^^ `UnsizedConstParamTy` cannot be made into an object
    |
 note: for a trait to be "dyn-compatible" 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>
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
diff --git a/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr b/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr
index 7578edce7d1..03e57841b1b 100644
--- a/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr
+++ b/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr
@@ -1,8 +1,8 @@
 error[E0038]: the trait `Expr` cannot be made into an object
-  --> $DIR/mentions-Self-in-super-predicates.rs:12:23
+  --> $DIR/mentions-Self-in-super-predicates.rs:12:27
    |
 LL |     elements: Vec<Box<dyn Expr + 'x>>,
-   |                       ^^^^^^^^^^^^^ `Expr` cannot be made into an object
+   |                           ^^^^ `Expr` cannot be made into an object
    |
 note: for a trait to be "dyn-compatible" 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/mentions-Self-in-super-predicates.rs:5:21
@@ -14,10 +14,10 @@ LL | trait Expr: Debug + PartialEq {
    = help: only type `SExpr<'x>` implements the trait, consider using it directly instead
 
 error[E0038]: the trait `Expr` cannot be made into an object
-  --> $DIR/mentions-Self-in-super-predicates.rs:38:16
+  --> $DIR/mentions-Self-in-super-predicates.rs:38:20
    |
 LL |     let a: Box<dyn Expr> = Box::new(SExpr::new());
-   |                ^^^^^^^^ `Expr` cannot be made into an object
+   |                    ^^^^ `Expr` cannot be made into an object
    |
 note: for a trait to be "dyn-compatible" 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/mentions-Self-in-super-predicates.rs:5:21
@@ -29,10 +29,10 @@ LL | trait Expr: Debug + PartialEq {
    = help: only type `SExpr<'x>` implements the trait, consider using it directly instead
 
 error[E0038]: the trait `Expr` cannot be made into an object
-  --> $DIR/mentions-Self-in-super-predicates.rs:40:16
+  --> $DIR/mentions-Self-in-super-predicates.rs:40:20
    |
 LL |     let b: Box<dyn Expr> = Box::new(SExpr::new());
-   |                ^^^^^^^^ `Expr` cannot be made into an object
+   |                    ^^^^ `Expr` cannot be made into an object
    |
 note: for a trait to be "dyn-compatible" 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/mentions-Self-in-super-predicates.rs:5:21
diff --git a/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr b/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr
index 6474b115c46..abeafa1967f 100644
--- a/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr
+++ b/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr
@@ -19,10 +19,10 @@ LL | trait Bar<T: ?Sized> {
    |            ++++++++
 
 error[E0038]: the trait `Baz` cannot be made into an object
-  --> $DIR/supertrait-mentions-Self.rs:16:31
+  --> $DIR/supertrait-mentions-Self.rs:16:35
    |
 LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
-   |                               ^^^^^^^ `Baz` cannot be made into an object
+   |                                   ^^^ `Baz` cannot be made into an object
    |
 note: for a trait to be "dyn-compatible" 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/supertrait-mentions-Self.rs:8:13
diff --git a/tests/ui/error-codes/E0225.stderr b/tests/ui/error-codes/E0225.stderr
index a4b33a0b7b4..e6781282c8f 100644
--- a/tests/ui/error-codes/E0225.stderr
+++ b/tests/ui/error-codes/E0225.stderr
@@ -20,8 +20,8 @@ LL | trait Foo = std::io::Read + std::io::Write;
 LL |     let _: Box<dyn Foo>;
    |                    ^^^
    |                    |
-   |                    trait alias used in trait object type (additional use)
-   |                    trait alias used in trait object type (first use)
+   |                    first non-auto trait comes from this alias
+   |                    second non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: std::io::Read + std::io::Write {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
diff --git a/tests/ui/issues/issue-26056.stderr b/tests/ui/issues/issue-26056.stderr
index be5453ec19d..c5ae41200f6 100644
--- a/tests/ui/issues/issue-26056.stderr
+++ b/tests/ui/issues/issue-26056.stderr
@@ -1,8 +1,8 @@
 error[E0038]: the trait `Map` cannot be made into an object
-  --> $DIR/issue-26056.rs:20:13
+  --> $DIR/issue-26056.rs:20:17
    |
 LL |         as &dyn Map<Key=u32,MapValue=u32>;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Map` cannot be made into an object
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ `Map` cannot be made into an object
    |
 note: for a trait to be "dyn-compatible" 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-26056.rs:9:12
diff --git a/tests/ui/traits/alias/generic-default-in-dyn.rs b/tests/ui/traits/alias/generic-default-in-dyn.rs
index d44e1c2a975..b180f0a6803 100644
--- a/tests/ui/traits/alias/generic-default-in-dyn.rs
+++ b/tests/ui/traits/alias/generic-default-in-dyn.rs
@@ -2,9 +2,9 @@ trait SendEqAlias<T> = PartialEq;
 //~^ ERROR trait aliases are experimental
 
 struct Foo<T>(dyn SendEqAlias<T>);
-//~^ ERROR the type parameter `Rhs` must be explicitly specified [E0393]
+//~^ ERROR the trait alias `SendEqAlias` cannot be made into an object
 
 struct Bar<T>(dyn SendEqAlias<T>, T);
-//~^ ERROR the type parameter `Rhs` must be explicitly specified [E0393]
+//~^ ERROR the trait alias `SendEqAlias` cannot be made into an object
 
 fn main() {}
diff --git a/tests/ui/traits/alias/generic-default-in-dyn.stderr b/tests/ui/traits/alias/generic-default-in-dyn.stderr
index 50031e184c1..902d18de944 100644
--- a/tests/ui/traits/alias/generic-default-in-dyn.stderr
+++ b/tests/ui/traits/alias/generic-default-in-dyn.stderr
@@ -8,29 +8,35 @@ LL | trait SendEqAlias<T> = PartialEq;
    = help: add `#![feature(trait_alias)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0393]: the type parameter `Rhs` must be explicitly specified
+error[E0038]: the trait alias `SendEqAlias` cannot be made into an object
   --> $DIR/generic-default-in-dyn.rs:4:19
    |
 LL | struct Foo<T>(dyn SendEqAlias<T>);
-   |                   ^^^^^^^^^^^^^^ missing reference to `Rhs`
-  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |                   ^^^^^^^^^^^^^^ `SendEqAlias` cannot be made into an object
    |
-   = note: type parameter `Rhs` must be specified for this
+note: for a trait to be "dyn-compatible" 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/generic-default-in-dyn.rs:1:24
    |
-   = note: because of the default `Self` reference, type parameters must be specified on object types
+LL | trait SendEqAlias<T> = PartialEq;
+   |       -----------      ^^^^^^^^^ ...because it uses `Self` as a type parameter
+   |       |
+   |       this trait cannot be made into an object...
 
-error[E0393]: the type parameter `Rhs` must be explicitly specified
+error[E0038]: the trait alias `SendEqAlias` cannot be made into an object
   --> $DIR/generic-default-in-dyn.rs:7:19
    |
 LL | struct Bar<T>(dyn SendEqAlias<T>, T);
-   |                   ^^^^^^^^^^^^^^ missing reference to `Rhs`
-  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |                   ^^^^^^^^^^^^^^ `SendEqAlias` cannot be made into an object
    |
-   = note: type parameter `Rhs` must be specified for this
+note: for a trait to be "dyn-compatible" 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/generic-default-in-dyn.rs:1:24
    |
-   = note: because of the default `Self` reference, type parameters must be specified on object types
+LL | trait SendEqAlias<T> = PartialEq;
+   |       -----------      ^^^^^^^^^ ...because it uses `Self` as a type parameter
+   |       |
+   |       this trait cannot be made into an object...
 
 error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0393, E0658.
-For more information about an error, try `rustc --explain E0393`.
+Some errors have detailed explanations: E0038, E0658.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/traits/alias/no-duplicates.stderr b/tests/ui/traits/alias/no-duplicates.stderr
index bf244b97e9b..6a901a80554 100644
--- a/tests/ui/traits/alias/no-duplicates.stderr
+++ b/tests/ui/traits/alias/no-duplicates.stderr
@@ -4,32 +4,32 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _0 = Obj;
    |            ---
    |            |
-   |            additional non-auto trait
    |            first non-auto trait
+   |            additional non-auto trait
 ...
 LL | type _T00 = dyn _0 + _0;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 --   ^^ second non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-duplicates.rs:19:22
+  --> $DIR/no-duplicates.rs:19:17
    |
 LL | trait _0 = Obj;
    |            ---
    |            |
-   |            additional non-auto trait
    |            first non-auto trait
+   |            additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | type _T01 = dyn _1 + _0;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 ^^   -- first non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -40,18 +40,18 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _0 = Obj;
    |            ---
    |            |
-   |            additional non-auto trait
    |            first non-auto trait
+   |            additional non-auto trait
 LL | trait _1 = _0;
    |            --
    |            |
-   |            referenced here (additional use)
-   |            referenced here (first use)
+   |            first non-auto trait comes from this alias
+   |            second non-auto trait comes from this alias
 ...
 LL | type _T02 = dyn _1 + _1;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 --   ^^ second non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -62,10 +62,10 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _0 = Obj;
    |            --- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | type _T03 = dyn Obj + _1;
-   |                 ---   ^^ trait alias used in trait object type (additional use)
+   |                 ---   ^^ second non-auto trait comes from this alias
    |                 |
    |                 first non-auto trait
    |
@@ -73,17 +73,17 @@ LL | type _T03 = dyn Obj + _1;
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-duplicates.rs:28:22
+  --> $DIR/no-duplicates.rs:28:17
    |
 LL | trait _0 = Obj;
-   |            --- first non-auto trait
+   |            --- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | type _T04 = dyn _1 + Obj;
-   |                 --   ^^^ additional non-auto trait
+   |                 ^^   --- first non-auto trait
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -92,23 +92,17 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
   --> $DIR/no-duplicates.rs:37:17
    |
 LL | trait _0 = Obj;
-   |            ---
-   |            |
-   |            additional non-auto trait
-   |            first non-auto trait
-LL | trait _1 = _0;
-   |            -- referenced here (additional use)
+   |            --- additional non-auto trait
 ...
 LL | trait _2 = _0 + _1;
-   |            --   -- referenced here (additional use)
-   |            |
-   |            referenced here (first use)
+   |            -- second non-auto trait comes from this alias
+LL | trait _3 = Obj;
+   |            --- first non-auto trait
 ...
 LL | type _T10 = dyn _2 + _3;
-   |                 ^^
+   |                 ^^   -- first non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (additional use)
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -120,14 +114,14 @@ LL | trait _0 = Obj;
    |            --- additional non-auto trait
 ...
 LL | trait _2 = _0 + _1;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 LL | trait _3 = Obj;
    |            --- first non-auto trait
 ...
 LL | type _T11 = dyn _3 + _2;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 --   ^^ second non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -139,10 +133,10 @@ LL | trait _0 = Obj;
    |            --- additional non-auto trait
 ...
 LL | trait _2 = _0 + _1;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | type _T12 = dyn Obj + _2;
-   |                 ---   ^^ trait alias used in trait object type (additional use)
+   |                 ---   ^^ second non-auto trait comes from this alias
    |                 |
    |                 first non-auto trait
    |
@@ -153,42 +147,34 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
   --> $DIR/no-duplicates.rs:46:17
    |
 LL | trait _0 = Obj;
-   |            ---
-   |            |
-   |            additional non-auto trait
-   |            first non-auto trait
-LL | trait _1 = _0;
-   |            -- referenced here (additional use)
+   |            --- additional non-auto trait
 ...
 LL | trait _2 = _0 + _1;
-   |            --   -- referenced here (additional use)
-   |            |
-   |            referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | type _T13 = dyn _2 + Obj;
-   |                 ^^
+   |                 ^^   --- first non-auto trait
    |                 |
-   |                 trait alias used in trait object type (additional use)
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-duplicates.rs:49:22
+  --> $DIR/no-duplicates.rs:49:17
    |
 LL | trait _0 = Obj;
-   |            --- first non-auto trait
+   |            --- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | trait _3 = Obj;
-   |            --- additional non-auto trait
+   |            --- first non-auto trait
 ...
 LL | type _T14 = dyn _1 + _3;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 ^^   -- first non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -199,15 +185,15 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _0 = Obj;
    |            --- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | trait _3 = Obj;
    |            --- first non-auto trait
 ...
 LL | type _T15 = dyn _3 + _1;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 --   ^^ second non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -218,17 +204,17 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _0 = Obj;
    |            --- first non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (first use)
+   |            -- first non-auto trait comes from this alias
 ...
 LL | trait _3 = Obj;
    |            --- additional non-auto trait
 LL | trait _4 = _3;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | type _T16 = dyn _1 + _4;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 --   ^^ second non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -239,17 +225,17 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _0 = Obj;
    |            --- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | trait _3 = Obj;
    |            --- first non-auto trait
 LL | trait _4 = _3;
-   |            -- referenced here (first use)
+   |            -- first non-auto trait comes from this alias
 ...
 LL | type _T17 = dyn _4 + _1;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 --   ^^ second non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -260,13 +246,13 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _5 = Obj + Send;
    |            ---
    |            |
-   |            additional non-auto trait
    |            first non-auto trait
+   |            additional non-auto trait
 LL |
 LL | type _T20 = dyn _5 + _5;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 --   ^^ second non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -278,7 +264,7 @@ LL | trait _5 = Obj + Send;
    |            --- additional non-auto trait
 ...
 LL | type _T21 = dyn Obj + _5;
-   |                 ---   ^^ trait alias used in trait object type (additional use)
+   |                 ---   ^^ second non-auto trait comes from this alias
    |                 |
    |                 first non-auto trait
    |
@@ -286,29 +272,29 @@ LL | type _T21 = dyn Obj + _5;
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-duplicates.rs:71:22
+  --> $DIR/no-duplicates.rs:71:17
    |
 LL | trait _5 = Obj + Send;
-   |            --- first non-auto trait
+   |            --- additional non-auto trait
 ...
 LL | type _T22 = dyn _5 + Obj;
-   |                 --   ^^^ additional non-auto trait
+   |                 ^^   --- first non-auto trait
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-duplicates.rs:74:36
+  --> $DIR/no-duplicates.rs:74:17
    |
 LL | trait _5 = Obj + Send;
-   |            --- first non-auto trait
+   |            --- additional non-auto trait
 ...
 LL | type _T23 = dyn _5 + Send + Sync + Obj;
-   |                 --                 ^^^ additional non-auto trait
+   |                 ^^                 --- first non-auto trait
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -319,19 +305,19 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _5 = Obj + Send;
    |            ---
    |            |
-   |            additional non-auto trait
    |            first non-auto trait
+   |            additional non-auto trait
 ...
 LL | trait _6 = _5 + _5; // ==> Obj + Send + Obj + Send
-   |            --   -- referenced here (additional use)
+   |            --   -- second non-auto trait comes from this alias
    |            |
-   |            referenced here (first use)
+   |            first non-auto trait comes from this alias
 LL |
 LL | type _T30 = dyn _6;
    |                 ^^
    |                 |
-   |                 trait alias used in trait object type (additional use)
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
+   |                 second non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -342,19 +328,19 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _5 = Obj + Send;
    |            ---
    |            |
-   |            additional non-auto trait
    |            first non-auto trait
+   |            additional non-auto trait
 ...
 LL | trait _6 = _5 + _5; // ==> Obj + Send + Obj + Send
-   |            --   -- referenced here (additional use)
+   |            --   -- second non-auto trait comes from this alias
    |            |
-   |            referenced here (first use)
+   |            first non-auto trait comes from this alias
 ...
 LL | type _T31 = dyn _6 + Send;
    |                 ^^
    |                 |
-   |                 trait alias used in trait object type (additional use)
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
+   |                 second non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -365,38 +351,38 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _5 = Obj + Send;
    |            ---
    |            |
-   |            additional non-auto trait
    |            first non-auto trait
+   |            additional non-auto trait
 ...
 LL | trait _6 = _5 + _5; // ==> Obj + Send + Obj + Send
-   |            --   -- referenced here (additional use)
+   |            --   -- second non-auto trait comes from this alias
    |            |
-   |            referenced here (first use)
+   |            first non-auto trait comes from this alias
 ...
 LL | type _T32 = dyn Send + _6;
    |                        ^^
    |                        |
-   |                        trait alias used in trait object type (additional use)
-   |                        trait alias used in trait object type (first use)
+   |                        first non-auto trait comes from this alias
+   |                        second non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-duplicates.rs:95:22
+  --> $DIR/no-duplicates.rs:95:17
    |
 LL | trait _5 = Obj + Send;
-   |            --- first non-auto trait
+   |            --- additional non-auto trait
 ...
 LL | trait _7 = _5 + Sync;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 LL | trait _8 = Unpin + _7;
-   |                    -- referenced here (first use)
+   |                    -- second non-auto trait comes from this alias
 LL |
 LL | type _T40 = dyn _8 + Obj;
-   |                 --   ^^^ additional non-auto trait
+   |                 ^^   --- first non-auto trait
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -408,12 +394,12 @@ LL | trait _5 = Obj + Send;
    |            --- additional non-auto trait
 ...
 LL | trait _7 = _5 + Sync;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 LL | trait _8 = Unpin + _7;
-   |                    -- referenced here (additional use)
+   |                    -- second non-auto trait comes from this alias
 ...
 LL | type _T41 = dyn Obj + _8;
-   |                 ---   ^^ trait alias used in trait object type (additional use)
+   |                 ---   ^^ second non-auto trait comes from this alias
    |                 |
    |                 first non-auto trait
    |
@@ -421,25 +407,25 @@ LL | type _T41 = dyn Obj + _8;
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-duplicates.rs:101:22
+  --> $DIR/no-duplicates.rs:101:17
    |
 LL | trait _3 = Obj;
-   |            --- additional non-auto trait
+   |            --- first non-auto trait
 LL | trait _4 = _3;
-   |            -- referenced here (additional use)
+   |            -- first non-auto trait comes from this alias
 ...
 LL | trait _5 = Obj + Send;
-   |            --- first non-auto trait
+   |            --- additional non-auto trait
 ...
 LL | trait _7 = _5 + Sync;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 LL | trait _8 = Unpin + _7;
-   |                    -- referenced here (first use)
+   |                    -- second non-auto trait comes from this alias
 ...
 LL | type _T42 = dyn _8 + _4;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 ^^   -- first non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -450,20 +436,20 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _3 = Obj;
    |            --- first non-auto trait
 LL | trait _4 = _3;
-   |            -- referenced here (first use)
+   |            -- first non-auto trait comes from this alias
 ...
 LL | trait _5 = Obj + Send;
    |            --- additional non-auto trait
 ...
 LL | trait _7 = _5 + Sync;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 LL | trait _8 = Unpin + _7;
-   |                    -- referenced here (additional use)
+   |                    -- second non-auto trait comes from this alias
 ...
 LL | type _T43 = dyn _4 + _8;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 --   ^^ second non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -474,20 +460,20 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _3 = Obj;
    |            --- first non-auto trait
 LL | trait _4 = _3;
-   |            -- referenced here (first use)
+   |            -- first non-auto trait comes from this alias
 ...
 LL | trait _5 = Obj + Send;
    |            --- additional non-auto trait
 ...
 LL | trait _7 = _5 + Sync;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 LL | trait _8 = Unpin + _7;
-   |                    -- referenced here (additional use)
+   |                    -- second non-auto trait comes from this alias
 ...
 LL | type _T44 = dyn _4 + Send + Sync + _8;
-   |                 --                 ^^ trait alias used in trait object type (additional use)
+   |                 --                 ^^ second non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -500,9 +486,9 @@ LL | trait _9 = for<'a> ObjL<'a>;
 LL | trait _10 = for<'b> ObjL<'b>;
    |             ---------------- additional non-auto trait
 LL | type _T50 = dyn _9 + _10;
-   |                 --   ^^^ trait alias used in trait object type (additional use)
+   |                 --   ^^^ second non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: for<'a> ObjL<'a> + for<'b> ObjL<'b> {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -515,9 +501,9 @@ LL | trait _11 = ObjT<for<'a> fn(&'a u8)>;
 LL | trait _12 = ObjT<for<'b> fn(&'b u8)>;
    |             ------------------------ additional non-auto trait
 LL | type _T60 = dyn _11 + _12;
-   |                 ---   ^^^ trait alias used in trait object type (additional use)
+   |                 ---   ^^^ second non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjT<for<'a> fn(&'a u8)> + ObjT<for<'b> fn(&'b u8)> {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
diff --git a/tests/ui/traits/alias/no-extra-traits.stderr b/tests/ui/traits/alias/no-extra-traits.stderr
index 4b1ddf6843c..fcdb4937ff5 100644
--- a/tests/ui/traits/alias/no-extra-traits.stderr
+++ b/tests/ui/traits/alias/no-extra-traits.stderr
@@ -1,15 +1,15 @@
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-extra-traits.rs:16:22
+  --> $DIR/no-extra-traits.rs:16:17
    |
 LL | trait _0 = ObjA;
-   |            ---- first non-auto trait
+   |            ---- additional non-auto trait
 ...
 LL | type _T00 = dyn _0 + ObjB;
-   |                 --   ^^^^ additional non-auto trait
+   |                 ^^   ---- first non-auto trait
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
@@ -19,7 +19,7 @@ LL | trait _0 = ObjA;
    |            ---- additional non-auto trait
 ...
 LL | type _T01 = dyn ObjB + _0;
-   |                 ----   ^^ trait alias used in trait object type (additional use)
+   |                 ----   ^^ second non-auto trait comes from this alias
    |                 |
    |                 first non-auto trait
    |
@@ -32,10 +32,10 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _0 = ObjA;
    |            ---- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | type _T02 = dyn ObjB + _1;
-   |                 ----   ^^ trait alias used in trait object type (additional use)
+   |                 ----   ^^ second non-auto trait comes from this alias
    |                 |
    |                 first non-auto trait
    |
@@ -43,19 +43,19 @@ LL | type _T02 = dyn ObjB + _1;
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-extra-traits.rs:25:22
+  --> $DIR/no-extra-traits.rs:25:17
    |
 LL | trait _0 = ObjA;
-   |            ---- first non-auto trait
+   |            ---- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | type _T03 = dyn _1 + ObjB;
-   |                 --   ^^^^ additional non-auto trait
+   |                 ^^   ---- first non-auto trait
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
@@ -64,34 +64,34 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _2 = ObjB;
    |            ----
    |            |
-   |            additional non-auto trait
    |            first non-auto trait
+   |            additional non-auto trait
 LL | trait _3 = _2;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | type _T10 = dyn _2 + _3;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 --   ^^ second non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjB {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-extra-traits.rs:37:22
+  --> $DIR/no-extra-traits.rs:37:17
    |
 LL | trait _2 = ObjB;
    |            ----
    |            |
-   |            additional non-auto trait
    |            first non-auto trait
+   |            additional non-auto trait
 LL | trait _3 = _2;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | type _T11 = dyn _3 + _2;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 ^^   -- first non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjB {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -102,38 +102,38 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _2 = ObjB;
    |            ----
    |            |
-   |            additional non-auto trait
    |            first non-auto trait
+   |            additional non-auto trait
 LL | trait _3 = _2;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 LL | trait _4 = _3;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | type _T12 = dyn _2 + _4;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 --   ^^ second non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjB {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-extra-traits.rs:43:22
+  --> $DIR/no-extra-traits.rs:43:17
    |
 LL | trait _2 = ObjB;
    |            ----
    |            |
-   |            additional non-auto trait
    |            first non-auto trait
+   |            additional non-auto trait
 LL | trait _3 = _2;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 LL | trait _4 = _3;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | type _T13 = dyn _4 + _2;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 ^^   -- first non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjB {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -144,50 +144,50 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _0 = ObjA;
    |            ---- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | trait _5 = Sync + ObjB + Send;
    |                   ---- first non-auto trait
 LL |
 LL | type _T20 = dyn _5 + _1;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 --   ^^ second non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-extra-traits.rs:53:22
+  --> $DIR/no-extra-traits.rs:53:17
    |
 LL | trait _0 = ObjA;
-   |            ---- first non-auto trait
+   |            ---- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | trait _5 = Sync + ObjB + Send;
-   |                   ---- additional non-auto trait
+   |                   ---- first non-auto trait
 ...
 LL | type _T21 = dyn _1 + _5;
-   |                 --   ^^ trait alias used in trait object type (additional use)
+   |                 ^^   -- first non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-extra-traits.rs:56:22
+  --> $DIR/no-extra-traits.rs:56:17
    |
 LL | trait _5 = Sync + ObjB + Send;
-   |                   ---- first non-auto trait
+   |                   ---- additional non-auto trait
 ...
 LL | type _T22 = dyn _5 + ObjA;
-   |                 --   ^^^^ additional non-auto trait
+   |                 ^^   ---- first non-auto trait
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
@@ -197,7 +197,7 @@ LL | trait _5 = Sync + ObjB + Send;
    |                   ---- additional non-auto trait
 ...
 LL | type _T23 = dyn ObjA + _5;
-   |                 ----   ^^ trait alias used in trait object type (additional use)
+   |                 ----   ^^ second non-auto trait comes from this alias
    |                 |
    |                 first non-auto trait
    |
@@ -210,50 +210,50 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
 LL | trait _0 = ObjA;
    |            ---- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | trait _5 = Sync + ObjB + Send;
    |                   ---- first non-auto trait
 ...
 LL | type _T24 = dyn Send + _5 + _1 + Sync;
-   |                        --   ^^ trait alias used in trait object type (additional use)
+   |                        --   ^^ second non-auto trait comes from this alias
    |                        |
-   |                        trait alias used in trait object type (first use)
+   |                        first non-auto trait comes from this alias
    |
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-extra-traits.rs:65:29
+  --> $DIR/no-extra-traits.rs:65:17
    |
 LL | trait _0 = ObjA;
-   |            ---- first non-auto trait
+   |            ---- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | trait _5 = Sync + ObjB + Send;
-   |                   ---- additional non-auto trait
+   |                   ---- first non-auto trait
 ...
 LL | type _T25 = dyn _1 + Sync + _5 + Send;
-   |                 --          ^^ trait alias used in trait object type (additional use)
+   |                 ^^          -- first non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-extra-traits.rs:68:36
+  --> $DIR/no-extra-traits.rs:68:31
    |
 LL | trait _5 = Sync + ObjB + Send;
-   |                   ---- first non-auto trait
+   |                   ---- additional non-auto trait
 ...
 LL | type _T26 = dyn Sync + Send + _5 + ObjA;
-   |                               --   ^^^^ additional non-auto trait
+   |                               ^^   ---- first non-auto trait
    |                               |
-   |                               trait alias used in trait object type (first use)
+   |                               second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
@@ -263,7 +263,7 @@ LL | trait _5 = Sync + ObjB + Send;
    |                   ---- additional non-auto trait
 ...
 LL | type _T27 = dyn Send + Sync + ObjA + _5;
-   |                               ----   ^^ trait alias used in trait object type (additional use)
+   |                               ----   ^^ second non-auto trait comes from this alias
    |                               |
    |                               first non-auto trait
    |
@@ -274,199 +274,199 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
   --> $DIR/no-extra-traits.rs:80:17
    |
 LL | trait _0 = ObjA;
-   |            ---- first non-auto trait
+   |            ---- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | trait _5 = Sync + ObjB + Send;
-   |                   ---- additional non-auto trait
+   |                   ---- first non-auto trait
 ...
 LL | trait _6 = _1 + _5;
-   |            --   -- referenced here (additional use)
+   |            --   -- first non-auto trait comes from this alias
    |            |
-   |            referenced here (first use)
+   |            second non-auto trait comes from this alias
 ...
 LL | type _T30 = dyn _6;
    |                 ^^
    |                 |
-   |                 trait alias used in trait object type (additional use)
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
+   |                 second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
   --> $DIR/no-extra-traits.rs:83:17
    |
 LL | trait _0 = ObjA;
-   |            ---- first non-auto trait
+   |            ---- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | trait _5 = Sync + ObjB + Send;
-   |                   ---- additional non-auto trait
+   |                   ---- first non-auto trait
 ...
 LL | trait _6 = _1 + _5;
-   |            --   -- referenced here (additional use)
+   |            --   -- first non-auto trait comes from this alias
    |            |
-   |            referenced here (first use)
+   |            second non-auto trait comes from this alias
 ...
 LL | type _T31 = dyn _6 + Send;
    |                 ^^
    |                 |
-   |                 trait alias used in trait object type (additional use)
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
+   |                 second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
   --> $DIR/no-extra-traits.rs:86:24
    |
 LL | trait _0 = ObjA;
-   |            ---- first non-auto trait
+   |            ---- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | trait _5 = Sync + ObjB + Send;
-   |                   ---- additional non-auto trait
+   |                   ---- first non-auto trait
 ...
 LL | trait _6 = _1 + _5;
-   |            --   -- referenced here (additional use)
+   |            --   -- first non-auto trait comes from this alias
    |            |
-   |            referenced here (first use)
+   |            second non-auto trait comes from this alias
 ...
 LL | type _T32 = dyn Send + _6;
    |                        ^^
    |                        |
-   |                        trait alias used in trait object type (additional use)
-   |                        trait alias used in trait object type (first use)
+   |                        first non-auto trait comes from this alias
+   |                        second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
   --> $DIR/no-extra-traits.rs:89:17
    |
 LL | trait _0 = ObjA;
-   |            ---- first non-auto trait
+   |            ---- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | trait _5 = Sync + ObjB + Send;
-   |                   ---- additional non-auto trait
+   |                   ---- first non-auto trait
 ...
 LL | trait _6 = _1 + _5;
-   |            --   -- referenced here (additional use)
+   |            --   -- first non-auto trait comes from this alias
    |            |
-   |            referenced here (first use)
+   |            second non-auto trait comes from this alias
 LL | trait _7 = _6;
    |            --
    |            |
-   |            referenced here (additional use)
-   |            referenced here (first use)
+   |            first non-auto trait comes from this alias
+   |            second non-auto trait comes from this alias
 LL | trait _8 = _7;
    |            --
    |            |
-   |            referenced here (additional use)
-   |            referenced here (first use)
+   |            first non-auto trait comes from this alias
+   |            second non-auto trait comes from this alias
 ...
 LL | type _T33 = dyn _8;
    |                 ^^
    |                 |
-   |                 trait alias used in trait object type (additional use)
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
+   |                 second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
   --> $DIR/no-extra-traits.rs:92:17
    |
 LL | trait _0 = ObjA;
-   |            ---- first non-auto trait
+   |            ---- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | trait _5 = Sync + ObjB + Send;
-   |                   ---- additional non-auto trait
+   |                   ---- first non-auto trait
 ...
 LL | trait _6 = _1 + _5;
-   |            --   -- referenced here (additional use)
+   |            --   -- first non-auto trait comes from this alias
    |            |
-   |            referenced here (first use)
+   |            second non-auto trait comes from this alias
 LL | trait _7 = _6;
    |            --
    |            |
-   |            referenced here (additional use)
-   |            referenced here (first use)
+   |            first non-auto trait comes from this alias
+   |            second non-auto trait comes from this alias
 LL | trait _8 = _7;
    |            --
    |            |
-   |            referenced here (additional use)
-   |            referenced here (first use)
+   |            first non-auto trait comes from this alias
+   |            second non-auto trait comes from this alias
 ...
 LL | type _T34 = dyn _8 + Send;
    |                 ^^
    |                 |
-   |                 trait alias used in trait object type (additional use)
-   |                 trait alias used in trait object type (first use)
+   |                 first non-auto trait comes from this alias
+   |                 second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
   --> $DIR/no-extra-traits.rs:95:24
    |
 LL | trait _0 = ObjA;
-   |            ---- first non-auto trait
+   |            ---- additional non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 ...
 LL | trait _5 = Sync + ObjB + Send;
-   |                   ---- additional non-auto trait
+   |                   ---- first non-auto trait
 ...
 LL | trait _6 = _1 + _5;
-   |            --   -- referenced here (additional use)
+   |            --   -- first non-auto trait comes from this alias
    |            |
-   |            referenced here (first use)
+   |            second non-auto trait comes from this alias
 LL | trait _7 = _6;
    |            --
    |            |
-   |            referenced here (additional use)
-   |            referenced here (first use)
+   |            first non-auto trait comes from this alias
+   |            second non-auto trait comes from this alias
 LL | trait _8 = _7;
    |            --
    |            |
-   |            referenced here (additional use)
-   |            referenced here (first use)
+   |            first non-auto trait comes from this alias
+   |            second non-auto trait comes from this alias
 ...
 LL | type _T35 = dyn Send + _8;
    |                        ^^
    |                        |
-   |                        trait alias used in trait object type (additional use)
-   |                        trait alias used in trait object type (first use)
+   |                        first non-auto trait comes from this alias
+   |                        second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-extra-traits.rs:103:23
+  --> $DIR/no-extra-traits.rs:103:17
    |
 LL | trait _5 = Sync + ObjB + Send;
-   |                   ---- first non-auto trait
+   |                   ---- additional non-auto trait
 ...
 LL | trait _9 = _5 + Sync;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 LL | trait _10 = Unpin + _9;
-   |                     -- referenced here (first use)
+   |                     -- second non-auto trait comes from this alias
 LL |
 LL | type _T40 = dyn _10 + ObjA;
-   |                 ---   ^^^^ additional non-auto trait
+   |                 ^^^   ---- first non-auto trait
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
@@ -476,12 +476,12 @@ LL | trait _5 = Sync + ObjB + Send;
    |                   ---- additional non-auto trait
 ...
 LL | trait _9 = _5 + Sync;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 LL | trait _10 = Unpin + _9;
-   |                     -- referenced here (additional use)
+   |                     -- second non-auto trait comes from this alias
 ...
 LL | type _T41 = dyn ObjA + _10;
-   |                 ----   ^^^ trait alias used in trait object type (additional use)
+   |                 ----   ^^^ second non-auto trait comes from this alias
    |                 |
    |                 first non-auto trait
    |
@@ -489,46 +489,46 @@ LL | type _T41 = dyn ObjA + _10;
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-extra-traits.rs:109:23
+  --> $DIR/no-extra-traits.rs:109:17
    |
 LL | trait _0 = ObjA;
-   |            ---- additional non-auto trait
+   |            ---- first non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (additional use)
+   |            -- first non-auto trait comes from this alias
 ...
 LL | trait _5 = Sync + ObjB + Send;
-   |                   ---- first non-auto trait
+   |                   ---- additional non-auto trait
 ...
 LL | trait _9 = _5 + Sync;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 LL | trait _10 = Unpin + _9;
-   |                     -- referenced here (first use)
+   |                     -- second non-auto trait comes from this alias
 ...
 LL | type _T42 = dyn _10 + _1;
-   |                 ---   ^^ trait alias used in trait object type (additional use)
+   |                 ^^^   -- first non-auto trait comes from this alias
    |                 |
-   |                 trait alias used in trait object type (first use)
+   |                 second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-extra-traits.rs:112:37
+  --> $DIR/no-extra-traits.rs:112:24
    |
 LL | trait _5 = Sync + ObjB + Send;
-   |                   ---- first non-auto trait
+   |                   ---- additional non-auto trait
 ...
 LL | trait _9 = _5 + Sync;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 LL | trait _10 = Unpin + _9;
-   |                     -- referenced here (first use)
+   |                     -- second non-auto trait comes from this alias
 ...
 LL | type _T43 = dyn Send + _10 + Sync + ObjA;
-   |                        ---          ^^^^ additional non-auto trait
+   |                        ^^^          ---- first non-auto trait
    |                        |
-   |                        trait alias used in trait object type (first use)
+   |                        second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
@@ -538,12 +538,12 @@ LL | trait _5 = Sync + ObjB + Send;
    |                   ---- additional non-auto trait
 ...
 LL | trait _9 = _5 + Sync;
-   |            -- referenced here (additional use)
+   |            -- second non-auto trait comes from this alias
 LL | trait _10 = Unpin + _9;
-   |                     -- referenced here (additional use)
+   |                     -- second non-auto trait comes from this alias
 ...
 LL | type _T44 = dyn ObjA + _10 + Send + Sync;
-   |                 ----   ^^^ trait alias used in trait object type (additional use)
+   |                 ----   ^^^ second non-auto trait comes from this alias
    |                 |
    |                 first non-auto trait
    |
@@ -551,27 +551,27 @@ LL | type _T44 = dyn ObjA + _10 + Send + Sync;
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/no-extra-traits.rs:118:37
+  --> $DIR/no-extra-traits.rs:118:31
    |
 LL | trait _0 = ObjA;
-   |            ---- additional non-auto trait
+   |            ---- first non-auto trait
 LL | trait _1 = _0;
-   |            -- referenced here (additional use)
+   |            -- first non-auto trait comes from this alias
 ...
 LL | trait _5 = Sync + ObjB + Send;
-   |                   ---- first non-auto trait
+   |                   ---- additional non-auto trait
 ...
 LL | trait _9 = _5 + Sync;
-   |            -- referenced here (first use)
+   |            -- second non-auto trait comes from this alias
 LL | trait _10 = Unpin + _9;
-   |                     -- referenced here (first use)
+   |                     -- second non-auto trait comes from this alias
 ...
 LL | type _T45 = dyn Sync + Send + _10 + _1;
-   |                               ---   ^^ trait alias used in trait object type (additional use)
+   |                               ^^^   -- first non-auto trait comes from this alias
    |                               |
-   |                               trait alias used in trait object type (first use)
+   |                               second non-auto trait comes from this alias
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error: aborting due to 28 previous errors
diff --git a/tests/ui/traits/alias/object-fail.rs b/tests/ui/traits/alias/object-fail.rs
index 5c753ff207c..38da7b8eef4 100644
--- a/tests/ui/traits/alias/object-fail.rs
+++ b/tests/ui/traits/alias/object-fail.rs
@@ -5,7 +5,7 @@ trait IteratorAlias = Iterator;
 
 fn main() {
     let _: &dyn EqAlias = &123;
-    //~^ ERROR the trait `Eq` cannot be made into an object [E0038]
+    //~^ ERROR the trait alias `EqAlias` cannot be made into an object [E0038]
     let _: &dyn IteratorAlias = &vec![123].into_iter();
     //~^ ERROR must be specified
 }
diff --git a/tests/ui/traits/alias/object-fail.stderr b/tests/ui/traits/alias/object-fail.stderr
index 1b89b87db9f..e4968ee2adc 100644
--- a/tests/ui/traits/alias/object-fail.stderr
+++ b/tests/ui/traits/alias/object-fail.stderr
@@ -1,13 +1,18 @@
-error[E0038]: the trait `Eq` cannot be made into an object
-  --> $DIR/object-fail.rs:7:13
+error[E0038]: the trait alias `EqAlias` cannot be made into an object
+  --> $DIR/object-fail.rs:7:17
    |
 LL |     let _: &dyn EqAlias = &123;
-   |             ^^^^^^^^^^^ `Eq` cannot be made into an object
+   |                 ^^^^^^^ `EqAlias` cannot be made into an object
    |
 note: for a trait to be "dyn-compatible" 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>
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
-   = note: the trait cannot be made into an object because it uses `Self` as a type parameter
+   = note: ...because it uses `Self` as a type parameter
+   |
+  ::: $DIR/object-fail.rs:3:7
+   |
+LL | trait EqAlias = Eq;
+   |       ------- this trait cannot be made into an object...
 
 error[E0191]: the value of the associated type `Item` in `Iterator` must be specified
   --> $DIR/object-fail.rs:9:17
diff --git a/tests/ui/traits/alias/self-in-const-generics.stderr b/tests/ui/traits/alias/self-in-const-generics.stderr
index 3de31b64c8b..6dd6fabe7b2 100644
--- a/tests/ui/traits/alias/self-in-const-generics.stderr
+++ b/tests/ui/traits/alias/self-in-const-generics.stderr
@@ -2,9 +2,19 @@ error[E0038]: the trait alias `BB` cannot be made into an object
   --> $DIR/self-in-const-generics.rs:9:16
    |
 LL | fn foo(x: &dyn BB) {}
-   |                ^^
+   |                ^^ `BB` cannot be made into an object
    |
-   = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause
+note: for a trait to be "dyn-compatible" 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/self-in-const-generics.rs:7:12
+   |
+LL | trait BB = Bar<{ 2 + 1 }>;
+   |       --   ^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter
+   |       |
+   |       this trait cannot be made into an object...
+help: consider using an opaque type instead
+   |
+LL | fn foo(x: &impl BB) {}
+   |            ~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/alias/self-in-generics.stderr b/tests/ui/traits/alias/self-in-generics.stderr
index ffc0a00ad7d..4fbd979e5f5 100644
--- a/tests/ui/traits/alias/self-in-generics.stderr
+++ b/tests/ui/traits/alias/self-in-generics.stderr
@@ -2,9 +2,21 @@ error[E0038]: the trait alias `SelfInput` cannot be made into an object
   --> $DIR/self-in-generics.rs:8:19
    |
 LL | pub fn f(_f: &dyn SelfInput) {}
-   |                   ^^^^^^^^^
+   |                   ^^^^^^^^^ `SelfInput` cannot be made into an object
    |
-   = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause
+note: for a trait to be "dyn-compatible" 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/self-in-generics.rs:6:23
+   |
+LL | pub trait SelfInput = Fn(&mut Self);
+   |           ---------   ^^^^^^^^^^^^^
+   |           |           |
+   |           |           ...because it uses `Self` as a type parameter
+   |           |           ...because it uses `Self` as a type parameter
+   |           this trait cannot be made into an object...
+help: consider using an opaque type instead
+   |
+LL | pub fn f(_f: &impl SelfInput) {}
+   |               ~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/bad-sized.stderr b/tests/ui/traits/bad-sized.stderr
index 0e82867ef03..21718cf0951 100644
--- a/tests/ui/traits/bad-sized.stderr
+++ b/tests/ui/traits/bad-sized.stderr
@@ -1,12 +1,12 @@
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/bad-sized.rs:4:28
+  --> $DIR/bad-sized.rs:4:20
    |
 LL |     let x: Vec<dyn Trait + Sized> = Vec::new();
-   |                    -----   ^^^^^ additional non-auto trait
+   |                    ^^^^^   ----- first non-auto trait
    |                    |
-   |                    first non-auto trait
+   |                    additional non-auto trait
    |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Trait + Sized {}`
+   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Sized + Trait {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/traits/issue-28576.stderr b/tests/ui/traits/issue-28576.stderr
index 23581f2ee51..cb0d55dce59 100644
--- a/tests/ui/traits/issue-28576.stderr
+++ b/tests/ui/traits/issue-28576.stderr
@@ -19,9 +19,10 @@ LL | pub trait Foo<RHS: ?Sized=Self> {
    |                  ++++++++
 
 error[E0038]: the trait `Bar` cannot be made into an object
-  --> $DIR/issue-28576.rs:9:12
+  --> $DIR/issue-28576.rs:9:16
    |
-LL | /            dyn Bar
+LL |              dyn Bar
+   |  ________________^
 LL | |               <Assoc=()>
    | |________________________^ `Bar` cannot be made into an object
    |
diff --git a/tests/ui/traits/issue-38404.stderr b/tests/ui/traits/issue-38404.stderr
index 145eeb88dd5..98d49fa3cba 100644
--- a/tests/ui/traits/issue-38404.stderr
+++ b/tests/ui/traits/issue-38404.stderr
@@ -1,8 +1,8 @@
 error[E0038]: the trait `B` cannot be made into an object
-  --> $DIR/issue-38404.rs:3:15
+  --> $DIR/issue-38404.rs:3:19
    |
 LL | trait C<T>: A<dyn B<T, Output = usize>> {}
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object
+   |                   ^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object
    |
 note: for a trait to be "dyn-compatible" 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
@@ -13,10 +13,10 @@ LL | trait B<T>: A<T> {}
    |       - this trait cannot be made into an object...
 
 error[E0038]: the trait `B` cannot be made into an object
-  --> $DIR/issue-38404.rs:3:15
+  --> $DIR/issue-38404.rs:3:19
    |
 LL | trait C<T>: A<dyn B<T, Output = usize>> {}
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object
+   |                   ^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object
    |
 note: for a trait to be "dyn-compatible" 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
@@ -28,10 +28,10 @@ LL | trait B<T>: A<T> {}
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0038]: the trait `B` cannot be made into an object
-  --> $DIR/issue-38404.rs:3:15
+  --> $DIR/issue-38404.rs:3:19
    |
 LL | trait C<T>: A<dyn B<T, Output = usize>> {}
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object
+   |                   ^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object
    |
 note: for a trait to be "dyn-compatible" 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
diff --git a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs
index 4aadd45c49c..3af299e5b11 100644
--- a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs
+++ b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs
@@ -10,7 +10,6 @@ fn w<'a, T: 'a, F: Fn(&'a T)>() {
     let b: &dyn FromResidual = &();
     //~^ ERROR: the trait `FromResidual` cannot be made into an object
     //~| ERROR: the trait `FromResidual` cannot be made into an object
-    //~| ERROR: the trait `FromResidual` cannot be made into an object
 }
 
 fn main() {}
diff --git a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr
index c67a8c05379..a131227e78e 100644
--- a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr
+++ b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr
@@ -1,12 +1,4 @@
 error[E0038]: the trait `FromResidual` cannot be made into an object
-  --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:17
-   |
-LL |     let b: &dyn FromResidual = &();
-   |                 ^^^^^^^^^^^^
-   |
-   = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause
-
-error[E0038]: the trait `FromResidual` cannot be made into an object
   --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:32
    |
 LL |     let b: &dyn FromResidual = &();
@@ -51,6 +43,6 @@ help: alternatively, consider constraining `from_residual` so it does not apply
 LL |     fn from_residual(residual: R) -> Self where Self: Sized;
    |                                           +++++++++++++++++
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0038`.