about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-10-12 23:00:56 +0200
committerGitHub <noreply@github.com>2024-10-12 23:00:56 +0200
commit663da008760a0f6d38dbd5e7db4c9bb67fa64798 (patch)
treee00227c79ce27f089aa3e4afd0ab0de99f6bad56
parentba75f2488818a053bf388afff4211cb8eca72ff5 (diff)
parent9a2772e1c2d6e770e13716d4691bc0a943cd7d61 (diff)
downloadrust-663da008760a0f6d38dbd5e7db4c9bb67fa64798.tar.gz
rust-663da008760a0f6d38dbd5e7db4c9bb67fa64798.zip
Rollup merge of #131239 - VulnBandit:trait-vulnerability, r=lcnr
Don't assume traits used as type are trait objs in 2021 edition

Fixes #127548

When you use a trait as a type, the compiler automatically assumes you meant to use a trait object, which is not always the case.
This PR fixes the bug where you don't need a trait object, so the error message was changed to:
```
error[E0782]: expected a type, found a trait
```
Also fixes some ICEs:
Fixes https://github.com/rust-lang/rust/issues/120241
Fixes https://github.com/rust-lang/rust/issues/120482
Fixes https://github.com/rust-lang/rust/issues/125512
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs53
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs19
-rw-r--r--tests/crashes/120241-2.rs10
-rw-r--r--tests/crashes/120241.rs13
-rw-r--r--tests/crashes/120482.rs13
-rw-r--r--tests/crashes/125512.rs10
-rw-r--r--tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs20
-rw-r--r--tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr58
-rw-r--r--tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr39
-rw-r--r--tests/ui/const-generics/not_wf_param_in_rpitit.rs3
-rw-r--r--tests/ui/const-generics/not_wf_param_in_rpitit.stderr55
-rw-r--r--tests/ui/dyn-compatibility/avoid-ice-on-warning-2.new.stderr40
-rw-r--r--tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr2
-rw-r--r--tests/ui/dyn-compatibility/avoid-ice-on-warning-2.rs7
-rw-r--r--tests/ui/dyn-compatibility/avoid-ice-on-warning-3.new.stderr74
-rw-r--r--tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr10
-rw-r--r--tests/ui/dyn-compatibility/avoid-ice-on-warning-3.rs8
-rw-r--r--tests/ui/dyn-compatibility/avoid-ice-on-warning.new.stderr16
-rw-r--r--tests/ui/dyn-compatibility/avoid-ice-on-warning.rs1
-rw-r--r--tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.fixed3
-rw-r--r--tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.stderr15
-rw-r--r--tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.rs3
-rw-r--r--tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs57
-rw-r--r--tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr141
-rw-r--r--tests/ui/dyn-keyword/dyn-2021-edition-error.rs6
-rw-r--r--tests/ui/dyn-keyword/dyn-2021-edition-error.stderr10
-rw-r--r--tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.rs3
-rw-r--r--tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr4
-rw-r--r--tests/ui/editions/dyn-trait-sugg-2021.rs2
-rw-r--r--tests/ui/editions/dyn-trait-sugg-2021.stderr4
-rw-r--r--tests/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr15
-rw-r--r--tests/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs3
-rw-r--r--tests/ui/resolve/issue-111312.rs3
-rw-r--r--tests/ui/resolve/issue-111312.stderr21
-rw-r--r--tests/ui/resolve/issue-111727.rs3
-rw-r--r--tests/ui/resolve/issue-111727.stderr15
-rw-r--r--tests/ui/rust-2021/ice-return-unsized-can-impl-2.rs15
-rw-r--r--tests/ui/rust-2021/ice-return-unsized-can-impl-2.stderr57
-rw-r--r--tests/ui/rust-2021/ice-return-unsized-can-impl.rs16
-rw-r--r--tests/ui/rust-2021/ice-return-unsized-can-impl.stderr30
-rw-r--r--tests/ui/rust-2021/ice-unsized-fn-params-2.rs12
-rw-r--r--tests/ui/rust-2021/ice-unsized-fn-params-2.stderr19
-rw-r--r--tests/ui/rust-2021/ice-unsized-fn-params.rs18
-rw-r--r--tests/ui/rust-2021/ice-unsized-fn-params.stderr57
-rw-r--r--tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs15
-rw-r--r--tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021-without-dyn.stderr81
-rw-r--r--tests/ui/suggestions/issue-116434-2021.rs6
-rw-r--r--tests/ui/suggestions/issue-116434-2021.stderr27
-rw-r--r--tests/ui/suggestions/suggest-blanket-impl-local-trait.rs28
-rw-r--r--tests/ui/suggestions/suggest-blanket-impl-local-trait.stderr28
-rw-r--r--tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs6
-rw-r--r--tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr12
-rw-r--r--tests/ui/traits/bound/not-on-bare-trait-2021.rs8
-rw-r--r--tests/ui/traits/bound/not-on-bare-trait-2021.stderr49
-rw-r--r--tests/ui/traits/issue-106072.rs4
-rw-r--r--tests/ui/traits/issue-106072.stderr29
-rw-r--r--tests/ui/traits/missing-for-type-in-impl.e2021.stderr4
-rw-r--r--tests/ui/traits/missing-for-type-in-impl.rs2
59 files changed, 607 insertions, 679 deletions
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
index 5607fe873f6..11c0450bfe2 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
@@ -1,6 +1,6 @@
 use rustc_ast::TraitObjectSyntax;
 use rustc_errors::codes::*;
-use rustc_errors::{Diag, EmissionGuarantee, StashKey};
+use rustc_errors::{Diag, EmissionGuarantee, ErrorGuaranteed, StashKey, Suggestions};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_lint_defs::Applicability;
@@ -15,13 +15,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     ///
     /// *Bare* trait object types are ones that aren't preceded by the keyword `dyn`.
     /// In edition 2021 and onward we emit a hard error for them.
-    pub(super) fn prohibit_or_lint_bare_trait_object_ty(&self, self_ty: &hir::Ty<'_>) {
+    pub(super) fn prohibit_or_lint_bare_trait_object_ty(
+        &self,
+        self_ty: &hir::Ty<'_>,
+    ) -> Option<ErrorGuaranteed> {
         let tcx = self.tcx();
 
         let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
             self_ty.kind
         else {
-            return;
+            return None;
         };
 
         let in_path = match tcx.parent_hir_node(self_ty.hir_id) {
@@ -70,8 +73,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         }
 
         if self_ty.span.edition().at_least_rust_2021() {
-            let msg = "trait objects must include the `dyn` keyword";
-            let label = "add `dyn` keyword before this trait";
+            let msg = "expected a type, found a trait";
+            let label = "you can add the `dyn` keyword if you want a trait object";
             let mut diag =
                 rustc_errors::struct_span_code_err!(self.dcx(), self_ty.span, E0782, "{}", msg);
             if self_ty.span.can_be_used_for_suggestions()
@@ -83,7 +86,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             // Check if the impl trait that we are considering is an impl of a local trait.
             self.maybe_suggest_blanket_trait_impl(self_ty, &mut diag);
             self.maybe_suggest_assoc_ty_bound(self_ty, &mut diag);
-            diag.stash(self_ty.span, StashKey::TraitMissingMethod);
+            // In case there is an associate type with the same name
+            // Add the suggestion to this error
+            if let Some(mut sugg) =
+                tcx.dcx().steal_non_err(self_ty.span, StashKey::AssociatedTypeSuggestion)
+                && let Suggestions::Enabled(ref mut s1) = diag.suggestions
+                && let Suggestions::Enabled(ref mut s2) = sugg.suggestions
+            {
+                s1.append(s2);
+                sugg.cancel();
+            }
+            diag.stash(self_ty.span, StashKey::TraitMissingMethod)
         } else {
             tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, |lint| {
                 lint.primary_message("trait objects without an explicit `dyn` are deprecated");
@@ -96,6 +109,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 }
                 self.maybe_suggest_blanket_trait_impl(self_ty, lint);
             });
+            None
         }
     }
 
@@ -174,41 +188,31 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // 1. Independent functions
         // 2. Functions inside trait blocks
         // 3. Functions inside impl blocks
-        let (sig, generics, owner) = match tcx.hir_node_by_def_id(parent_id) {
+        let (sig, generics) = match tcx.hir_node_by_def_id(parent_id) {
             hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, generics, _), .. }) => {
-                (sig, generics, None)
+                (sig, generics)
             }
             hir::Node::TraitItem(hir::TraitItem {
                 kind: hir::TraitItemKind::Fn(sig, _),
                 generics,
-                owner_id,
                 ..
-            }) => (sig, generics, Some(tcx.parent(owner_id.to_def_id()))),
+            }) => (sig, generics),
             hir::Node::ImplItem(hir::ImplItem {
                 kind: hir::ImplItemKind::Fn(sig, _),
                 generics,
-                owner_id,
                 ..
-            }) => (sig, generics, Some(tcx.parent(owner_id.to_def_id()))),
+            }) => (sig, generics),
             _ => return false,
         };
         let Ok(trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else {
             return false;
         };
         let impl_sugg = vec![(self_ty.span.shrink_to_lo(), "impl ".to_string())];
-        let mut is_downgradable = true;
-
         // Check if trait object is safe for suggesting dynamic dispatch.
         let is_dyn_compatible = match self_ty.kind {
             hir::TyKind::TraitObject(objects, ..) => {
                 objects.iter().all(|(o, _)| match o.trait_ref.path.res {
-                    Res::Def(DefKind::Trait, id) => {
-                        if Some(id) == owner {
-                            // For recursive traits, don't downgrade the error. (#119652)
-                            is_downgradable = false;
-                        }
-                        tcx.is_dyn_compatible(id)
-                    }
+                    Res::Def(DefKind::Trait, id) => tcx.is_dyn_compatible(id),
                     _ => false,
                 })
             }
@@ -255,9 +259,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     suggestion,
                     Applicability::MachineApplicable,
                 );
-            } else if is_downgradable {
-                // We'll emit the dyn-compatibility error already, with a structured suggestion.
-                diag.downgrade_to_delayed_bug();
             }
             return true;
         }
@@ -281,10 +282,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             );
             if !is_dyn_compatible {
                 diag.note(format!("`{trait_name}` it is dyn-incompatible, so it can't be `dyn`"));
-                if is_downgradable {
-                    // We'll emit the dyn-compatibility error already, with a structured suggestion.
-                    diag.downgrade_to_delayed_bug();
-                }
             } else {
                 // No ampersand in suggestion if it's borrowed already
                 let (dyn_str, paren_dyn_str) =
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 9148b0e681e..d760acf53bd 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -2064,13 +2064,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 )
             }
             hir::TyKind::TraitObject(bounds, lifetime, repr) => {
-                self.prohibit_or_lint_bare_trait_object_ty(hir_ty);
-
-                let repr = match repr {
-                    TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
-                    TraitObjectSyntax::DynStar => ty::DynStar,
-                };
-                self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, repr)
+                if let Some(guar) = self.prohibit_or_lint_bare_trait_object_ty(hir_ty) {
+                    // Don't continue with type analysis if the `dyn` keyword is missing
+                    // It generates confusing errors, especially if the user meant to use another
+                    // keyword like `impl`
+                    Ty::new_error(tcx, guar)
+                } else {
+                    let repr = match repr {
+                        TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
+                        TraitObjectSyntax::DynStar => ty::DynStar,
+                    };
+                    self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, repr)
+                }
             }
             // If we encounter a fully qualified path with RTN generics, then it must have
             // *not* gone through `lower_ty_maybe_return_type_notation`, and therefore
diff --git a/tests/crashes/120241-2.rs b/tests/crashes/120241-2.rs
deleted file mode 100644
index 91ec3362090..00000000000
--- a/tests/crashes/120241-2.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ known-bug: #120241
-//@ edition:2021
-#![feature(dyn_compatible_for_dispatch)]
-#![feature(unsized_fn_params)]
-
-fn guard(_s: Copy) -> bool {
-    panic!()
-}
-
-fn main() {}
diff --git a/tests/crashes/120241.rs b/tests/crashes/120241.rs
deleted file mode 100644
index b4fcb903714..00000000000
--- a/tests/crashes/120241.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//@ known-bug: #120241
-//@ edition:2021
-#![feature(dyn_compatible_for_dispatch)]
-
-trait B {
-    fn f(a: A) -> A;
-}
-
-trait A {
-    fn g(b: B) -> B;
-}
-
-fn main() {}
diff --git a/tests/crashes/120482.rs b/tests/crashes/120482.rs
deleted file mode 100644
index a395855d796..00000000000
--- a/tests/crashes/120482.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//@ known-bug: #120482
-//@ edition:2021
-#![feature(dyn_compatible_for_dispatch)]
-
-trait B {
-    fn bar(&self, x: &Self);
-}
-
-trait A {
-    fn g(new: B) -> B;
-}
-
-fn main() {}
diff --git a/tests/crashes/125512.rs b/tests/crashes/125512.rs
deleted file mode 100644
index 37dbdf2f32f..00000000000
--- a/tests/crashes/125512.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ known-bug: rust-lang/rust#125512
-//@ edition:2021
-#![feature(dyn_compatible_for_dispatch)]
-trait B {
-    fn f(a: A) -> A;
-}
-trait A {
-    fn concrete(b: B) -> B;
-}
-fn main() {}
diff --git a/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs
index 7df042d5f88..c8bb0ebd574 100644
--- a/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs
+++ b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs
@@ -2,28 +2,24 @@
 //@ edition: 2021
 
 fn f(_: impl Trait<T = Copy>) {}
-//~^ ERROR trait objects must include the `dyn` keyword
-//~| HELP add `dyn` keyword before this trait
+//~^ ERROR expected a type, found a trait
+//~| HELP you can add the `dyn` keyword if you want a trait object
 //~| HELP you might have meant to write a bound here
-//~| ERROR the trait `Copy` cannot be made into an object
 
 fn g(_: impl Trait<T = std::fmt::Debug + Eq>) {}
-//~^ ERROR trait objects must include the `dyn` keyword
-//~| HELP add `dyn` keyword before this trait
+//~^ ERROR expected a type, found a trait
+//~| HELP you can add the `dyn` keyword if you want a trait object
 //~| HELP you might have meant to write a bound here
-//~| ERROR only auto traits can be used as additional traits in a trait object
-//~| HELP consider creating a new trait
-//~| ERROR the trait `Eq` cannot be made into an object
 
 fn h(_: impl Trait<T<> = 'static + for<'a> Fn(&'a ())>) {}
-//~^ ERROR trait objects must include the `dyn` keyword
-//~| HELP add `dyn` keyword before this trait
+//~^ ERROR expected a type, found a trait
+//~| HELP you can add the `dyn` keyword if you want a trait object
 //~| HELP you might have meant to write a bound here
 
 // Don't suggest assoc ty bound in trait object types, that's not valid:
 type Obj = dyn Trait<T = Clone>;
-//~^ ERROR trait objects must include the `dyn` keyword
-//~| HELP add `dyn` keyword before this trait
+//~^ ERROR expected a type, found a trait
+//~| HELP you can add the `dyn` keyword if you want a trait object
 
 trait Trait { type T; }
 
diff --git a/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr
index bec60187e42..dbe285c5310 100644
--- a/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr
+++ b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr
@@ -1,41 +1,10 @@
-error[E0038]: the trait `Copy` cannot be made into an object
-  --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:4:20
-   |
-LL | fn f(_: impl Trait<T = Copy>) {}
-   |                    ^^^^^^^^ `Copy` cannot be made into an object
-   |
-   = note: the trait cannot be made into an object because it requires `Self: Sized`
-   = 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>
-
-error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:10:42
-   |
-LL | fn g(_: impl Trait<T = std::fmt::Debug + Eq>) {}
-   |                        ---------------   ^^ additional non-auto trait
-   |                        |
-   |                        first non-auto trait
-   |
-   = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Debug + Eq {}`
-   = 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[E0038]: the trait `Eq` cannot be made into an object
-  --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:10:24
-   |
-LL | fn g(_: impl Trait<T = std::fmt::Debug + Eq>) {}
-   |                        ^^^^^^^^^^^^^^^^^^^^ `Eq` 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
-
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:4:24
    |
 LL | fn f(_: impl Trait<T = Copy>) {}
    |                        ^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | fn f(_: impl Trait<T = dyn Copy>) {}
    |                        +++
@@ -44,13 +13,13 @@ help: you might have meant to write a bound here
 LL | fn f(_: impl Trait<T: Copy>) {}
    |                     ~
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:10:24
+error[E0782]: expected a type, found a trait
+  --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:9:24
    |
 LL | fn g(_: impl Trait<T = std::fmt::Debug + Eq>) {}
    |                        ^^^^^^^^^^^^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | fn g(_: impl Trait<T = dyn std::fmt::Debug + Eq>) {}
    |                        +++
@@ -59,13 +28,13 @@ help: you might have meant to write a bound here
 LL | fn g(_: impl Trait<T: std::fmt::Debug + Eq>) {}
    |                     ~
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:18:26
+error[E0782]: expected a type, found a trait
+  --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:14:26
    |
 LL | fn h(_: impl Trait<T<> = 'static + for<'a> Fn(&'a ())>) {}
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | fn h(_: impl Trait<T<> = dyn 'static + for<'a> Fn(&'a ())>) {}
    |                          +++
@@ -74,18 +43,17 @@ help: you might have meant to write a bound here
 LL | fn h(_: impl Trait<T<>: 'static + for<'a> Fn(&'a ())>) {}
    |                       ~
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:24:26
+error[E0782]: expected a type, found a trait
+  --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:20:26
    |
 LL | type Obj = dyn Trait<T = Clone>;
    |                          ^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | type Obj = dyn Trait<T = dyn Clone>;
    |                          +++
 
-error: aborting due to 7 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0038, E0225, E0782.
-For more information about an error, try `rustc --explain E0038`.
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs
index 4bea3ad87f5..c1d3321f840 100644
--- a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs
+++ b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs
@@ -14,10 +14,8 @@ fn f<T>(
          1
      }],
 ) -> impl Iterator<Item = SubAssign> {
-//~^ ERROR the type parameter `Rhs` must be explicitly specified
+//~^ ERROR expected a type, found a trait
 //~| ERROR `()` is not an iterator
-//~| ERROR trait objects must include the `dyn` keyword
-//~| ERROR the type parameter `Rhs` must be explicitly specified [E0393]
 }
 
 pub fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr
index 416a9381124..5c4d643a28e 100644
--- a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr
@@ -16,37 +16,6 @@ help: you might be missing a type parameter
 LL | fn f<T, F>(
    |       +++
 
-error[E0393]: the type parameter `Rhs` must be explicitly specified
-  --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:27
-   |
-LL | ) -> impl Iterator<Item = SubAssign> {
-   |                           ^^^^^^^^^
-  --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
-   |
-   = note: type parameter `Rhs` must be specified for this
-   |
-   = note: because of the default `Self` reference, type parameters must be specified on object types
-help: set the type parameter to the desired type
-   |
-LL | ) -> impl Iterator<Item = SubAssign<Rhs>> {
-   |                                    +++++
-
-error[E0393]: the type parameter `Rhs` must be explicitly specified
-  --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:27
-   |
-LL | ) -> impl Iterator<Item = SubAssign> {
-   |                           ^^^^^^^^^
-  --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
-   |
-   = note: type parameter `Rhs` must be specified for this
-   |
-   = note: because of the default `Self` reference, type parameters must be specified on object types
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: set the type parameter to the desired type
-   |
-LL | ) -> impl Iterator<Item = SubAssign<Rhs>> {
-   |                                    +++++
-
 error[E0277]: `()` is not an iterator
   --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:6
    |
@@ -55,13 +24,13 @@ LL | ) -> impl Iterator<Item = SubAssign> {
    |
    = help: the trait `Iterator` is not implemented for `()`
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:27
    |
 LL | ) -> impl Iterator<Item = SubAssign> {
    |                           ^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | ) -> impl Iterator<Item = dyn SubAssign> {
    |                           +++
@@ -70,7 +39,7 @@ help: you might have meant to write a bound here
 LL | ) -> impl Iterator<Item: SubAssign> {
    |                        ~
 
-error: aborting due to 5 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0277, E0393, E0412, E0782.
+Some errors have detailed explanations: E0277, E0412, E0782.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/not_wf_param_in_rpitit.rs b/tests/ui/const-generics/not_wf_param_in_rpitit.rs
index eb672194340..b454562ad49 100644
--- a/tests/ui/const-generics/not_wf_param_in_rpitit.rs
+++ b/tests/ui/const-generics/not_wf_param_in_rpitit.rs
@@ -1,12 +1,11 @@
 //@ edition:2021
 
-trait Trait<const N: Trait = bar> {
+trait Trait<const N: dyn Trait = bar> {
     //~^ ERROR: cannot find value `bar` in this scope
     //~| ERROR: cycle detected when computing type of `Trait::N`
     //~| ERROR: the trait `Trait` cannot be made into an object
     //~| ERROR: the trait `Trait` cannot be made into an object
     //~| ERROR: the trait `Trait` cannot be made into an object
-    //~| ERROR: trait objects must include the `dyn` keyword
     async fn a() {}
 }
 
diff --git a/tests/ui/const-generics/not_wf_param_in_rpitit.stderr b/tests/ui/const-generics/not_wf_param_in_rpitit.stderr
index ade40550c73..2500409e828 100644
--- a/tests/ui/const-generics/not_wf_param_in_rpitit.stderr
+++ b/tests/ui/const-generics/not_wf_param_in_rpitit.stderr
@@ -1,33 +1,33 @@
 error[E0425]: cannot find value `bar` in this scope
-  --> $DIR/not_wf_param_in_rpitit.rs:3:30
+  --> $DIR/not_wf_param_in_rpitit.rs:3:34
    |
-LL | trait Trait<const N: Trait = bar> {
-   |                              ^^^ not found in this scope
+LL | trait Trait<const N: dyn Trait = bar> {
+   |                                  ^^^ not found in this scope
 
 error[E0391]: cycle detected when computing type of `Trait::N`
-  --> $DIR/not_wf_param_in_rpitit.rs:3:22
+  --> $DIR/not_wf_param_in_rpitit.rs:3:26
    |
-LL | trait Trait<const N: Trait = bar> {
-   |                      ^^^^^
+LL | trait Trait<const N: dyn Trait = bar> {
+   |                          ^^^^^
    |
    = note: ...which immediately requires computing type of `Trait::N` again
 note: cycle used when computing explicit predicates of trait `Trait`
   --> $DIR/not_wf_param_in_rpitit.rs:3:1
    |
-LL | trait Trait<const N: Trait = bar> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | trait Trait<const N: dyn Trait = bar> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/not_wf_param_in_rpitit.rs:3:22
    |
-LL | trait Trait<const N: Trait = bar> {
-   |                      ^^^^^ `Trait` cannot be made into an object
+LL | trait Trait<const N: dyn Trait = bar> {
+   |                      ^^^^^^^^^ `Trait` 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/not_wf_param_in_rpitit.rs:10:14
+  --> $DIR/not_wf_param_in_rpitit.rs:9:14
    |
-LL | trait Trait<const N: Trait = bar> {
+LL | trait Trait<const N: dyn Trait = bar> {
    |       ----- this trait cannot be made into an object...
 ...
 LL |     async fn a() {}
@@ -44,13 +44,13 @@ LL |     async fn a() where Self: Sized {}
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/not_wf_param_in_rpitit.rs:3:13
    |
-LL | trait Trait<const N: Trait = bar> {
-   |             ^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object
+LL | trait Trait<const N: dyn Trait = bar> {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ `Trait` 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/not_wf_param_in_rpitit.rs:10:14
+  --> $DIR/not_wf_param_in_rpitit.rs:9:14
    |
-LL | trait Trait<const N: Trait = bar> {
+LL | trait Trait<const N: dyn Trait = bar> {
    |       ----- this trait cannot be made into an object...
 ...
 LL |     async fn a() {}
@@ -67,13 +67,13 @@ LL |     async fn a() where Self: Sized {}
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/not_wf_param_in_rpitit.rs:3:13
    |
-LL | trait Trait<const N: Trait = bar> {
-   |             ^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object
+LL | trait Trait<const N: dyn Trait = bar> {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ `Trait` 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/not_wf_param_in_rpitit.rs:10:14
+  --> $DIR/not_wf_param_in_rpitit.rs:9:14
    |
-LL | trait Trait<const N: Trait = bar> {
+LL | trait Trait<const N: dyn Trait = bar> {
    |       ----- this trait cannot be made into an object...
 ...
 LL |     async fn a() {}
@@ -88,18 +88,7 @@ help: alternatively, consider constraining `a` so it does not apply to trait obj
 LL |     async fn a() where Self: Sized {}
    |                  +++++++++++++++++
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/not_wf_param_in_rpitit.rs:3:22
-   |
-LL | trait Trait<const N: Trait = bar> {
-   |                      ^^^^^
-   |
-help: add `dyn` keyword before this trait
-   |
-LL | trait Trait<const N: dyn Trait = bar> {
-   |                      +++
-
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0038, E0391, E0425, E0782.
+Some errors have detailed explanations: E0038, E0391, E0425.
 For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.new.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.new.stderr
index 4e3d2ebebad..83795f3128e 100644
--- a/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.new.stderr
+++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.new.stderr
@@ -1,41 +1,19 @@
-error[E0038]: the trait `Copy` cannot be made into an object
+error[E0782]: expected a type, found a trait
   --> $DIR/avoid-ice-on-warning-2.rs:4:13
    |
 LL | fn id<F>(f: Copy) -> usize {
-   |             ^^^^ `Copy` cannot be made into an object
+   |             ^^^^
    |
-   = note: the trait cannot be made into an object because it requires `Self: Sized`
-   = 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>
-
-error[E0618]: expected function, found `(dyn Copy + 'static)`
-  --> $DIR/avoid-ice-on-warning-2.rs:11:5
+   = note: `Copy` it is dyn-incompatible, so it can't be `dyn`
+help: use a new generic type parameter, constrained by `Copy`
    |
-LL | fn id<F>(f: Copy) -> usize {
-   |          - `f` has type `(dyn Copy + 'static)`
-...
-LL |     f()
-   |     ^--
-   |     |
-   |     call expression requires function
-
-error[E0277]: the size for values of type `(dyn Copy + 'static)` cannot be known at compilation time
-  --> $DIR/avoid-ice-on-warning-2.rs:4:13
-   |
-LL | fn id<F>(f: Copy) -> usize {
-   |             ^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `(dyn Copy + 'static)`
-   = help: unsized fn params are gated as an unstable feature
-help: you can use `impl Trait` as the argument type
+LL | fn id<F, T: Copy>(f: T) -> usize {
+   |        +++++++++     ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
    |
 LL | fn id<F>(f: impl Copy) -> usize {
    |             ++++
-help: function arguments must have a statically known size, borrowed types always have a known size
-   |
-LL | fn id<F>(f: &dyn Copy) -> usize {
-   |             ++++
 
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0038, E0277, E0618.
-For more information about an error, try `rustc --explain E0038`.
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr
index 180cd679dea..54daefea31c 100644
--- a/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr
+++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr
@@ -36,7 +36,7 @@ LL | fn id<F>(f: Copy) -> usize {
    = 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>
 
 error[E0618]: expected function, found `(dyn Copy + 'static)`
-  --> $DIR/avoid-ice-on-warning-2.rs:11:5
+  --> $DIR/avoid-ice-on-warning-2.rs:12:5
    |
 LL | fn id<F>(f: Copy) -> usize {
    |          - `f` has type `(dyn Copy + 'static)`
diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.rs b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.rs
index db2f4aea05b..3c2da667b39 100644
--- a/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.rs
+++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.rs
@@ -2,13 +2,14 @@
 //@[old] edition:2015
 //@[new] edition:2021
 fn id<F>(f: Copy) -> usize {
-//~^ ERROR the trait `Copy` cannot be made into an object
-//~| ERROR: the size for values of type `(dyn Copy + 'static)`
+//[new]~^ ERROR expected a type, found a trait
+//[old]~^^ ERROR the trait `Copy` cannot be made into an object
+//[old]~| ERROR the size for values of type `(dyn Copy + 'static)`
 //[old]~| WARN trait objects without an explicit `dyn` are deprecated
 //[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
 //[old]~| WARN trait objects without an explicit `dyn` are deprecated
 //[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
     f()
-    //~^ ERROR: expected function, found `(dyn Copy + 'static)`
+    //[old]~^ ERROR: expected function, found `(dyn Copy + 'static)`
 }
 fn main() {}
diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.new.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.new.stderr
index fdd3e8ab507..813b5863738 100644
--- a/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.new.stderr
+++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.new.stderr
@@ -1,47 +1,57 @@
-error[E0038]: the trait `A` cannot be made into an object
-  --> $DIR/avoid-ice-on-warning-3.rs:4:19
+error[E0782]: expected a type, found a trait
+  --> $DIR/avoid-ice-on-warning-3.rs:14:19
    |
-LL | trait B { fn f(a: A) -> A; }
-   |                   ^ `A` cannot be made into an object
+LL | trait A { fn g(b: B) -> B; }
+   |                   ^
    |
-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/avoid-ice-on-warning-3.rs:12:14
+   = note: `B` it is dyn-incompatible, so it can't be `dyn`
+help: use a new generic type parameter, constrained by `B`
+   |
+LL | trait A { fn g<T: B>(b: T) -> B; }
+   |               ++++++    ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL | trait A { fn g(b: impl B) -> B; }
+   |                   ++++
+
+error[E0782]: expected a type, found a trait
+  --> $DIR/avoid-ice-on-warning-3.rs:14:25
    |
 LL | trait A { fn g(b: B) -> B; }
-   |       -      ^ ...because associated function `g` has no `self` parameter
-   |       |
-   |       this trait cannot be made into an object...
-help: consider turning `g` into a method by giving it a `&self` argument
+   |                         ^
    |
-LL | trait A { fn g(&self, b: B) -> B; }
-   |                ++++++
-help: alternatively, consider constraining `g` so it does not apply to trait objects
+help: `B` is dyn-incompatible, use `impl B` to return an opaque type, as long as you return a single underlying type
    |
-LL | trait A { fn g(b: B) -> B where Self: Sized; }
-   |                           +++++++++++++++++
+LL | trait A { fn g(b: B) -> impl B; }
+   |                         ++++
 
-error[E0038]: the trait `B` cannot be made into an object
-  --> $DIR/avoid-ice-on-warning-3.rs:12:19
+error[E0782]: expected a type, found a trait
+  --> $DIR/avoid-ice-on-warning-3.rs:4:19
    |
-LL | trait A { fn g(b: B) -> B; }
-   |                   ^ `B` cannot be made into an object
+LL | trait B { fn f(a: A) -> A; }
+   |                   ^
    |
-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/avoid-ice-on-warning-3.rs:4:14
+   = note: `A` it is dyn-incompatible, so it can't be `dyn`
+help: use a new generic type parameter, constrained by `A`
+   |
+LL | trait B { fn f<T: A>(a: T) -> A; }
+   |               ++++++    ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL | trait B { fn f(a: impl A) -> A; }
+   |                   ++++
+
+error[E0782]: expected a type, found a trait
+  --> $DIR/avoid-ice-on-warning-3.rs:4:25
    |
 LL | trait B { fn f(a: A) -> A; }
-   |       -      ^ ...because associated function `f` has no `self` parameter
-   |       |
-   |       this trait cannot be made into an object...
-help: consider turning `f` into a method by giving it a `&self` argument
+   |                         ^
    |
-LL | trait B { fn f(&self, a: A) -> A; }
-   |                ++++++
-help: alternatively, consider constraining `f` so it does not apply to trait objects
+help: `A` is dyn-incompatible, use `impl A` to return an opaque type, as long as you return a single underlying type
    |
-LL | trait B { fn f(a: A) -> A where Self: Sized; }
-   |                           +++++++++++++++++
+LL | trait B { fn f(a: A) -> impl A; }
+   |                         ++++
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0038`.
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr
index bd362abb355..6bc2d73a0d0 100644
--- a/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr
+++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr
@@ -26,7 +26,7 @@ LL | trait B { fn f(a: A) -> dyn A; }
    |                         +++
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/avoid-ice-on-warning-3.rs:12:19
+  --> $DIR/avoid-ice-on-warning-3.rs:14:19
    |
 LL | trait A { fn g(b: B) -> B; }
    |                   ^
@@ -39,7 +39,7 @@ LL | trait A { fn g(b: dyn B) -> B; }
    |                   +++
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/avoid-ice-on-warning-3.rs:12:25
+  --> $DIR/avoid-ice-on-warning-3.rs:14:25
    |
 LL | trait A { fn g(b: B) -> B; }
    |                         ^
@@ -72,7 +72,7 @@ LL | trait B { fn f(a: A) -> A; }
    |                   ^ `A` 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/avoid-ice-on-warning-3.rs:12:14
+  --> $DIR/avoid-ice-on-warning-3.rs:14:14
    |
 LL | trait A { fn g(b: B) -> B; }
    |       -      ^ ...because associated function `g` has no `self` parameter
@@ -88,7 +88,7 @@ LL | trait A { fn g(b: B) -> B where Self: Sized; }
    |                           +++++++++++++++++
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/avoid-ice-on-warning-3.rs:12:19
+  --> $DIR/avoid-ice-on-warning-3.rs:14:19
    |
 LL | trait A { fn g(b: B) -> B; }
    |                   ^
@@ -102,7 +102,7 @@ LL | trait A { fn g(b: dyn B) -> B; }
    |                   +++
 
 error[E0038]: the trait `B` cannot be made into an object
-  --> $DIR/avoid-ice-on-warning-3.rs:12:19
+  --> $DIR/avoid-ice-on-warning-3.rs:14:19
    |
 LL | trait A { fn g(b: B) -> B; }
    |                   ^ `B` cannot be made into an object
diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.rs b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.rs
index 38bee8142bb..00d47225e92 100644
--- a/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.rs
+++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.rs
@@ -2,7 +2,9 @@
 //@[old] edition:2015
 //@[new] edition:2021
 trait B { fn f(a: A) -> A; }
-//~^ ERROR the trait `A` cannot be made into an object
+//[new]~^ ERROR expected a type, found a trait
+//[new]~| ERROR expected a type, found a trait
+//[old]~^^^ ERROR the trait `A` cannot be made into an object
 //[old]~| WARN trait objects without an explicit `dyn` are deprecated
 //[old]~| WARN trait objects without an explicit `dyn` are deprecated
 //[old]~| WARN trait objects without an explicit `dyn` are deprecated
@@ -10,7 +12,9 @@ trait B { fn f(a: A) -> A; }
 //[old]~| WARN this is accepted in the current edition
 //[old]~| WARN this is accepted in the current edition
 trait A { fn g(b: B) -> B; }
-//~^ ERROR the trait `B` cannot be made into an object
+//[new]~^ ERROR expected a type, found a trait
+//[new]~| ERROR expected a type, found a trait
+//[old]~^^^ ERROR the trait `B` cannot be made into an object
 //[old]~| WARN trait objects without an explicit `dyn` are deprecated
 //[old]~| WARN trait objects without an explicit `dyn` are deprecated
 //[old]~| WARN trait objects without an explicit `dyn` are deprecated
diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning.new.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning.new.stderr
index 4ff45d7a848..e9eb1cdd0c2 100644
--- a/tests/ui/dyn-compatibility/avoid-ice-on-warning.new.stderr
+++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning.new.stderr
@@ -15,6 +15,18 @@ error[E0405]: cannot find trait `call_that` in this scope
 LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
    |                                    ^^^^^^^^^ not found in this scope
 
-error: aborting due to 2 previous errors
+error[E0782]: expected a type, found a trait
+  --> $DIR/avoid-ice-on-warning.rs:4:25
+   |
+LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
+   |                         ^^^^^^^^^^^^^^^^^^^^
+   |
+help: `Fn(&str) + call_that` is dyn-incompatible, use `impl Fn(&str) + call_that` to return an opaque type, as long as you return a single underlying type
+   |
+LL | fn call_this<F>(f: F) : impl Fn(&str) + call_that {}
+   |                         ++++
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0405`.
+Some errors have detailed explanations: E0405, E0782.
+For more information about an error, try `rustc --explain E0405`.
diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning.rs b/tests/ui/dyn-compatibility/avoid-ice-on-warning.rs
index b90d8911d50..ef82321df0e 100644
--- a/tests/ui/dyn-compatibility/avoid-ice-on-warning.rs
+++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning.rs
@@ -4,6 +4,7 @@
 fn call_this<F>(f: F) : Fn(&str) + call_that {}
 //~^ ERROR return types are denoted using `->`
 //~| ERROR cannot find trait `call_that` in this scope
+//[new]~| ERROR expected a type, found a trait
 //[old]~| WARN trait objects without an explicit `dyn` are deprecated
 //[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
 fn main() {}
diff --git a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.fixed b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.fixed
index 4f5310082e1..a54892afd3e 100644
--- a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.fixed
+++ b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.fixed
@@ -4,7 +4,8 @@
 //@[new] run-rustfix
 #![deny(bare_trait_objects)]
 fn ord_prefer_dot(s: String) -> impl Ord {
-    //~^ ERROR the trait `Ord` cannot be made into an object
+    //[new]~^ ERROR expected a type, found a trait
+    //[old]~^^ ERROR the trait `Ord` cannot be made into an object
     //[old]~| ERROR trait objects without an explicit `dyn` are deprecated
     //[old]~| WARNING this is accepted in the current edition (Rust 2015)
     (s.starts_with("."), s)
diff --git a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.stderr b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.stderr
index bb2bf6ddcda..52168261a64 100644
--- a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.stderr
+++ b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.new.stderr
@@ -1,21 +1,14 @@
-error[E0038]: the trait `Ord` cannot be made into an object
+error[E0782]: expected a type, found a trait
   --> $DIR/bare-trait-dont-suggest-dyn.rs:6:33
    |
 LL | fn ord_prefer_dot(s: String) -> Ord {
-   |                                 ^^^ `Ord` 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
-  ::: $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
-help: consider using an opaque type instead
+help: `Ord` is dyn-incompatible, use `impl Ord` to return an opaque type, as long as you return a single underlying type
    |
 LL | fn ord_prefer_dot(s: String) -> impl Ord {
    |                                 ++++
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0038`.
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.rs b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.rs
index cb5a305eab0..cf9be612d2e 100644
--- a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.rs
+++ b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.rs
@@ -4,7 +4,8 @@
 //@[new] run-rustfix
 #![deny(bare_trait_objects)]
 fn ord_prefer_dot(s: String) -> Ord {
-    //~^ ERROR the trait `Ord` cannot be made into an object
+    //[new]~^ ERROR expected a type, found a trait
+    //[old]~^^ ERROR the trait `Ord` cannot be made into an object
     //[old]~| ERROR trait objects without an explicit `dyn` are deprecated
     //[old]~| WARNING this is accepted in the current edition (Rust 2015)
     (s.starts_with("."), s)
diff --git a/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs b/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs
index dabaa309c16..7bc2af463cb 100644
--- a/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs
+++ b/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs
@@ -6,104 +6,102 @@ struct IceCream;
 
 impl IceCream {
     fn foo(_: &Trait) {}
-    //~^ ERROR: trait objects must include the `dyn` keyword
+    //~^ ERROR: expected a type, found a trait
 
     fn bar(self, _: &'a Trait) {}
-    //~^ ERROR: trait objects must include the `dyn` keyword
+    //~^ ERROR: expected a type, found a trait
     //~| ERROR: use of undeclared lifetime name
 
     fn alice<'a>(&self, _: &Trait) {}
-    //~^ ERROR: trait objects must include the `dyn` keyword
+    //~^ ERROR: expected a type, found a trait
 
     fn bob<'a>(_: &'a Trait) {}
-    //~^ ERROR: trait objects must include the `dyn` keyword
+    //~^ ERROR: expected a type, found a trait
 
     fn cat() -> &Trait {
         //~^ ERROR: missing lifetime specifier
-        //~| ERROR: trait objects must include the `dyn` keyword
+        //~| ERROR: expected a type, found a trait
         &Type
     }
 
     fn dog<'a>() -> &Trait {
         //~^ ERROR: missing lifetime specifier
-        //~| ERROR: trait objects must include the `dyn` keyword
+        //~| ERROR: expected a type, found a trait
         &Type
     }
 
     fn kitten() -> &'a Trait {
         //~^ ERROR: use of undeclared lifetime name
-        //~| ERROR: trait objects must include the `dyn` keyword
+        //~| ERROR: expected a type, found a trait
         &Type
     }
 
     fn puppy<'a>() -> &'a Trait {
-        //~^ ERROR: trait objects must include the `dyn` keyword
+        //~^ ERROR: expected a type, found a trait
         &Type
     }
 
     fn parrot() -> &mut Trait {
         //~^ ERROR: missing lifetime specifier
-        //~| ERROR: trait objects must include the `dyn` keyword
+        //~| ERROR: expected a type, found a trait
         &mut Type
-        //~^ ERROR: cannot return reference to temporary value
     }
 }
 
 trait Sing {
     fn foo(_: &Trait);
-    //~^ ERROR: trait objects must include the `dyn` keyword
+    //~^ ERROR: expected a type, found a trait
 
     fn bar(_: &'a Trait);
-    //~^ ERROR: trait objects must include the `dyn` keyword
+    //~^ ERROR: expected a type, found a trait
     //~| ERROR: use of undeclared lifetime name
 
     fn alice<'a>(_: &Trait);
-    //~^ ERROR: trait objects must include the `dyn` keyword
+    //~^ ERROR: expected a type, found a trait
 
     fn bob<'a>(_: &'a Trait);
-    //~^ ERROR: trait objects must include the `dyn` keyword
+    //~^ ERROR: expected a type, found a trait
 
     fn cat() -> &Trait;
         //~^ ERROR: missing lifetime specifier
-        //~| ERROR: trait objects must include the `dyn` keyword
+        //~| ERROR: expected a type, found a trait
 
     fn dog<'a>() -> &Trait {
         //~^ ERROR: missing lifetime specifier
-        //~| ERROR: trait objects must include the `dyn` keyword
+        //~| ERROR: expected a type, found a trait
         &Type
     }
 
     fn kitten() -> &'a Trait {
         //~^ ERROR: use of undeclared lifetime name
-        //~| ERROR: trait objects must include the `dyn` keyword
+        //~| ERROR: expected a type, found a trait
         &Type
     }
 
     fn puppy<'a>() -> &'a Trait {
-        //~^ ERROR: trait objects must include the `dyn` keyword
+        //~^ ERROR: expected a type, found a trait
         &Type
     }
 
     fn parrot() -> &mut Trait {
         //~^ ERROR: missing lifetime specifier
-        //~| ERROR: trait objects must include the `dyn` keyword
+        //~| ERROR: expected a type, found a trait
         &mut Type
-        //~^ ERROR: cannot return reference to temporary value
     }
 }
 
 fn foo(_: &Trait) {}
-//~^ ERROR: trait objects must include the `dyn` keyword
+//~^ ERROR: expected a type, found a trait
 
 fn bar(_: &'a Trait) {}
-//~^ ERROR: trait objects must include the `dyn` keyword
+//~^ ERROR: expected a type, found a trait
 //~| ERROR: use of undeclared lifetime name
 
 fn alice<'a>(_: &Trait) {}
-//~^ ERROR: trait objects must include the `dyn` keyword
+//~^ ERROR: expected a type, found a trait
 
 fn bob<'a>(_: &'a Trait) {}
-//~^ ERROR: trait objects must include the `dyn` keyword
+//~^ ERROR: expected a type, found a trait
 
 struct Type;
 
@@ -111,32 +109,31 @@ impl Trait for Type {}
 
 fn cat() -> &Trait {
 //~^ ERROR: missing lifetime specifier
-//~| ERROR: trait objects must include the `dyn` keyword
+//~| ERROR: expected a type, found a trait
     &Type
 }
 
 fn dog<'a>() -> &Trait {
 //~^ ERROR: missing lifetime specifier
-//~| ERROR: trait objects must include the `dyn` keyword
+//~| ERROR: expected a type, found a trait
     &Type
 }
 
 fn kitten() -> &'a Trait {
 //~^ ERROR: use of undeclared lifetime name
-//~| ERROR: trait objects must include the `dyn` keyword
+//~| ERROR: expected a type, found a trait
     &Type
 }
 
 fn puppy<'a>() -> &'a Trait {
-//~^ ERROR: trait objects must include the `dyn` keyword
+//~^ ERROR: expected a type, found a trait
     &Type
 }
 
 fn parrot() -> &mut Trait {
     //~^ ERROR: missing lifetime specifier
-    //~| ERROR: trait objects must include the `dyn` keyword
+    //~| ERROR: expected a type, found a trait
     &mut Type
-    //~^ ERROR: cannot return reference to temporary value
 }
 
 fn main() {}
diff --git a/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr b/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr
index 8bdfea7766e..4c6d84f0534 100644
--- a/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr
+++ b/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr
@@ -65,7 +65,7 @@ LL |     fn parrot() -> &'static mut Trait {
    |                     +++++++
 
 error[E0261]: use of undeclared lifetime name `'a`
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:56:16
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:55:16
    |
 LL |     fn bar(_: &'a Trait);
    |                ^^ undeclared lifetime
@@ -80,7 +80,7 @@ LL | trait Sing<'a> {
    |           ++++
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:66:17
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:65:17
    |
 LL |     fn cat() -> &Trait;
    |                 ^ expected named lifetime parameter
@@ -97,7 +97,7 @@ LL +     fn cat() -> Trait;
    |
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:70:21
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:69:21
    |
 LL |     fn dog<'a>() -> &Trait {
    |                     ^ expected named lifetime parameter
@@ -109,7 +109,7 @@ LL |     fn dog<'a>() -> &'a Trait {
    |                      ++
 
 error[E0261]: use of undeclared lifetime name `'a`
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:76:21
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:75:21
    |
 LL |     fn kitten() -> &'a Trait {
    |                     ^^ undeclared lifetime
@@ -124,7 +124,7 @@ LL | trait Sing<'a> {
    |           ++++
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:87:20
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:86:20
    |
 LL |     fn parrot() -> &mut Trait {
    |                    ^ expected named lifetime parameter
@@ -136,7 +136,7 @@ LL |     fn parrot() -> &'static mut Trait {
    |                     +++++++
 
 error[E0261]: use of undeclared lifetime name `'a`
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:98:12
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:96:12
    |
 LL | fn bar(_: &'a Trait) {}
    |       -    ^^ undeclared lifetime
@@ -144,7 +144,7 @@ LL | fn bar(_: &'a Trait) {}
    |       help: consider introducing lifetime `'a` here: `<'a>`
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:112:13
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:110:13
    |
 LL | fn cat() -> &Trait {
    |             ^ expected named lifetime parameter
@@ -156,7 +156,7 @@ LL | fn cat() -> &'static Trait {
    |              +++++++
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:118:17
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:116:17
    |
 LL | fn dog<'a>() -> &Trait {
    |                 ^ expected named lifetime parameter
@@ -168,7 +168,7 @@ LL | fn dog<'a>() -> &'a Trait {
    |                  ++
 
 error[E0261]: use of undeclared lifetime name `'a`
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:124:17
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:122:17
    |
 LL | fn kitten() -> &'a Trait {
    |          -      ^^ undeclared lifetime
@@ -176,7 +176,7 @@ LL | fn kitten() -> &'a Trait {
    |          help: consider introducing lifetime `'a` here: `<'a>`
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:135:16
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:133:16
    |
 LL | fn parrot() -> &mut Trait {
    |                ^ expected named lifetime parameter
@@ -187,35 +187,8 @@ help: consider using the `'static` lifetime, but this is uncommon unless you're
 LL | fn parrot() -> &'static mut Trait {
    |                 +++++++
 
-error[E0515]: cannot return reference to temporary value
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:47:9
-   |
-LL |         &mut Type
-   |         ^^^^^----
-   |         |    |
-   |         |    temporary value created here
-   |         returns a reference to data owned by the current function
-
-error[E0515]: cannot return reference to temporary value
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:90:9
-   |
-LL |         &mut Type
-   |         ^^^^^----
-   |         |    |
-   |         |    temporary value created here
-   |         returns a reference to data owned by the current function
-
-error[E0515]: cannot return reference to temporary value
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:138:5
-   |
-LL |     &mut Type
-   |     ^^^^^----
-   |     |    |
-   |     |    temporary value created here
-   |     returns a reference to data owned by the current function
-
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:53:16
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:52:16
    |
 LL |     fn foo(_: &Trait);
    |                ^^^^^
@@ -233,8 +206,8 @@ help: alternatively, use a trait object to accept any type that implements `Trai
 LL |     fn foo(_: &dyn Trait);
    |                +++
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:56:19
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:55:19
    |
 LL |     fn bar(_: &'a Trait);
    |                   ^^^^^
@@ -252,8 +225,8 @@ help: alternatively, use a trait object to accept any type that implements `Trai
 LL |     fn bar(_: &'a dyn Trait);
    |                   +++
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:60:22
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:59:22
    |
 LL |     fn alice<'a>(_: &Trait);
    |                      ^^^^^
@@ -271,8 +244,8 @@ help: alternatively, use a trait object to accept any type that implements `Trai
 LL |     fn alice<'a>(_: &dyn Trait);
    |                      +++
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:63:23
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:62:23
    |
 LL |     fn bob<'a>(_: &'a Trait);
    |                       ^^^^^
@@ -290,8 +263,8 @@ help: alternatively, use a trait object to accept any type that implements `Trai
 LL |     fn bob<'a>(_: &'a dyn Trait);
    |                       +++
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:66:18
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:65:18
    |
 LL |     fn cat() -> &Trait;
    |                  ^^^^^
@@ -305,8 +278,8 @@ help: alternatively, you can return an owned trait object
 LL |     fn cat() -> Box<dyn Trait>;
    |                 ~~~~~~~~~~~~~~
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:70:22
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:69:22
    |
 LL |     fn dog<'a>() -> &Trait {
    |                      ^^^^^
@@ -320,8 +293,8 @@ help: alternatively, you can return an owned trait object
 LL |     fn dog<'a>() -> Box<dyn Trait> {
    |                     ~~~~~~~~~~~~~~
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:76:24
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:75:24
    |
 LL |     fn kitten() -> &'a Trait {
    |                        ^^^^^
@@ -335,8 +308,8 @@ help: alternatively, you can return an owned trait object
 LL |     fn kitten() -> Box<dyn Trait> {
    |                    ~~~~~~~~~~~~~~
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:82:27
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:81:27
    |
 LL |     fn puppy<'a>() -> &'a Trait {
    |                           ^^^^^
@@ -350,8 +323,8 @@ help: alternatively, you can return an owned trait object
 LL |     fn puppy<'a>() -> Box<dyn Trait> {
    |                       ~~~~~~~~~~~~~~
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:87:25
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:86:25
    |
 LL |     fn parrot() -> &mut Trait {
    |                         ^^^^^
@@ -365,8 +338,8 @@ help: alternatively, you can return an owned trait object
 LL |     fn parrot() -> Box<dyn Trait> {
    |                    ~~~~~~~~~~~~~~
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:95:12
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:93:12
    |
 LL | fn foo(_: &Trait) {}
    |            ^^^^^
@@ -384,8 +357,8 @@ help: alternatively, use a trait object to accept any type that implements `Trai
 LL | fn foo(_: &dyn Trait) {}
    |            +++
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:98:15
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:96:15
    |
 LL | fn bar(_: &'a Trait) {}
    |               ^^^^^
@@ -403,8 +376,8 @@ help: alternatively, use a trait object to accept any type that implements `Trai
 LL | fn bar(_: &'a dyn Trait) {}
    |               +++
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:102:18
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:100:18
    |
 LL | fn alice<'a>(_: &Trait) {}
    |                  ^^^^^
@@ -422,8 +395,8 @@ help: alternatively, use a trait object to accept any type that implements `Trai
 LL | fn alice<'a>(_: &dyn Trait) {}
    |                  +++
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:105:19
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:103:19
    |
 LL | fn bob<'a>(_: &'a Trait) {}
    |                   ^^^^^
@@ -441,8 +414,8 @@ help: alternatively, use a trait object to accept any type that implements `Trai
 LL | fn bob<'a>(_: &'a dyn Trait) {}
    |                   +++
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:112:14
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:110:14
    |
 LL | fn cat() -> &Trait {
    |              ^^^^^
@@ -456,8 +429,8 @@ help: alternatively, you can return an owned trait object
 LL | fn cat() -> Box<dyn Trait> {
    |             ~~~~~~~~~~~~~~
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:118:18
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:116:18
    |
 LL | fn dog<'a>() -> &Trait {
    |                  ^^^^^
@@ -471,8 +444,8 @@ help: alternatively, you can return an owned trait object
 LL | fn dog<'a>() -> Box<dyn Trait> {
    |                 ~~~~~~~~~~~~~~
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:124:20
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:122:20
    |
 LL | fn kitten() -> &'a Trait {
    |                    ^^^^^
@@ -486,8 +459,8 @@ help: alternatively, you can return an owned trait object
 LL | fn kitten() -> Box<dyn Trait> {
    |                ~~~~~~~~~~~~~~
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:130:23
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:128:23
    |
 LL | fn puppy<'a>() -> &'a Trait {
    |                       ^^^^^
@@ -501,8 +474,8 @@ help: alternatively, you can return an owned trait object
 LL | fn puppy<'a>() -> Box<dyn Trait> {
    |                   ~~~~~~~~~~~~~~
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:135:21
+error[E0782]: expected a type, found a trait
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:133:21
    |
 LL | fn parrot() -> &mut Trait {
    |                     ^^^^^
@@ -516,7 +489,7 @@ help: alternatively, you can return an owned trait object
 LL | fn parrot() -> Box<dyn Trait> {
    |                ~~~~~~~~~~~~~~
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:8:16
    |
 LL |     fn foo(_: &Trait) {}
@@ -535,7 +508,7 @@ help: alternatively, use a trait object to accept any type that implements `Trai
 LL |     fn foo(_: &dyn Trait) {}
    |                +++
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:11:25
    |
 LL |     fn bar(self, _: &'a Trait) {}
@@ -554,7 +527,7 @@ help: alternatively, use a trait object to accept any type that implements `Trai
 LL |     fn bar(self, _: &'a dyn Trait) {}
    |                         +++
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:15:29
    |
 LL |     fn alice<'a>(&self, _: &Trait) {}
@@ -573,7 +546,7 @@ help: alternatively, use a trait object to accept any type that implements `Trai
 LL |     fn alice<'a>(&self, _: &dyn Trait) {}
    |                             +++
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:18:23
    |
 LL |     fn bob<'a>(_: &'a Trait) {}
@@ -592,7 +565,7 @@ help: alternatively, use a trait object to accept any type that implements `Trai
 LL |     fn bob<'a>(_: &'a dyn Trait) {}
    |                       +++
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:21:18
    |
 LL |     fn cat() -> &Trait {
@@ -607,7 +580,7 @@ help: alternatively, you can return an owned trait object
 LL |     fn cat() -> Box<dyn Trait> {
    |                 ~~~~~~~~~~~~~~
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:27:22
    |
 LL |     fn dog<'a>() -> &Trait {
@@ -622,7 +595,7 @@ help: alternatively, you can return an owned trait object
 LL |     fn dog<'a>() -> Box<dyn Trait> {
    |                     ~~~~~~~~~~~~~~
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:33:24
    |
 LL |     fn kitten() -> &'a Trait {
@@ -637,7 +610,7 @@ help: alternatively, you can return an owned trait object
 LL |     fn kitten() -> Box<dyn Trait> {
    |                    ~~~~~~~~~~~~~~
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:39:27
    |
 LL |     fn puppy<'a>() -> &'a Trait {
@@ -652,7 +625,7 @@ help: alternatively, you can return an owned trait object
 LL |     fn puppy<'a>() -> Box<dyn Trait> {
    |                       ~~~~~~~~~~~~~~
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:44:25
    |
 LL |     fn parrot() -> &mut Trait {
@@ -667,7 +640,7 @@ help: alternatively, you can return an owned trait object
 LL |     fn parrot() -> Box<dyn Trait> {
    |                    ~~~~~~~~~~~~~~
 
-error: aborting due to 45 previous errors
+error: aborting due to 42 previous errors
 
-Some errors have detailed explanations: E0106, E0261, E0515, E0782.
+Some errors have detailed explanations: E0106, E0261, E0782.
 For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/dyn-keyword/dyn-2021-edition-error.rs b/tests/ui/dyn-keyword/dyn-2021-edition-error.rs
index f98bf4ef5d1..5d607d82ea1 100644
--- a/tests/ui/dyn-keyword/dyn-2021-edition-error.rs
+++ b/tests/ui/dyn-keyword/dyn-2021-edition-error.rs
@@ -1,10 +1,10 @@
 //@ edition:2021
 
 fn function(x: &SomeTrait, y: Box<SomeTrait>) {
-    //~^ ERROR trait objects must include the `dyn` keyword
-    //~| ERROR trait objects must include the `dyn` keyword
+    //~^ ERROR expected a type, found a trait
+    //~| ERROR expected a type, found a trait
     let _x: &SomeTrait = todo!();
-    //~^ ERROR trait objects must include the `dyn` keyword
+    //~^ ERROR expected a type, found a trait
 }
 
 trait SomeTrait {}
diff --git a/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr b/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr
index 52ee6c81ab7..6d1a1618ac0 100644
--- a/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr
+++ b/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr
@@ -1,4 +1,4 @@
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/dyn-2021-edition-error.rs:3:17
    |
 LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
@@ -17,24 +17,24 @@ help: alternatively, use a trait object to accept any type that implements `Some
 LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
    |                 +++
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/dyn-2021-edition-error.rs:3:35
    |
 LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
    |                                   ^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
    |                                   +++
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/dyn-2021-edition-error.rs:6:14
    |
 LL |     let _x: &SomeTrait = todo!();
    |              ^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL |     let _x: &dyn SomeTrait = todo!();
    |              +++
diff --git a/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.rs b/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.rs
index 19b5edb620f..bee15788da9 100644
--- a/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.rs
+++ b/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.rs
@@ -9,6 +9,7 @@ impl dyn Trait {
 fn main() {
     match () {
         Trait::CONST => {}
-        //~^ ERROR trait objects must include the `dyn` keyword
+        //~^ ERROR expected a type, found a trait
+        //~| HELP you can add the `dyn` keyword if you want a trait object
     }
 }
diff --git a/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr b/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr
index 4446a89b63b..6a2bb3ec09a 100644
--- a/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr
+++ b/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr
@@ -1,10 +1,10 @@
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/suggest-dyn-on-bare-trait-in-pat.rs:11:9
    |
 LL |         Trait::CONST => {}
    |         ^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL |         <dyn Trait>::CONST => {}
    |         ++++      +
diff --git a/tests/ui/editions/dyn-trait-sugg-2021.rs b/tests/ui/editions/dyn-trait-sugg-2021.rs
index d702bfb2f88..a5364662600 100644
--- a/tests/ui/editions/dyn-trait-sugg-2021.rs
+++ b/tests/ui/editions/dyn-trait-sugg-2021.rs
@@ -8,5 +8,5 @@ impl<T> dyn Foo<T> {
 
 fn main() {
     Foo::hi(123);
-    //~^ ERROR trait objects must include the `dyn` keyword
+    //~^ ERROR expected a type, found a trait
 }
diff --git a/tests/ui/editions/dyn-trait-sugg-2021.stderr b/tests/ui/editions/dyn-trait-sugg-2021.stderr
index 8a65fea11c9..3aea8ac491d 100644
--- a/tests/ui/editions/dyn-trait-sugg-2021.stderr
+++ b/tests/ui/editions/dyn-trait-sugg-2021.stderr
@@ -1,10 +1,10 @@
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/dyn-trait-sugg-2021.rs:10:5
    |
 LL |     Foo::hi(123);
    |     ^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL |     <dyn Foo>::hi(123);
    |     ++++    +
diff --git a/tests/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr b/tests/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr
index 7917fa991ee..1e268bc7f49 100644
--- a/tests/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr
+++ b/tests/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr
@@ -1,21 +1,14 @@
-error[E0277]: the trait bound `(): AsRef<(dyn for<'a> Fn(&'a ()) + 'static)>` is not satisfied
-  --> $DIR/generic-with-implicit-hrtb-without-dyn.rs:6:13
-   |
-LL | fn ice() -> impl AsRef<Fn(&())> {
-   |             ^^^^^^^^^^^^^^^^^^^ the trait `AsRef<(dyn for<'a> Fn(&'a ()) + 'static)>` is not implemented for `()`
-
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/generic-with-implicit-hrtb-without-dyn.rs:6:24
    |
 LL | fn ice() -> impl AsRef<Fn(&())> {
    |                        ^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | fn ice() -> impl AsRef<dyn Fn(&())> {
    |                        +++
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0277, E0782.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs b/tests/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs
index 582386aa759..c71f794d5d1 100644
--- a/tests/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs
+++ b/tests/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs
@@ -5,8 +5,7 @@
 
 fn ice() -> impl AsRef<Fn(&())> {
     //[edition2015]~^ ERROR: the trait bound `(): AsRef<(dyn for<'a> Fn(&'a ()) + 'static)>` is not satisfied [E0277]
-    //[edition2021]~^^ ERROR: trait objects must include the `dyn` keyword [E0782]
-    //[edition2021]~| ERROR: the trait bound `(): AsRef<(dyn for<'a> Fn(&'a ()) + 'static)>` is not satisfied [E0277]
+    //[edition2021]~^^ ERROR: expected a type, found a trait [E0782]
     todo!()
 }
 
diff --git a/tests/ui/resolve/issue-111312.rs b/tests/ui/resolve/issue-111312.rs
index 79c6f67dadd..574e9870cd2 100644
--- a/tests/ui/resolve/issue-111312.rs
+++ b/tests/ui/resolve/issue-111312.rs
@@ -8,6 +8,5 @@ trait HasNot {}
 
 fn main() {
     HasNot::has();
-    //~^ ERROR trait objects must include the `dyn` keyword
-    //~| ERROR no function or associated item named `has` found for trait `HasNot`
+    //~^ ERROR expected a type, found a trait
 }
diff --git a/tests/ui/resolve/issue-111312.stderr b/tests/ui/resolve/issue-111312.stderr
index 431802ead30..a1f8d6bc46c 100644
--- a/tests/ui/resolve/issue-111312.stderr
+++ b/tests/ui/resolve/issue-111312.stderr
@@ -1,27 +1,14 @@
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/issue-111312.rs:10:5
    |
 LL |     HasNot::has();
    |     ^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL |     <dyn HasNot>::has();
    |     ++++       +
 
-error[E0599]: no function or associated item named `has` found for trait `HasNot`
-  --> $DIR/issue-111312.rs:10:13
-   |
-LL |     HasNot::has();
-   |             ^^^ function or associated item not found in `HasNot`
-   |
-note: `Has` defines an item `has`
-  --> $DIR/issue-111312.rs:3:1
-   |
-LL | trait Has {
-   | ^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0599, E0782.
-For more information about an error, try `rustc --explain E0599`.
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/resolve/issue-111727.rs b/tests/ui/resolve/issue-111727.rs
index fcab924b809..a5c2c0ca8c6 100644
--- a/tests/ui/resolve/issue-111727.rs
+++ b/tests/ui/resolve/issue-111727.rs
@@ -2,6 +2,5 @@
 
 fn main() {
     std::any::Any::create();
-    //~^ ERROR trait objects must include the `dyn` keyword
-    //~| ERROR no function or associated item named `create` found for trait `Any`
+    //~^ ERROR expected a type, found a trait
 }
diff --git a/tests/ui/resolve/issue-111727.stderr b/tests/ui/resolve/issue-111727.stderr
index 1ef5a1a1d5e..71ea989ac34 100644
--- a/tests/ui/resolve/issue-111727.stderr
+++ b/tests/ui/resolve/issue-111727.stderr
@@ -1,21 +1,14 @@
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/issue-111727.rs:4:5
    |
 LL |     std::any::Any::create();
    |     ^^^^^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL |     <dyn std::any::Any>::create();
    |     ++++              +
 
-error[E0599]: no function or associated item named `create` found for trait `Any`
-  --> $DIR/issue-111727.rs:4:20
-   |
-LL |     std::any::Any::create();
-   |                    ^^^^^^ function or associated item not found in `Any`
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0599, E0782.
-For more information about an error, try `rustc --explain E0599`.
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/rust-2021/ice-return-unsized-can-impl-2.rs b/tests/ui/rust-2021/ice-return-unsized-can-impl-2.rs
new file mode 100644
index 00000000000..e57e9ce4844
--- /dev/null
+++ b/tests/ui/rust-2021/ice-return-unsized-can-impl-2.rs
@@ -0,0 +1,15 @@
+// Doesn't trigger ICE when returning unsized trait that can be impl
+// issue https://github.com/rust-lang/rust/issues/125512
+//@ edition:2021
+#![feature(dyn_compatible_for_dispatch)]
+trait B {
+    fn f(a: A) -> A;
+    //~^ ERROR: expected a type, found a trait
+    //~| ERROR: expected a type, found a trait
+}
+trait A {
+    fn concrete(b: B) -> B;
+    //~^ ERROR: expected a type, found a trait
+    //~| ERROR: expected a type, found a trait
+}
+fn main() {}
diff --git a/tests/ui/rust-2021/ice-return-unsized-can-impl-2.stderr b/tests/ui/rust-2021/ice-return-unsized-can-impl-2.stderr
new file mode 100644
index 00000000000..b8a9a5c8129
--- /dev/null
+++ b/tests/ui/rust-2021/ice-return-unsized-can-impl-2.stderr
@@ -0,0 +1,57 @@
+error[E0782]: expected a type, found a trait
+  --> $DIR/ice-return-unsized-can-impl-2.rs:11:20
+   |
+LL |     fn concrete(b: B) -> B;
+   |                    ^
+   |
+   = note: `B` it is dyn-incompatible, so it can't be `dyn`
+help: use a new generic type parameter, constrained by `B`
+   |
+LL |     fn concrete<T: B>(b: T) -> B;
+   |                ++++++    ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL |     fn concrete(b: impl B) -> B;
+   |                    ++++
+
+error[E0782]: expected a type, found a trait
+  --> $DIR/ice-return-unsized-can-impl-2.rs:11:26
+   |
+LL |     fn concrete(b: B) -> B;
+   |                          ^
+   |
+help: `B` is dyn-incompatible, use `impl B` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn concrete(b: B) -> impl B;
+   |                          ++++
+
+error[E0782]: expected a type, found a trait
+  --> $DIR/ice-return-unsized-can-impl-2.rs:6:13
+   |
+LL |     fn f(a: A) -> A;
+   |             ^
+   |
+   = note: `A` it is dyn-incompatible, so it can't be `dyn`
+help: use a new generic type parameter, constrained by `A`
+   |
+LL |     fn f<T: A>(a: T) -> A;
+   |         ++++++    ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL |     fn f(a: impl A) -> A;
+   |             ++++
+
+error[E0782]: expected a type, found a trait
+  --> $DIR/ice-return-unsized-can-impl-2.rs:6:19
+   |
+LL |     fn f(a: A) -> A;
+   |                   ^
+   |
+help: `A` is dyn-incompatible, use `impl A` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn f(a: A) -> impl A;
+   |                   ++++
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/rust-2021/ice-return-unsized-can-impl.rs b/tests/ui/rust-2021/ice-return-unsized-can-impl.rs
new file mode 100644
index 00000000000..055b11b4424
--- /dev/null
+++ b/tests/ui/rust-2021/ice-return-unsized-can-impl.rs
@@ -0,0 +1,16 @@
+// Doesn't trigger ICE when returning unsized trait that can be impl
+// issue https://github.com/rust-lang/rust/issues/120482
+//@ edition:2021
+#![feature(dyn_compatible_for_dispatch)]
+
+trait B {
+    fn bar(&self, x: &Self);
+}
+
+trait A {
+    fn g(new: B) -> B;
+    //~^ ERROR: expected a type, found a trait
+    //~| ERROR: expected a type, found a trait
+}
+
+fn main() {}
diff --git a/tests/ui/rust-2021/ice-return-unsized-can-impl.stderr b/tests/ui/rust-2021/ice-return-unsized-can-impl.stderr
new file mode 100644
index 00000000000..c0969570e92
--- /dev/null
+++ b/tests/ui/rust-2021/ice-return-unsized-can-impl.stderr
@@ -0,0 +1,30 @@
+error[E0782]: expected a type, found a trait
+  --> $DIR/ice-return-unsized-can-impl.rs:11:15
+   |
+LL |     fn g(new: B) -> B;
+   |               ^
+   |
+   = note: `B` it is dyn-incompatible, so it can't be `dyn`
+help: use a new generic type parameter, constrained by `B`
+   |
+LL |     fn g<T: B>(new: T) -> B;
+   |         ++++++      ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL |     fn g(new: impl B) -> B;
+   |               ++++
+
+error[E0782]: expected a type, found a trait
+  --> $DIR/ice-return-unsized-can-impl.rs:11:21
+   |
+LL |     fn g(new: B) -> B;
+   |                     ^
+   |
+help: `B` is dyn-incompatible, use `impl B` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn g(new: B) -> impl B;
+   |                     ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/rust-2021/ice-unsized-fn-params-2.rs b/tests/ui/rust-2021/ice-unsized-fn-params-2.rs
new file mode 100644
index 00000000000..2b4f7bd088f
--- /dev/null
+++ b/tests/ui/rust-2021/ice-unsized-fn-params-2.rs
@@ -0,0 +1,12 @@
+//@ edition:2021
+// Test that it doesn't trigger an ICE when using an unsized fn params.
+// https://github.com/rust-lang/rust/issues/120241
+#![feature(dyn_compatible_for_dispatch)]
+#![feature(unsized_fn_params)]
+
+fn guard(_s: Copy) -> bool {
+    //~^ ERROR: expected a type, found a trait
+    panic!()
+}
+
+fn main() {}
diff --git a/tests/ui/rust-2021/ice-unsized-fn-params-2.stderr b/tests/ui/rust-2021/ice-unsized-fn-params-2.stderr
new file mode 100644
index 00000000000..d35c8ab3e42
--- /dev/null
+++ b/tests/ui/rust-2021/ice-unsized-fn-params-2.stderr
@@ -0,0 +1,19 @@
+error[E0782]: expected a type, found a trait
+  --> $DIR/ice-unsized-fn-params-2.rs:7:14
+   |
+LL | fn guard(_s: Copy) -> bool {
+   |              ^^^^
+   |
+   = note: `Copy` it is dyn-incompatible, so it can't be `dyn`
+help: use a new generic type parameter, constrained by `Copy`
+   |
+LL | fn guard<T: Copy>(_s: T) -> bool {
+   |         +++++++++     ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL | fn guard(_s: impl Copy) -> bool {
+   |              ++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/rust-2021/ice-unsized-fn-params.rs b/tests/ui/rust-2021/ice-unsized-fn-params.rs
new file mode 100644
index 00000000000..6d8c1c3f152
--- /dev/null
+++ b/tests/ui/rust-2021/ice-unsized-fn-params.rs
@@ -0,0 +1,18 @@
+//@ edition:2021
+// Test that it doesn't trigger an ICE when using an unsized fn params.
+// https://github.com/rust-lang/rust/issues/120241
+#![feature(dyn_compatible_for_dispatch)]
+
+trait B {
+    fn f(a: A) -> A;
+    //~^ ERROR: expected a type, found a trait
+    //~| ERROR: expected a type, found a trait
+}
+
+trait A {
+    fn g(b: B) -> B;
+    //~^ ERROR: expected a type, found a trait
+    //~| ERROR: expected a type, found a trait
+}
+
+fn main() {}
diff --git a/tests/ui/rust-2021/ice-unsized-fn-params.stderr b/tests/ui/rust-2021/ice-unsized-fn-params.stderr
new file mode 100644
index 00000000000..d56e9981a28
--- /dev/null
+++ b/tests/ui/rust-2021/ice-unsized-fn-params.stderr
@@ -0,0 +1,57 @@
+error[E0782]: expected a type, found a trait
+  --> $DIR/ice-unsized-fn-params.rs:13:13
+   |
+LL |     fn g(b: B) -> B;
+   |             ^
+   |
+   = note: `B` it is dyn-incompatible, so it can't be `dyn`
+help: use a new generic type parameter, constrained by `B`
+   |
+LL |     fn g<T: B>(b: T) -> B;
+   |         ++++++    ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL |     fn g(b: impl B) -> B;
+   |             ++++
+
+error[E0782]: expected a type, found a trait
+  --> $DIR/ice-unsized-fn-params.rs:13:19
+   |
+LL |     fn g(b: B) -> B;
+   |                   ^
+   |
+help: `B` is dyn-incompatible, use `impl B` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn g(b: B) -> impl B;
+   |                   ++++
+
+error[E0782]: expected a type, found a trait
+  --> $DIR/ice-unsized-fn-params.rs:7:13
+   |
+LL |     fn f(a: A) -> A;
+   |             ^
+   |
+   = note: `A` it is dyn-incompatible, so it can't be `dyn`
+help: use a new generic type parameter, constrained by `A`
+   |
+LL |     fn f<T: A>(a: T) -> A;
+   |         ++++++    ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL |     fn f(a: impl A) -> A;
+   |             ++++
+
+error[E0782]: expected a type, found a trait
+  --> $DIR/ice-unsized-fn-params.rs:7:19
+   |
+LL |     fn f(a: A) -> A;
+   |                   ^
+   |
+help: `A` is dyn-incompatible, use `impl A` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn f(a: A) -> impl A;
+   |                   ++++
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs b/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs
index 37afab6b643..10b4781eb04 100644
--- a/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs
+++ b/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs
@@ -2,24 +2,21 @@
 #![allow(bare_trait_objects)]
 trait A: Sized {
     fn f(a: A) -> A;
-    //~^ ERROR trait objects must include the `dyn` keyword
-    //~| ERROR trait objects must include the `dyn` keyword
+    //~^ ERROR expected a type, found a trait
+    //~| ERROR expected a type, found a trait
     //~| ERROR associated item referring to unboxed trait object for its own trait
-    //~| ERROR the trait `A` cannot be made into an object
 }
 trait B {
     fn f(b: B) -> B;
-    //~^ ERROR trait objects must include the `dyn` keyword
-    //~| ERROR trait objects must include the `dyn` keyword
+    //~^ ERROR expected a type, found a trait
+    //~| ERROR expected a type, found a trait
     //~| ERROR associated item referring to unboxed trait object for its own trait
-    //~| ERROR the trait `B` cannot be made into an object
 }
 trait C {
     fn f(&self, c: C) -> C;
-    //~^ ERROR trait objects must include the `dyn` keyword
-    //~| ERROR trait objects must include the `dyn` keyword
+    //~^ ERROR expected a type, found a trait
+    //~| ERROR expected a type, found a trait
     //~| ERROR associated item referring to unboxed trait object for its own trait
-    //~| ERROR the trait `C` cannot be made into an object
 }
 
 fn main() {}
diff --git a/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021-without-dyn.stderr b/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021-without-dyn.stderr
index 53304382584..c0cfb18955c 100644
--- a/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021-without-dyn.stderr
+++ b/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021-without-dyn.stderr
@@ -11,22 +11,8 @@ help: you might have meant to use `Self` to refer to the implementing type
 LL |     fn f(a: Self) -> Self;
    |             ~~~~     ~~~~
 
-error[E0038]: the trait `A` cannot be made into an object
-  --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:4:13
-   |
-LL |     fn f(a: A) -> A;
-   |             ^ `A` 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/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:3:10
-   |
-LL | trait A: Sized {
-   |       -  ^^^^^ ...because it requires `Self: Sized`
-   |       |
-   |       this trait cannot be made into an object...
-
 error: associated item referring to unboxed trait object for its own trait
-  --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:11:13
+  --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:10:13
    |
 LL | trait B {
    |       - in this trait
@@ -38,30 +24,8 @@ help: you might have meant to use `Self` to refer to the implementing type
 LL |     fn f(b: Self) -> Self;
    |             ~~~~     ~~~~
 
-error[E0038]: the trait `B` cannot be made into an object
-  --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:11:13
-   |
-LL |     fn f(b: B) -> B;
-   |             ^ `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/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:11:8
-   |
-LL | trait B {
-   |       - this trait cannot be made into an object...
-LL |     fn f(b: B) -> B;
-   |        ^ ...because associated function `f` has no `self` parameter
-help: consider turning `f` into a method by giving it a `&self` argument
-   |
-LL |     fn f(&self, b: B) -> B;
-   |          ++++++
-help: alternatively, consider constraining `f` so it does not apply to trait objects
-   |
-LL |     fn f(b: B) -> B where Self: Sized;
-   |                     +++++++++++++++++
-
 error: associated item referring to unboxed trait object for its own trait
-  --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:18:20
+  --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:16:20
    |
 LL | trait C {
    |       - in this trait
@@ -73,23 +37,7 @@ help: you might have meant to use `Self` to refer to the implementing type
 LL |     fn f(&self, c: Self) -> Self;
    |                    ~~~~     ~~~~
 
-error[E0038]: the trait `C` cannot be made into an object
-  --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:18:20
-   |
-LL |     fn f(&self, c: C) -> C;
-   |          -----     ^ `C` cannot be made into an object
-   |          |
-   |          help: consider changing method `f`'s `self` parameter to be `&self` (notice the capitalization): `&Self`
-   |
-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/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:18:10
-   |
-LL | trait C {
-   |       - this trait cannot be made into an object...
-LL |     fn f(&self, c: C) -> C;
-   |          ^^^^^ ...because method `f`'s `self` parameter cannot be dispatched on
-
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:4:13
    |
 LL |     fn f(a: A) -> A;
@@ -105,7 +53,7 @@ help: you can also use an opaque type, but users won't be able to specify the ty
 LL |     fn f(a: impl A) -> A;
    |             ++++
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:4:19
    |
 LL |     fn f(a: A) -> A;
@@ -116,8 +64,8 @@ help: `A` is dyn-incompatible, use `impl A` to return an opaque type, as long as
 LL |     fn f(a: A) -> impl A;
    |                   ++++
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:11:13
+error[E0782]: expected a type, found a trait
+  --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:10:13
    |
 LL |     fn f(b: B) -> B;
    |             ^
@@ -132,8 +80,8 @@ help: you can also use an opaque type, but users won't be able to specify the ty
 LL |     fn f(b: impl B) -> B;
    |             ++++
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:11:19
+error[E0782]: expected a type, found a trait
+  --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:10:19
    |
 LL |     fn f(b: B) -> B;
    |                   ^
@@ -143,8 +91,8 @@ help: `B` is dyn-incompatible, use `impl B` to return an opaque type, as long as
 LL |     fn f(b: B) -> impl B;
    |                   ++++
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:18:20
+error[E0782]: expected a type, found a trait
+  --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:16:20
    |
 LL |     fn f(&self, c: C) -> C;
    |                    ^
@@ -159,8 +107,8 @@ help: you can also use an opaque type, but users won't be able to specify the ty
 LL |     fn f(&self, c: impl C) -> C;
    |                    ++++
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:18:26
+error[E0782]: expected a type, found a trait
+  --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:16:26
    |
 LL |     fn f(&self, c: C) -> C;
    |                          ^
@@ -170,7 +118,6 @@ help: `C` is dyn-incompatible, use `impl C` to return an opaque type, as long as
 LL |     fn f(&self, c: C) -> impl C;
    |                          ++++
 
-error: aborting due to 12 previous errors
+error: aborting due to 9 previous errors
 
-Some errors have detailed explanations: E0038, E0782.
-For more information about an error, try `rustc --explain E0038`.
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/suggestions/issue-116434-2021.rs b/tests/ui/suggestions/issue-116434-2021.rs
index 6feba3dc6c1..77cdfb8b614 100644
--- a/tests/ui/suggestions/issue-116434-2021.rs
+++ b/tests/ui/suggestions/issue-116434-2021.rs
@@ -3,7 +3,8 @@
 trait Foo {
     type Clone;
     fn foo() -> Clone;
-    //~^ ERROR the trait `Clone` cannot be made into an object [E0038]
+    //~^ ERROR expected a type, found a trait
+    //~| HELP `Clone` is dyn-incompatible, use `impl Clone` to return an opaque type, as long as you return a single underlying type
     //~| HELP there is an associated type with the same name
 }
 
@@ -12,7 +13,8 @@ trait DbHandle: Sized {}
 trait DbInterface {
     type DbHandle;
     fn handle() -> DbHandle;
-    //~^ ERROR the trait `DbHandle` cannot be made into an object [E0038]
+    //~^ ERROR expected a type, found a trait
+    //~| HELP `DbHandle` is dyn-incompatible, use `impl DbHandle` to return an opaque type, as long as you return a single underlying type
     //~| HELP there is an associated type with the same name
 }
 
diff --git a/tests/ui/suggestions/issue-116434-2021.stderr b/tests/ui/suggestions/issue-116434-2021.stderr
index 7f8cc147210..3853f03f1db 100644
--- a/tests/ui/suggestions/issue-116434-2021.stderr
+++ b/tests/ui/suggestions/issue-116434-2021.stderr
@@ -1,29 +1,28 @@
-error[E0038]: the trait `Clone` cannot be made into an object
+error[E0782]: expected a type, found a trait
   --> $DIR/issue-116434-2021.rs:5:17
    |
 LL |     fn foo() -> Clone;
-   |                 ^^^^^ `Clone` cannot be made into an object
+   |                 ^^^^^
    |
-   = note: the trait cannot be made into an object because it requires `Self: Sized`
-   = 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>
+help: `Clone` is dyn-incompatible, use `impl Clone` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn foo() -> impl Clone;
+   |                 ++++
 help: there is an associated type with the same name
    |
 LL |     fn foo() -> Self::Clone;
    |                 ++++++
 
-error[E0038]: the trait `DbHandle` cannot be made into an object
-  --> $DIR/issue-116434-2021.rs:14:20
+error[E0782]: expected a type, found a trait
+  --> $DIR/issue-116434-2021.rs:15:20
    |
 LL |     fn handle() -> DbHandle;
-   |                    ^^^^^^^^ `DbHandle` 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-116434-2021.rs:10:17
+help: `DbHandle` is dyn-incompatible, use `impl DbHandle` to return an opaque type, as long as you return a single underlying type
    |
-LL | trait DbHandle: Sized {}
-   |       --------  ^^^^^ ...because it requires `Self: Sized`
-   |       |
-   |       this trait cannot be made into an object...
+LL |     fn handle() -> impl DbHandle;
+   |                    ++++
 help: there is an associated type with the same name
    |
 LL |     fn handle() -> Self::DbHandle;
@@ -31,4 +30,4 @@ LL |     fn handle() -> Self::DbHandle;
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0038`.
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/suggestions/suggest-blanket-impl-local-trait.rs b/tests/ui/suggestions/suggest-blanket-impl-local-trait.rs
index 76300c6a3f4..dd7e203abd7 100644
--- a/tests/ui/suggestions/suggest-blanket-impl-local-trait.rs
+++ b/tests/ui/suggestions/suggest-blanket-impl-local-trait.rs
@@ -11,48 +11,48 @@ trait LocalTraitTwo { }
 trait GenericTrait<T> {}
 
 impl LocalTraitTwo for LocalTraitOne {}
-//~^ ERROR trait objects must include the `dyn` keyword
-//~| HELP add `dyn` keyword before this trait
+//~^ ERROR expected a type, found a trait
+//~| HELP you can add the `dyn` keyword if you want a trait object
 //~| HELP alternatively use a blanket implementation to implement `LocalTraitTwo` for all types that also implement `LocalTraitOne`
 
 impl fmt::Display for LocalTraitOne {
-//~^ ERROR trait objects must include the `dyn` keyword
-//~| HELP add `dyn` keyword before this trait
+//~^ ERROR expected a type, found a trait
+//~| HELP you can add the `dyn` keyword if you want a trait object
     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
         todo!();
     }
 }
 
 impl fmt::Display for LocalTraitTwo + Send {
-//~^ ERROR trait objects must include the `dyn` keyword
-//~| HELP add `dyn` keyword before this trait
+//~^ ERROR expected a type, found a trait
+//~| HELP you can add the `dyn` keyword if you want a trait object
     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
         todo!();
     }
 }
 
 impl LocalTraitOne for fmt::Display {}
-//~^ ERROR trait objects must include the `dyn` keyword
-//~| HELP add `dyn` keyword before this trait
+//~^ ERROR expected a type, found a trait
+//~| HELP you can add the `dyn` keyword if you want a trait object
 //~| HELP alternatively use a blanket implementation to implement `LocalTraitOne` for all types that also implement `fmt::Display`
 
 
 impl LocalTraitOne for fmt::Display + Send {}
-//~^ ERROR trait objects must include the `dyn` keyword
-//~| HELP add `dyn` keyword before this trait
+//~^ ERROR expected a type, found a trait
+//~| HELP you can add the `dyn` keyword if you want a trait object
 //~| HELP alternatively use a blanket implementation to implement `LocalTraitOne` for all types that also implement `fmt::Display + Send`
 
 
 impl<E> GenericTrait<E> for LocalTraitOne {}
-//~^ ERROR trait objects must include the `dyn` keyword
-//~| HELP add `dyn` keyword before this trait
+//~^ ERROR expected a type, found a trait
+//~| HELP you can add the `dyn` keyword if you want a trait object
 //~| HELP alternatively use a blanket implementation to implement `GenericTrait<E>` for all types that also implement `LocalTraitOne`
 
 trait GenericTraitTwo<T> {}
 
 impl<T, E> GenericTraitTwo<E> for GenericTrait<T> {}
-//~^ ERROR trait objects must include the `dyn` keyword
-//~| HELP add `dyn` keyword before this trait
+//~^ ERROR expected a type, found a trait
+//~| HELP you can add the `dyn` keyword if you want a trait object
 //~| HELP alternatively use a blanket implementation to implement `GenericTraitTwo<E>` for all types that also implement `GenericTrait<T>`
 
 fn main() {}
diff --git a/tests/ui/suggestions/suggest-blanket-impl-local-trait.stderr b/tests/ui/suggestions/suggest-blanket-impl-local-trait.stderr
index 769f3bd64f3..102438e1ec5 100644
--- a/tests/ui/suggestions/suggest-blanket-impl-local-trait.stderr
+++ b/tests/ui/suggestions/suggest-blanket-impl-local-trait.stderr
@@ -1,10 +1,10 @@
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/suggest-blanket-impl-local-trait.rs:34:24
    |
 LL | impl LocalTraitOne for fmt::Display {}
    |                        ^^^^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | impl LocalTraitOne for dyn fmt::Display {}
    |                        +++
@@ -13,13 +13,13 @@ help: alternatively use a blanket implementation to implement `LocalTraitOne` fo
 LL | impl<T: fmt::Display> LocalTraitOne for T {}
    |     +++++++++++++++++                   ~
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/suggest-blanket-impl-local-trait.rs:40:24
    |
 LL | impl LocalTraitOne for fmt::Display + Send {}
    |                        ^^^^^^^^^^^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | impl LocalTraitOne for dyn fmt::Display + Send {}
    |                        +++
@@ -28,13 +28,13 @@ help: alternatively use a blanket implementation to implement `LocalTraitOne` fo
 LL | impl<T: fmt::Display + Send> LocalTraitOne for T {}
    |     ++++++++++++++++++++++++                   ~
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/suggest-blanket-impl-local-trait.rs:13:24
    |
 LL | impl LocalTraitTwo for LocalTraitOne {}
    |                        ^^^^^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | impl LocalTraitTwo for dyn LocalTraitOne {}
    |                        +++
@@ -43,13 +43,13 @@ help: alternatively use a blanket implementation to implement `LocalTraitTwo` fo
 LL | impl<T: LocalTraitOne> LocalTraitTwo for T {}
    |     ++++++++++++++++++                   ~
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/suggest-blanket-impl-local-trait.rs:46:29
    |
 LL | impl<E> GenericTrait<E> for LocalTraitOne {}
    |                             ^^^^^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | impl<E> GenericTrait<E> for dyn LocalTraitOne {}
    |                             +++
@@ -58,35 +58,35 @@ help: alternatively use a blanket implementation to implement `GenericTrait<E>`
 LL | impl<E, T: LocalTraitOne> GenericTrait<E> for T {}
    |       ++++++++++++++++++                      ~
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/suggest-blanket-impl-local-trait.rs:18:23
    |
 LL | impl fmt::Display for LocalTraitOne {
    |                       ^^^^^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | impl fmt::Display for dyn LocalTraitOne {
    |                       +++
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/suggest-blanket-impl-local-trait.rs:26:23
    |
 LL | impl fmt::Display for LocalTraitTwo + Send {
    |                       ^^^^^^^^^^^^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | impl fmt::Display for dyn LocalTraitTwo + Send {
    |                       +++
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/suggest-blanket-impl-local-trait.rs:53:35
    |
 LL | impl<T, E> GenericTraitTwo<E> for GenericTrait<T> {}
    |                                   ^^^^^^^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | impl<T, E> GenericTraitTwo<E> for dyn GenericTrait<T> {}
    |                                   +++
diff --git a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs
index a5ab8be7f45..fe36d093430 100644
--- a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs
+++ b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs
@@ -14,14 +14,14 @@ pub union Union<T> {
 
 impl<'a, T> Struct<T> for Trait<'a, T> {}
 //~^ ERROR expected trait, found struct `Struct`
-//~| ERROR trait objects must include the `dyn` keyword
+//~| ERROR expected a type, found a trait
 
 impl<'a, T> Enum<T> for Trait<'a, T> {}
 //~^ ERROR expected trait, found enum `Enum`
-//~| ERROR trait objects must include the `dyn` keyword
+//~| ERROR expected a type, found a trait
 
 impl<'a, T> Union<T> for Trait<'a, T> {}
 //~^ ERROR expected trait, found union `Union`
-//~| ERROR trait objects must include the `dyn` keyword
+//~| ERROR expected a type, found a trait
 
 fn main() {}
diff --git a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr
index 2893370570d..0bd601e2170 100644
--- a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr
+++ b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr
@@ -58,35 +58,35 @@ LL | pub union Union<T> {
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
    = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:15:27
    |
 LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
    |                           ^^^^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
    |                           +++
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:19:25
    |
 LL | impl<'a, T> Enum<T> for Trait<'a, T> {}
    |                         ^^^^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | impl<'a, T> Enum<T> for dyn Trait<'a, T> {}
    |                         +++
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:23:26
    |
 LL | impl<'a, T> Union<T> for Trait<'a, T> {}
    |                          ^^^^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | impl<'a, T> Union<T> for dyn Trait<'a, T> {}
    |                          +++
diff --git a/tests/ui/traits/bound/not-on-bare-trait-2021.rs b/tests/ui/traits/bound/not-on-bare-trait-2021.rs
index 07b866cb4a6..93d2f04b54e 100644
--- a/tests/ui/traits/bound/not-on-bare-trait-2021.rs
+++ b/tests/ui/traits/bound/not-on-bare-trait-2021.rs
@@ -6,13 +6,11 @@ trait Foo {
 // This should emit the less confusing error, not the more confusing one.
 
 fn foo(_x: Foo + Send) {
-    //~^ ERROR trait objects must include the `dyn` keyword
-    //~| ERROR size for values of type
+    //~^ ERROR expected a type, found a trait
 }
 fn bar(x: Foo) -> Foo {
-    //~^ ERROR trait objects must include the `dyn` keyword
-    //~| ERROR trait objects must include the `dyn` keyword
-    //~| ERROR size for values of type
+    //~^ ERROR expected a type, found a trait
+    //~| ERROR expected a type, found a trait
     x
 }
 
diff --git a/tests/ui/traits/bound/not-on-bare-trait-2021.stderr b/tests/ui/traits/bound/not-on-bare-trait-2021.stderr
index e05ae8e5267..e50186aff7e 100644
--- a/tests/ui/traits/bound/not-on-bare-trait-2021.stderr
+++ b/tests/ui/traits/bound/not-on-bare-trait-2021.stderr
@@ -1,38 +1,4 @@
-error[E0277]: the size for values of type `(dyn Foo + Send + 'static)` cannot be known at compilation time
-  --> $DIR/not-on-bare-trait-2021.rs:8:12
-   |
-LL | fn foo(_x: Foo + Send) {
-   |            ^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `(dyn Foo + Send + 'static)`
-   = help: unsized fn params are gated as an unstable feature
-help: you can use `impl Trait` as the argument type
-   |
-LL | fn foo(_x: impl Foo + Send) {
-   |            ++++
-help: function arguments must have a statically known size, borrowed types always have a known size
-   |
-LL | fn foo(_x: &(dyn Foo + Send)) {
-   |            +++++           +
-
-error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time
-  --> $DIR/not-on-bare-trait-2021.rs:12:11
-   |
-LL | fn bar(x: Foo) -> Foo {
-   |           ^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)`
-   = help: unsized fn params are gated as an unstable feature
-help: you can use `impl Trait` as the argument type
-   |
-LL | fn bar(x: impl Foo) -> Foo {
-   |           ++++
-help: function arguments must have a statically known size, borrowed types always have a known size
-   |
-LL | fn bar(x: &dyn Foo) -> Foo {
-   |           ++++
-
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/not-on-bare-trait-2021.rs:8:12
    |
 LL | fn foo(_x: Foo + Send) {
@@ -51,8 +17,8 @@ help: alternatively, use a trait object to accept any type that implements `Foo
 LL | fn foo(_x: &(dyn Foo + Send)) {
    |            +++++           +
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/not-on-bare-trait-2021.rs:12:11
+error[E0782]: expected a type, found a trait
+  --> $DIR/not-on-bare-trait-2021.rs:11:11
    |
 LL | fn bar(x: Foo) -> Foo {
    |           ^^^
@@ -70,8 +36,8 @@ help: alternatively, use a trait object to accept any type that implements `Foo`
 LL | fn bar(x: &dyn Foo) -> Foo {
    |           ++++
 
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/not-on-bare-trait-2021.rs:12:19
+error[E0782]: expected a type, found a trait
+  --> $DIR/not-on-bare-trait-2021.rs:11:19
    |
 LL | fn bar(x: Foo) -> Foo {
    |                   ^^^
@@ -85,7 +51,6 @@ help: alternatively, you can return an owned trait object
 LL | fn bar(x: Foo) -> Box<dyn Foo> {
    |                   +++++++    +
 
-error: aborting due to 5 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0277, E0782.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/traits/issue-106072.rs b/tests/ui/traits/issue-106072.rs
index 8adbac46a5b..696bd765ebc 100644
--- a/tests/ui/traits/issue-106072.rs
+++ b/tests/ui/traits/issue-106072.rs
@@ -1,6 +1,4 @@
-#[derive(Clone)] //~  trait objects must include the `dyn` keyword
-//~^ ERROR: the size for values of type `(dyn Foo + 'static)` cannot be known
-//~| ERROR: return type cannot have an unboxed trait object
+#[derive(Clone)] //~  expected a type, found a trait
 struct Foo;
 trait Foo {} //~ the name `Foo` is defined multiple times
 fn main() {}
diff --git a/tests/ui/traits/issue-106072.stderr b/tests/ui/traits/issue-106072.stderr
index 6476c8b3237..4a48e4e898d 100644
--- a/tests/ui/traits/issue-106072.stderr
+++ b/tests/ui/traits/issue-106072.stderr
@@ -1,5 +1,5 @@
 error[E0428]: the name `Foo` is defined multiple times
-  --> $DIR/issue-106072.rs:5:1
+  --> $DIR/issue-106072.rs:3:1
    |
 LL | struct Foo;
    | ----------- previous definition of the type `Foo` here
@@ -8,26 +8,7 @@ LL | trait Foo {}
    |
    = note: `Foo` must be defined only once in the type namespace of this module
 
-error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time
-  --> $DIR/issue-106072.rs:1:10
-   |
-LL | #[derive(Clone)]
-   |          ^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)`
-note: required by a bound in `Clone`
-  --> $SRC_DIR/core/src/clone.rs:LL:COL
-   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error[E0746]: return type cannot have an unboxed trait object
-  --> $DIR/issue-106072.rs:1:10
-   |
-LL | #[derive(Clone)]
-   |          ^^^^^ doesn't have a size known at compile-time
-   |
-   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/issue-106072.rs:1:10
    |
 LL | #[derive(Clone)]
@@ -35,7 +16,7 @@ LL | #[derive(Clone)]
    |
    = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0277, E0428, E0746, E0782.
-For more information about an error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0428, E0782.
+For more information about an error, try `rustc --explain E0428`.
diff --git a/tests/ui/traits/missing-for-type-in-impl.e2021.stderr b/tests/ui/traits/missing-for-type-in-impl.e2021.stderr
index b5a607a54cb..a49c5d9d45b 100644
--- a/tests/ui/traits/missing-for-type-in-impl.e2021.stderr
+++ b/tests/ui/traits/missing-for-type-in-impl.e2021.stderr
@@ -10,13 +10,13 @@ help: this trait has no implementations, consider adding one
 LL | trait Foo<T> {
    | ^^^^^^^^^^^^
 
-error[E0782]: trait objects must include the `dyn` keyword
+error[E0782]: expected a type, found a trait
   --> $DIR/missing-for-type-in-impl.rs:8:6
    |
 LL | impl Foo<i64> {
    |      ^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: you can add the `dyn` keyword if you want a trait object
    |
 LL | impl dyn Foo<i64> {
    |      +++
diff --git a/tests/ui/traits/missing-for-type-in-impl.rs b/tests/ui/traits/missing-for-type-in-impl.rs
index 7d4ad479e77..e5dd3651609 100644
--- a/tests/ui/traits/missing-for-type-in-impl.rs
+++ b/tests/ui/traits/missing-for-type-in-impl.rs
@@ -6,7 +6,7 @@ trait Foo<T> {
 
 /* note the "missing" for ... (in this case for i64, in order for this to compile) */
 impl Foo<i64> {
-//[e2021]~^ ERROR trait objects must include the `dyn` keyword
+//[e2021]~^ ERROR expected a type, found a trait
 //[e2015]~^^ WARNING trait objects without an explicit `dyn` are deprecated
 //[e2015]~| WARNING trait objects without an explicit `dyn` are deprecated
 //[e2015]~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!