From 75692056e1ab8ca8a5e0c8e2def4cabcf2f3b445 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Fri, 5 Jul 2024 20:58:33 +0000
Subject: [PATCH] Use verbose suggestion for changing arg type

---
 .../src/check/compare_impl_item.rs            |  6 ++--
 .../defaults-specialization.stderr            | 18 +++++-----
 tests/ui/compare-method/bad-self-type.stderr  | 18 +++++-----
 tests/ui/compare-method/issue-90444.stderr    | 18 +++++-----
 .../reordered-type-param.stderr               | 10 +++---
 ...-gate-unboxed-closures-manual-impls.stderr | 18 +++++-----
 .../impl-generic-mismatch-ab.stderr           | 10 +++---
 .../in-assoc-type-unconstrained.stderr        |  9 ++---
 .../method-signature-matches.lt.stderr        | 10 +++---
 .../method-signature-matches.mismatch.stderr  |  9 ++---
 ...od-signature-matches.mismatch_async.stderr |  9 ++---
 .../opaque-and-lifetime-mismatch.stderr       |  9 ++---
 .../in-trait/specialization-broken.stderr     |  9 ++---
 ...s-impl-trait-declaration-too-subtle.stderr | 18 +++++-----
 tests/ui/impl-trait/trait_type.stderr         |  9 ++---
 tests/ui/impl-trait/where-allowed.stderr      |  9 ++---
 tests/ui/issues/issue-20225.stderr            | 27 +++++++-------
 tests/ui/issues/issue-21332.stderr            |  9 ++---
 tests/ui/mismatched_types/E0053.stderr        | 18 +++++-----
 tests/ui/mismatched_types/issue-112036.stderr |  9 ++---
 tests/ui/mismatched_types/issue-13033.stderr  |  9 ++---
 .../trait-impl-fn-incompatibility.stderr      | 18 +++++-----
 tests/ui/traits/issue-35869.stderr            | 36 ++++++++++---------
 .../traits/wrong-mul-method-signature.stderr  | 27 +++++++-------
 .../unnameable_type.stderr                    |  9 ++---
 .../typeck/mismatched-map-under-self.stderr   |  9 ++---
 tests/ui/ufcs/ufcs-explicit-self-bad.stderr   |  9 ++---
 27 files changed, 206 insertions(+), 163 deletions(-)

diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index b5b68471b9d16..0dbe64c3ea7f7 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -981,7 +981,7 @@ fn report_trait_method_mismatch<'tcx>(
                 .next()
                 .unwrap_or(impl_err_span);
 
-            diag.span_suggestion(
+            diag.span_suggestion_verbose(
                 span,
                 "change the self-receiver type to match the trait",
                 sugg,
@@ -1005,12 +1005,12 @@ fn report_trait_method_mismatch<'tcx>(
                         }
                         hir::FnRetTy::Return(hir_ty) => {
                             let sugg = trait_sig.output();
-                            diag.span_suggestion(hir_ty.span, msg, sugg, ap);
+                            diag.span_suggestion_verbose(hir_ty.span, msg, sugg, ap);
                         }
                     };
                 };
             } else if let Some(trait_ty) = trait_sig.inputs().get(*i) {
-                diag.span_suggestion(
+                diag.span_suggestion_verbose(
                     impl_err_span,
                     "change the parameter type to match the trait",
                     trait_ty,
diff --git a/tests/ui/associated-types/defaults-specialization.stderr b/tests/ui/associated-types/defaults-specialization.stderr
index 7ef433d859fa4..b4ed99f36f44a 100644
--- a/tests/ui/associated-types/defaults-specialization.stderr
+++ b/tests/ui/associated-types/defaults-specialization.stderr
@@ -12,10 +12,7 @@ error[E0053]: method `make` has an incompatible type for trait
   --> $DIR/defaults-specialization.rs:19:18
    |
 LL |     fn make() -> u8 { 0 }
-   |                  ^^
-   |                  |
-   |                  expected associated type, found `u8`
-   |                  help: change the output type to match the trait: `<A<T> as Tr>::Ty`
+   |                  ^^ expected associated type, found `u8`
    |
 note: type in trait
   --> $DIR/defaults-specialization.rs:9:18
@@ -24,6 +21,10 @@ LL |     fn make() -> Self::Ty {
    |                  ^^^^^^^^
    = note: expected signature `fn() -> <A<T> as Tr>::Ty`
               found signature `fn() -> u8`
+help: change the output type to match the trait
+   |
+LL |     fn make() -> <A<T> as Tr>::Ty { 0 }
+   |                  ~~~~~~~~~~~~~~~~
 
 error[E0053]: method `make` has an incompatible type for trait
   --> $DIR/defaults-specialization.rs:35:18
@@ -32,10 +33,7 @@ LL |     default type Ty = bool;
    |     ----------------------- associated type is `default` and may be overridden
 LL |
 LL |     fn make() -> bool { true }
-   |                  ^^^^
-   |                  |
-   |                  expected associated type, found `bool`
-   |                  help: change the output type to match the trait: `<B<T> as Tr>::Ty`
+   |                  ^^^^ expected associated type, found `bool`
    |
 note: type in trait
   --> $DIR/defaults-specialization.rs:9:18
@@ -44,6 +42,10 @@ LL |     fn make() -> Self::Ty {
    |                  ^^^^^^^^
    = note: expected signature `fn() -> <B<T> as Tr>::Ty`
               found signature `fn() -> bool`
+help: change the output type to match the trait
+   |
+LL |     fn make() -> <B<T> as Tr>::Ty { true }
+   |                  ~~~~~~~~~~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/defaults-specialization.rs:10:9
diff --git a/tests/ui/compare-method/bad-self-type.stderr b/tests/ui/compare-method/bad-self-type.stderr
index a87b713c2b4bd..29ebbc5dffb11 100644
--- a/tests/ui/compare-method/bad-self-type.stderr
+++ b/tests/ui/compare-method/bad-self-type.stderr
@@ -2,22 +2,20 @@ error[E0053]: method `poll` has an incompatible type for trait
   --> $DIR/bad-self-type.rs:10:13
    |
 LL |     fn poll(self, _: &mut Context<'_>) -> Poll<()> {
-   |             ^^^^
-   |             |
-   |             expected `Pin<&mut MyFuture>`, found `MyFuture`
-   |             help: change the self-receiver type to match the trait: `self: Pin<&mut MyFuture>`
+   |             ^^^^ expected `Pin<&mut MyFuture>`, found `MyFuture`
    |
    = note: expected signature `fn(Pin<&mut MyFuture>, &mut Context<'_>) -> Poll<_>`
               found signature `fn(MyFuture, &mut Context<'_>) -> Poll<_>`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn poll(self: Pin<&mut MyFuture>, _: &mut Context<'_>) -> Poll<()> {
+   |             ~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0053]: method `foo` has an incompatible type for trait
   --> $DIR/bad-self-type.rs:22:18
    |
 LL |     fn foo(self: Box<Self>) {}
-   |            ------^^^^^^^^^
-   |            |     |
-   |            |     expected `MyFuture`, found `Box<MyFuture>`
-   |            help: change the self-receiver type to match the trait: `self`
+   |                  ^^^^^^^^^ expected `MyFuture`, found `Box<MyFuture>`
    |
 note: type in trait
   --> $DIR/bad-self-type.rs:17:12
@@ -26,6 +24,10 @@ LL |     fn foo(self);
    |            ^^^^
    = note: expected signature `fn(MyFuture)`
               found signature `fn(Box<MyFuture>)`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn foo(self) {}
+   |            ~~~~
 
 error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/bad-self-type.rs:24:17
diff --git a/tests/ui/compare-method/issue-90444.stderr b/tests/ui/compare-method/issue-90444.stderr
index 52e23d03b148b..f05c9939c0096 100644
--- a/tests/ui/compare-method/issue-90444.stderr
+++ b/tests/ui/compare-method/issue-90444.stderr
@@ -2,25 +2,27 @@ error[E0053]: method `from` has an incompatible type for trait
   --> $DIR/issue-90444.rs:3:16
    |
 LL |     fn from(_: fn((), (), &mut ())) -> Self {
-   |                ^^^^^^^^^^^^^^^^^^^
-   |                |
-   |                types differ in mutability
-   |                help: change the parameter type to match the trait: `for<'a> fn((), (), &'a ())`
+   |                ^^^^^^^^^^^^^^^^^^^ types differ in mutability
    |
    = note: expected signature `fn(for<'a> fn((), (), &'a ())) -> A`
               found signature `fn(for<'a> fn((), (), &'a mut ())) -> A`
+help: change the parameter type to match the trait
+   |
+LL |     fn from(_: for<'a> fn((), (), &'a ())) -> Self {
+   |                ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0053]: method `from` has an incompatible type for trait
   --> $DIR/issue-90444.rs:11:16
    |
 LL |     fn from(_: fn((), (), u64)) -> Self {
-   |                ^^^^^^^^^^^^^^^
-   |                |
-   |                expected `u32`, found `u64`
-   |                help: change the parameter type to match the trait: `fn((), (), u32)`
+   |                ^^^^^^^^^^^^^^^ expected `u32`, found `u64`
    |
    = note: expected signature `fn(fn((), (), u32)) -> B`
               found signature `fn(fn((), (), u64)) -> B`
+help: change the parameter type to match the trait
+   |
+LL |     fn from(_: fn((), (), u32)) -> Self {
+   |                ~~~~~~~~~~~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/compare-method/reordered-type-param.stderr b/tests/ui/compare-method/reordered-type-param.stderr
index 8a439acee13de..1e8266e213d7f 100644
--- a/tests/ui/compare-method/reordered-type-param.stderr
+++ b/tests/ui/compare-method/reordered-type-param.stderr
@@ -2,10 +2,8 @@ error[E0053]: method `b` has an incompatible type for trait
   --> $DIR/reordered-type-param.rs:16:30
    |
 LL |   fn b<F:Clone,G>(&self, _x: G) -> G { panic!() }
-   |        -       -             ^
-   |        |       |             |
-   |        |       |             expected type parameter `F`, found type parameter `G`
-   |        |       |             help: change the parameter type to match the trait: `F`
+   |        -       -             ^ expected type parameter `F`, found type parameter `G`
+   |        |       |
    |        |       found type parameter
    |        expected type parameter
    |
@@ -18,6 +16,10 @@ LL |   fn b<C:Clone,D>(&self, x: C) -> C;
               found signature `fn(&E, G) -> G`
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+help: change the parameter type to match the trait
+   |
+LL |   fn b<F:Clone,G>(&self, _x: F) -> G { panic!() }
+   |                              ~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
index 1b9febd431d6f..06a606b09dc97 100644
--- a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
+++ b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
@@ -89,13 +89,14 @@ error[E0053]: method `call` has an incompatible type for trait
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:13:32
    |
 LL |     extern "rust-call" fn call(self, args: ()) -> () {}
-   |                                ^^^^
-   |                                |
-   |                                expected `&Foo`, found `Foo`
-   |                                help: change the self-receiver type to match the trait: `&self`
+   |                                ^^^^ expected `&Foo`, found `Foo`
    |
    = note: expected signature `extern "rust-call" fn(&Foo, ()) -> _`
               found signature `extern "rust-call" fn(Foo, ())`
+help: change the self-receiver type to match the trait
+   |
+LL |     extern "rust-call" fn call(&self, args: ()) -> () {}
+   |                                ~~~~~
 
 error[E0183]: manual implementations of `FnOnce` are experimental
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6
@@ -158,13 +159,14 @@ error[E0053]: method `call_mut` has an incompatible type for trait
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:30:36
    |
 LL |     extern "rust-call" fn call_mut(&self, args: ()) -> () {}
-   |                                    ^^^^^
-   |                                    |
-   |                                    types differ in mutability
-   |                                    help: change the self-receiver type to match the trait: `&mut self`
+   |                                    ^^^^^ types differ in mutability
    |
    = note: expected signature `extern "rust-call" fn(&mut Bar, ()) -> _`
               found signature `extern "rust-call" fn(&Bar, ())`
+help: change the self-receiver type to match the trait
+   |
+LL |     extern "rust-call" fn call_mut(&mut self, args: ()) -> () {}
+   |                                    ~~~~~~~~~
 
 error[E0046]: not all trait items implemented, missing: `Output`
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:35:1
diff --git a/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr b/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr
index 7046e729e1834..90c31c9e3fc19 100644
--- a/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr
+++ b/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr
@@ -2,10 +2,8 @@ error[E0053]: method `foo` has an incompatible type for trait
   --> $DIR/impl-generic-mismatch-ab.rs:8:32
    |
 LL |     fn foo<B: Debug>(&self, a: &impl Debug, b: &B) { }
-   |            -                   ^^^^^^^^^^^
-   |            |                   |
-   |            |                   expected type parameter `B`, found type parameter `impl Debug`
-   |            |                   help: change the parameter type to match the trait: `&B`
+   |            -                   ^^^^^^^^^^^ expected type parameter `B`, found type parameter `impl Debug`
+   |            |
    |            expected type parameter
    |
 note: type in trait
@@ -17,6 +15,10 @@ LL |     fn foo<A: Debug>(&self, a: &A, b: &impl Debug);
               found signature `fn(&(), &impl Debug, &B)`
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+help: change the parameter type to match the trait
+   |
+LL |     fn foo<B: Debug>(&self, a: &B, b: &B) { }
+   |                                ~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
index 8e61a65abe4be..e32c59a75c699 100644
--- a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
+++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
@@ -27,10 +27,7 @@ LL |         type Ty = impl Sized;
    |                   ---------- the expected opaque type
 LL |
 LL |         fn method() -> () {}
-   |                        ^^
-   |                        |
-   |                        expected opaque type, found `()`
-   |                        help: change the output type to match the trait: `<() as compare_method::Trait>::Ty`
+   |                        ^^ expected opaque type, found `()`
    |
 note: type in trait
   --> $DIR/in-assoc-type-unconstrained.rs:17:24
@@ -44,6 +41,10 @@ note: this item must have the opaque type in its signature in order to be able t
    |
 LL |         fn method() -> () {}
    |            ^^^^^^
+help: change the output type to match the trait
+   |
+LL |         fn method() -> <() as compare_method::Trait>::Ty {}
+   |                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unconstrained opaque type
   --> $DIR/in-assoc-type-unconstrained.rs:20:19
diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr
index 2231205327cb0..6f6b787b6fe1b 100644
--- a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr
+++ b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr
@@ -2,10 +2,8 @@ error[E0053]: method `early` has an incompatible type for trait
   --> $DIR/method-signature-matches.rs:55:27
    |
 LL |     fn early<'late, T>(_: &'late ()) {}
-   |                     -     ^^^^^^^^^
-   |                     |     |
-   |                     |     expected type parameter `T`, found `()`
-   |                     |     help: change the parameter type to match the trait: `&T`
+   |                     -     ^^^^^^^^^ expected type parameter `T`, found `()`
+   |                     |
    |                     expected this type parameter
    |
 note: type in trait
@@ -15,6 +13,10 @@ LL |     fn early<'early, T>(x: &'early T) -> impl Sized;
    |                            ^^^^^^^^^
    = note: expected signature `fn(&T)`
               found signature `fn(&'late ())`
+help: change the parameter type to match the trait
+   |
+LL |     fn early<'late, T>(_: &T) {}
+   |                           ~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr
index ec2a126865d5c..9e18517e48c55 100644
--- a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr
+++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `owo` has an incompatible type for trait
   --> $DIR/method-signature-matches.rs:11:15
    |
 LL |     fn owo(_: u8) {}
-   |               ^^
-   |               |
-   |               expected `()`, found `u8`
-   |               help: change the parameter type to match the trait: `()`
+   |               ^^ expected `()`, found `u8`
    |
 note: type in trait
   --> $DIR/method-signature-matches.rs:6:15
@@ -14,6 +11,10 @@ LL |     fn owo(x: ()) -> impl Sized;
    |               ^^
    = note: expected signature `fn(())`
               found signature `fn(u8)`
+help: change the parameter type to match the trait
+   |
+LL |     fn owo(_: ()) {}
+   |               ~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr
index 4d3e64e8050f9..c01d7322d117e 100644
--- a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr
+++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `owo` has an incompatible type for trait
   --> $DIR/method-signature-matches.rs:22:21
    |
 LL |     async fn owo(_: u8) {}
-   |                     ^^
-   |                     |
-   |                     expected `()`, found `u8`
-   |                     help: change the parameter type to match the trait: `()`
+   |                     ^^ expected `()`, found `u8`
    |
 note: type in trait
   --> $DIR/method-signature-matches.rs:17:21
@@ -14,6 +11,10 @@ LL |     async fn owo(x: ()) {}
    |                     ^^
    = note: expected signature `fn(()) -> _`
               found signature `fn(u8) -> _`
+help: change the parameter type to match the trait
+   |
+LL |     async fn owo(_: ()) {}
+   |                     ~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr
index d7fc40fa3426f..1f8a0d5edd781 100644
--- a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr
+++ b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr
@@ -75,10 +75,7 @@ error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/opaque-and-lifetime-mismatch.rs:10:17
    |
 LL |     fn bar() -> i32 {
-   |                 ^^^
-   |                 |
-   |                 expected `Wrapper<'static>`, found `i32`
-   |                 help: change the output type to match the trait: `Wrapper<'static>`
+   |                 ^^^ expected `Wrapper<'static>`, found `i32`
    |
 note: type in trait
   --> $DIR/opaque-and-lifetime-mismatch.rs:4:17
@@ -87,6 +84,10 @@ LL |     fn bar() -> Wrapper<impl Sized>;
    |                 ^^^^^^^^^^^^^^^^^^^
    = note: expected signature `fn() -> Wrapper<'static>`
               found signature `fn() -> i32`
+help: change the output type to match the trait
+   |
+LL |     fn bar() -> Wrapper<'static> {
+   |                 ~~~~~~~~~~~~~~~~
 
 error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/opaque-and-lifetime-mismatch.rs:24:17
diff --git a/tests/ui/impl-trait/in-trait/specialization-broken.stderr b/tests/ui/impl-trait/in-trait/specialization-broken.stderr
index b8a8e2401b229..8c9f265601540 100644
--- a/tests/ui/impl-trait/in-trait/specialization-broken.stderr
+++ b/tests/ui/impl-trait/in-trait/specialization-broken.stderr
@@ -5,10 +5,7 @@ LL | default impl<U> Foo for U
    |              - found this type parameter
 ...
 LL |     fn bar(&self) -> U {
-   |                      ^
-   |                      |
-   |                      expected associated type, found type parameter `U`
-   |                      help: change the output type to match the trait: `impl Sized`
+   |                      ^ expected associated type, found type parameter `U`
    |
 note: type in trait
   --> $DIR/specialization-broken.rs:8:22
@@ -17,6 +14,10 @@ LL |     fn bar(&self) -> impl Sized;
    |                      ^^^^^^^^^^
    = note: expected signature `fn(&_) -> impl Sized`
               found signature `fn(&_) -> U`
+help: change the output type to match the trait
+   |
+LL |     fn bar(&self) -> impl Sized {
+   |                      ~~~~~~~~~~
 
 error: method with return-position `impl Trait` in trait cannot be specialized
   --> $DIR/specialization-broken.rs:15:5
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
index 4352af1c0df76..3692cc77b0fb4 100644
--- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
+++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
@@ -26,13 +26,14 @@ LL |     type Foo = impl PartialEq<(Foo, i32)>;
    |                -------------------------- the found opaque type
 ...
 LL |         fn eq(&self, _other: &(Foo, i32)) -> bool {
-   |                              ^^^^^^^^^^^
-   |                              |
-   |                              expected `a::Bar`, found opaque type
-   |                              help: change the parameter type to match the trait: `&(a::Bar, i32)`
+   |                              ^^^^^^^^^^^ expected `a::Bar`, found opaque type
    |
    = note: expected signature `fn(&a::Bar, &(a::Bar, _)) -> _`
               found signature `fn(&a::Bar, &(a::Foo, _)) -> _`
+help: change the parameter type to match the trait
+   |
+LL |         fn eq(&self, _other: &(a::Bar, i32)) -> bool {
+   |                              ~~~~~~~~~~~~~~
 
 error: unconstrained opaque type
   --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16
@@ -49,10 +50,7 @@ LL |     type Foo = impl PartialEq<(Foo, i32)>;
    |                -------------------------- the expected opaque type
 ...
 LL |         fn eq(&self, _other: &(Bar, i32)) -> bool {
-   |                              ^^^^^^^^^^^
-   |                              |
-   |                              expected opaque type, found `b::Bar`
-   |                              help: change the parameter type to match the trait: `&(b::Foo, i32)`
+   |                              ^^^^^^^^^^^ expected opaque type, found `b::Bar`
    |
    = note: expected signature `fn(&b::Bar, &(b::Foo, _)) -> _`
               found signature `fn(&b::Bar, &(b::Bar, _)) -> _`
@@ -61,6 +59,10 @@ note: this item must have the opaque type in its signature in order to be able t
    |
 LL |         fn eq(&self, _other: &(Bar, i32)) -> bool {
    |            ^^
+help: change the parameter type to match the trait
+   |
+LL |         fn eq(&self, _other: &(b::Foo, i32)) -> bool {
+   |                              ~~~~~~~~~~~~~~
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/impl-trait/trait_type.stderr b/tests/ui/impl-trait/trait_type.stderr
index 81e4c933e53f4..0eb132c7a1901 100644
--- a/tests/ui/impl-trait/trait_type.stderr
+++ b/tests/ui/impl-trait/trait_type.stderr
@@ -2,13 +2,14 @@ error[E0053]: method `fmt` has an incompatible type for trait
   --> $DIR/trait_type.rs:7:21
    |
 LL |    fn fmt(&self, x: &str) -> () { }
-   |                     ^^^^
-   |                     |
-   |                     types differ in mutability
-   |                     help: change the parameter type to match the trait: `&mut Formatter<'_>`
+   |                     ^^^^ types differ in mutability
    |
    = note: expected signature `fn(&MyType, &mut Formatter<'_>) -> Result<(), std::fmt::Error>`
               found signature `fn(&MyType, &str)`
+help: change the parameter type to match the trait
+   |
+LL |    fn fmt(&self, x: &mut Formatter<'_>) -> () { }
+   |                     ~~~~~~~~~~~~~~~~~~
 
 error[E0050]: method `fmt` has 1 parameter but the declaration in trait `std::fmt::Display::fmt` has 2
   --> $DIR/trait_type.rs:12:11
diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr
index bffe0447f8bb4..f0d259d01de94 100644
--- a/tests/ui/impl-trait/where-allowed.stderr
+++ b/tests/ui/impl-trait/where-allowed.stderr
@@ -397,10 +397,7 @@ LL |     type Out = impl Debug;
    |                ---------- the expected opaque type
 ...
 LL |     fn in_trait_impl_return() -> impl Debug { () }
-   |                                  ^^^^^^^^^^
-   |                                  |
-   |                                  expected opaque type, found a different opaque type
-   |                                  help: change the output type to match the trait: `<() as DummyTrait>::Out`
+   |                                  ^^^^^^^^^^ expected opaque type, found a different opaque type
    |
 note: type in trait
   --> $DIR/where-allowed.rs:119:34
@@ -410,6 +407,10 @@ LL |     fn in_trait_impl_return() -> Self::Out;
    = note: expected signature `fn() -> <() as DummyTrait>::Out`
               found signature `fn() -> impl Debug`
    = note: distinct uses of `impl Trait` result in different opaque types
+help: change the output type to match the trait
+   |
+LL |     fn in_trait_impl_return() -> <() as DummyTrait>::Out { () }
+   |                                  ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unconstrained opaque type
   --> $DIR/where-allowed.rs:122:16
diff --git a/tests/ui/issues/issue-20225.stderr b/tests/ui/issues/issue-20225.stderr
index 2d24a5bbd50ab..7d6b09cf7f893 100644
--- a/tests/ui/issues/issue-20225.stderr
+++ b/tests/ui/issues/issue-20225.stderr
@@ -4,13 +4,14 @@ error[E0053]: method `call` has an incompatible type for trait
 LL | impl<'a, T> Fn<(&'a T,)> for Foo {
    |          - found this type parameter
 LL |   extern "rust-call" fn call(&self, (_,): (T,)) {}
-   |                                           ^^^^
-   |                                           |
-   |                                           expected `&'a T`, found type parameter `T`
-   |                                           help: change the parameter type to match the trait: `(&'a T,)`
+   |                                           ^^^^ expected `&'a T`, found type parameter `T`
    |
    = note: expected signature `extern "rust-call" fn(&Foo, (&'a _,))`
               found signature `extern "rust-call" fn(&Foo, (_,))`
+help: change the parameter type to match the trait
+   |
+LL |   extern "rust-call" fn call(&self, (_,): (&'a T,)) {}
+   |                                           ~~~~~~~~
 
 error[E0053]: method `call_mut` has an incompatible type for trait
   --> $DIR/issue-20225.rs:11:51
@@ -18,13 +19,14 @@ error[E0053]: method `call_mut` has an incompatible type for trait
 LL | impl<'a, T> FnMut<(&'a T,)> for Foo {
    |          - found this type parameter
 LL |   extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
-   |                                                   ^^^^
-   |                                                   |
-   |                                                   expected `&'a T`, found type parameter `T`
-   |                                                   help: change the parameter type to match the trait: `(&'a T,)`
+   |                                                   ^^^^ expected `&'a T`, found type parameter `T`
    |
    = note: expected signature `extern "rust-call" fn(&mut Foo, (&'a _,))`
               found signature `extern "rust-call" fn(&mut Foo, (_,))`
+help: change the parameter type to match the trait
+   |
+LL |   extern "rust-call" fn call_mut(&mut self, (_,): (&'a T,)) {}
+   |                                                   ~~~~~~~~
 
 error[E0053]: method `call_once` has an incompatible type for trait
   --> $DIR/issue-20225.rs:18:47
@@ -33,13 +35,14 @@ LL | impl<'a, T> FnOnce<(&'a T,)> for Foo {
    |          - found this type parameter
 ...
 LL |   extern "rust-call" fn call_once(self, (_,): (T,)) {}
-   |                                               ^^^^
-   |                                               |
-   |                                               expected `&'a T`, found type parameter `T`
-   |                                               help: change the parameter type to match the trait: `(&'a T,)`
+   |                                               ^^^^ expected `&'a T`, found type parameter `T`
    |
    = note: expected signature `extern "rust-call" fn(Foo, (&'a _,))`
               found signature `extern "rust-call" fn(Foo, (_,))`
+help: change the parameter type to match the trait
+   |
+LL |   extern "rust-call" fn call_once(self, (_,): (&'a T,)) {}
+   |                                               ~~~~~~~~
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/issues/issue-21332.stderr b/tests/ui/issues/issue-21332.stderr
index 96e0f5fdb31db..7c960f7646db7 100644
--- a/tests/ui/issues/issue-21332.stderr
+++ b/tests/ui/issues/issue-21332.stderr
@@ -2,13 +2,14 @@ error[E0053]: method `next` has an incompatible type for trait
   --> $DIR/issue-21332.rs:5:27
    |
 LL |     fn next(&mut self) -> Result<i32, i32> { Ok(7) }
-   |                           ^^^^^^^^^^^^^^^^
-   |                           |
-   |                           expected `Option<i32>`, found `Result<i32, i32>`
-   |                           help: change the output type to match the trait: `Option<i32>`
+   |                           ^^^^^^^^^^^^^^^^ expected `Option<i32>`, found `Result<i32, i32>`
    |
    = note: expected signature `fn(&mut S) -> Option<i32>`
               found signature `fn(&mut S) -> Result<i32, i32>`
+help: change the output type to match the trait
+   |
+LL |     fn next(&mut self) -> Option<i32> { Ok(7) }
+   |                           ~~~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/mismatched_types/E0053.stderr b/tests/ui/mismatched_types/E0053.stderr
index d0bd5b46cf59f..2559d4487491e 100644
--- a/tests/ui/mismatched_types/E0053.stderr
+++ b/tests/ui/mismatched_types/E0053.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait
   --> $DIR/E0053.rs:9:15
    |
 LL |     fn foo(x: i16) { }
-   |               ^^^
-   |               |
-   |               expected `u16`, found `i16`
-   |               help: change the parameter type to match the trait: `u16`
+   |               ^^^ expected `u16`, found `i16`
    |
 note: type in trait
   --> $DIR/E0053.rs:2:15
@@ -14,15 +11,16 @@ LL |     fn foo(x: u16);
    |               ^^^
    = note: expected signature `fn(u16)`
               found signature `fn(i16)`
+help: change the parameter type to match the trait
+   |
+LL |     fn foo(x: u16) { }
+   |               ~~~
 
 error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/E0053.rs:11:12
    |
 LL |     fn bar(&mut self) { }
-   |            ^^^^^^^^^
-   |            |
-   |            types differ in mutability
-   |            help: change the self-receiver type to match the trait: `&self`
+   |            ^^^^^^^^^ types differ in mutability
    |
 note: type in trait
   --> $DIR/E0053.rs:3:12
@@ -31,6 +29,10 @@ LL |     fn bar(&self);
    |            ^^^^^
    = note: expected signature `fn(&Bar)`
               found signature `fn(&mut Bar)`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn bar(&self) { }
+   |            ~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/mismatched_types/issue-112036.stderr b/tests/ui/mismatched_types/issue-112036.stderr
index b93ce4a8674c2..bd446b3d78cb2 100644
--- a/tests/ui/mismatched_types/issue-112036.stderr
+++ b/tests/ui/mismatched_types/issue-112036.stderr
@@ -2,13 +2,14 @@ error[E0053]: method `drop` has an incompatible type for trait
   --> $DIR/issue-112036.rs:4:13
    |
 LL |     fn drop(self) {}
-   |             ^^^^
-   |             |
-   |             expected `&mut Foo`, found `Foo`
-   |             help: change the self-receiver type to match the trait: `&mut self`
+   |             ^^^^ expected `&mut Foo`, found `Foo`
    |
    = note: expected signature `fn(&mut Foo)`
               found signature `fn(Foo)`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn drop(&mut self) {}
+   |             ~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/mismatched_types/issue-13033.stderr b/tests/ui/mismatched_types/issue-13033.stderr
index 4886fa30e89b1..2a266d40e7717 100644
--- a/tests/ui/mismatched_types/issue-13033.stderr
+++ b/tests/ui/mismatched_types/issue-13033.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/issue-13033.rs:8:30
    |
 LL |     fn bar(&mut self, other: &dyn Foo) {}
-   |                              ^^^^^^^^
-   |                              |
-   |                              types differ in mutability
-   |                              help: change the parameter type to match the trait: `&mut dyn Foo`
+   |                              ^^^^^^^^ types differ in mutability
    |
 note: type in trait
   --> $DIR/issue-13033.rs:2:30
@@ -14,6 +11,10 @@ LL |     fn bar(&mut self, other: &mut dyn Foo);
    |                              ^^^^^^^^^^^^
    = note: expected signature `fn(&mut Baz, &mut dyn Foo)`
               found signature `fn(&mut Baz, &dyn Foo)`
+help: change the parameter type to match the trait
+   |
+LL |     fn bar(&mut self, other: &mut dyn Foo) {}
+   |                              ~~~~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
index 6e7bf5eb46d92..2e544a62223a0 100644
--- a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
+++ b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait
   --> $DIR/trait-impl-fn-incompatibility.rs:9:15
    |
 LL |     fn foo(x: i16) { }
-   |               ^^^
-   |               |
-   |               expected `u16`, found `i16`
-   |               help: change the parameter type to match the trait: `u16`
+   |               ^^^ expected `u16`, found `i16`
    |
 note: type in trait
   --> $DIR/trait-impl-fn-incompatibility.rs:2:15
@@ -14,15 +11,16 @@ LL |     fn foo(x: u16);
    |               ^^^
    = note: expected signature `fn(u16)`
               found signature `fn(i16)`
+help: change the parameter type to match the trait
+   |
+LL |     fn foo(x: u16) { }
+   |               ~~~
 
 error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/trait-impl-fn-incompatibility.rs:10:28
    |
 LL |     fn bar(&mut self, bar: &Bar) { }
-   |                            ^^^^
-   |                            |
-   |                            types differ in mutability
-   |                            help: change the parameter type to match the trait: `&mut Bar`
+   |                            ^^^^ types differ in mutability
    |
 note: type in trait
   --> $DIR/trait-impl-fn-incompatibility.rs:3:28
@@ -31,6 +29,10 @@ LL |     fn bar(&mut self, bar: &mut Bar);
    |                            ^^^^^^^^
    = note: expected signature `fn(&mut Bar, &mut Bar)`
               found signature `fn(&mut Bar, &Bar)`
+help: change the parameter type to match the trait
+   |
+LL |     fn bar(&mut self, bar: &mut Bar) { }
+   |                            ~~~~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/issue-35869.stderr b/tests/ui/traits/issue-35869.stderr
index 6d985bdeaf859..503f9cee246e9 100644
--- a/tests/ui/traits/issue-35869.stderr
+++ b/tests/ui/traits/issue-35869.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait
   --> $DIR/issue-35869.rs:11:15
    |
 LL |     fn foo(_: fn(u16) -> ()) {}
-   |               ^^^^^^^^^^^^^
-   |               |
-   |               expected `u8`, found `u16`
-   |               help: change the parameter type to match the trait: `fn(u8)`
+   |               ^^^^^^^^^^^^^ expected `u8`, found `u16`
    |
 note: type in trait
   --> $DIR/issue-35869.rs:2:15
@@ -14,15 +11,16 @@ LL |     fn foo(_: fn(u8) -> ());
    |               ^^^^^^^^^^^^
    = note: expected signature `fn(fn(u8))`
               found signature `fn(fn(u16))`
+help: change the parameter type to match the trait
+   |
+LL |     fn foo(_: fn(u8)) {}
+   |               ~~~~~~
 
 error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/issue-35869.rs:13:15
    |
 LL |     fn bar(_: Option<u16>) {}
-   |               ^^^^^^^^^^^
-   |               |
-   |               expected `u8`, found `u16`
-   |               help: change the parameter type to match the trait: `Option<u8>`
+   |               ^^^^^^^^^^^ expected `u8`, found `u16`
    |
 note: type in trait
   --> $DIR/issue-35869.rs:3:15
@@ -31,15 +29,16 @@ LL |     fn bar(_: Option<u8>);
    |               ^^^^^^^^^^
    = note: expected signature `fn(Option<u8>)`
               found signature `fn(Option<u16>)`
+help: change the parameter type to match the trait
+   |
+LL |     fn bar(_: Option<u8>) {}
+   |               ~~~~~~~~~~
 
 error[E0053]: method `baz` has an incompatible type for trait
   --> $DIR/issue-35869.rs:15:15
    |
 LL |     fn baz(_: (u16, u16)) {}
-   |               ^^^^^^^^^^
-   |               |
-   |               expected `u8`, found `u16`
-   |               help: change the parameter type to match the trait: `(u8, u16)`
+   |               ^^^^^^^^^^ expected `u8`, found `u16`
    |
 note: type in trait
   --> $DIR/issue-35869.rs:4:15
@@ -48,15 +47,16 @@ LL |     fn baz(_: (u8, u16));
    |               ^^^^^^^^^
    = note: expected signature `fn((u8, _))`
               found signature `fn((u16, _))`
+help: change the parameter type to match the trait
+   |
+LL |     fn baz(_: (u8, u16)) {}
+   |               ~~~~~~~~~
 
 error[E0053]: method `qux` has an incompatible type for trait
   --> $DIR/issue-35869.rs:17:17
    |
 LL |     fn qux() -> u16 { 5u16 }
-   |                 ^^^
-   |                 |
-   |                 expected `u8`, found `u16`
-   |                 help: change the output type to match the trait: `u8`
+   |                 ^^^ expected `u8`, found `u16`
    |
 note: type in trait
   --> $DIR/issue-35869.rs:5:17
@@ -65,6 +65,10 @@ LL |     fn qux() -> u8;
    |                 ^^
    = note: expected signature `fn() -> u8`
               found signature `fn() -> u16`
+help: change the output type to match the trait
+   |
+LL |     fn qux() -> u8 { 5u16 }
+   |                 ~~
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/traits/wrong-mul-method-signature.stderr b/tests/ui/traits/wrong-mul-method-signature.stderr
index 91162cbc1231f..e30b61622ae01 100644
--- a/tests/ui/traits/wrong-mul-method-signature.stderr
+++ b/tests/ui/traits/wrong-mul-method-signature.stderr
@@ -2,37 +2,40 @@ error[E0053]: method `mul` has an incompatible type for trait
   --> $DIR/wrong-mul-method-signature.rs:16:21
    |
 LL |     fn mul(self, s: &f64) -> Vec1 {
-   |                     ^^^^
-   |                     |
-   |                     expected `f64`, found `&f64`
-   |                     help: change the parameter type to match the trait: `f64`
+   |                     ^^^^ expected `f64`, found `&f64`
    |
    = note: expected signature `fn(Vec1, _) -> Vec1`
               found signature `fn(Vec1, &_) -> Vec1`
+help: change the parameter type to match the trait
+   |
+LL |     fn mul(self, s: f64) -> Vec1 {
+   |                     ~~~
 
 error[E0053]: method `mul` has an incompatible type for trait
   --> $DIR/wrong-mul-method-signature.rs:33:21
    |
 LL |     fn mul(self, s: f64) -> Vec2 {
-   |                     ^^^
-   |                     |
-   |                     expected `Vec2`, found `f64`
-   |                     help: change the parameter type to match the trait: `Vec2`
+   |                     ^^^ expected `Vec2`, found `f64`
    |
    = note: expected signature `fn(Vec2, Vec2) -> f64`
               found signature `fn(Vec2, f64) -> Vec2`
+help: change the parameter type to match the trait
+   |
+LL |     fn mul(self, s: Vec2) -> Vec2 {
+   |                     ~~~~
 
 error[E0053]: method `mul` has an incompatible type for trait
   --> $DIR/wrong-mul-method-signature.rs:52:29
    |
 LL |     fn mul(self, s: f64) -> f64 {
-   |                             ^^^
-   |                             |
-   |                             expected `i32`, found `f64`
-   |                             help: change the output type to match the trait: `i32`
+   |                             ^^^ expected `i32`, found `f64`
    |
    = note: expected signature `fn(Vec3, _) -> i32`
               found signature `fn(Vec3, _) -> f64`
+help: change the output type to match the trait
+   |
+LL |     fn mul(self, s: f64) -> i32 {
+   |                             ~~~
 
 error[E0308]: mismatched types
   --> $DIR/wrong-mul-method-signature.rs:63:45
diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.stderr b/tests/ui/type-alias-impl-trait/unnameable_type.stderr
index f567b01d29a1b..5b331c5660d9c 100644
--- a/tests/ui/type-alias-impl-trait/unnameable_type.stderr
+++ b/tests/ui/type-alias-impl-trait/unnameable_type.stderr
@@ -5,10 +5,7 @@ LL | type MyPrivate = impl Sized;
    |                  ---------- the found opaque type
 LL | impl Trait for u32 {
 LL |     fn dont_define_this(private: MyPrivate) {
-   |                                  ^^^^^^^^^
-   |                                  |
-   |                                  expected `Private`, found opaque type
-   |                                  help: change the parameter type to match the trait: `Private`
+   |                                  ^^^^^^^^^ expected `Private`, found opaque type
    |
 note: type in trait
   --> $DIR/unnameable_type.rs:10:39
@@ -17,6 +14,10 @@ LL |         fn dont_define_this(_private: Private) {}
    |                                       ^^^^^^^
    = note: expected signature `fn(Private)`
               found signature `fn(MyPrivate)`
+help: change the parameter type to match the trait
+   |
+LL |     fn dont_define_this(private: Private) {
+   |                                  ~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/typeck/mismatched-map-under-self.stderr b/tests/ui/typeck/mismatched-map-under-self.stderr
index 322bf349f92fc..59de00a58bbea 100644
--- a/tests/ui/typeck/mismatched-map-under-self.stderr
+++ b/tests/ui/typeck/mismatched-map-under-self.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `values` has an incompatible type for trait
   --> $DIR/mismatched-map-under-self.rs:10:15
    |
 LL |     fn values(self) -> Self::Values {
-   |               ^^^^
-   |               |
-   |               expected `&Option<T>`, found `Option<T>`
-   |               help: change the self-receiver type to match the trait: `&self`
+   |               ^^^^ expected `&Option<T>`, found `Option<T>`
    |
 note: type in trait
   --> $DIR/mismatched-map-under-self.rs:4:15
@@ -14,6 +11,10 @@ LL |     fn values(&self) -> Self::Values;
    |               ^^^^^
    = note: expected signature `fn(&Option<_>)`
               found signature `fn(Option<_>)`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn values(&self) -> Self::Values {
+   |               ~~~~~
 
 error[E0631]: type mismatch in function arguments
   --> $DIR/mismatched-map-under-self.rs:12:18
diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
index c48d094daea20..2a8c4edbdb5f3 100644
--- a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
+++ b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `dummy2` has an incompatible type for trait
   --> $DIR/ufcs-explicit-self-bad.rs:37:21
    |
 LL |     fn dummy2(self: &Bar<T>) {}
-   |               ------^^^^^^^
-   |               |     |
-   |               |     expected `&'a Bar<T>`, found `Bar<T>`
-   |               help: change the self-receiver type to match the trait: `&self`
+   |                     ^^^^^^^ expected `&'a Bar<T>`, found `Bar<T>`
    |
 note: type in trait
   --> $DIR/ufcs-explicit-self-bad.rs:31:15
@@ -14,6 +11,10 @@ LL |     fn dummy2(&self);
    |               ^^^^^
    = note: expected signature `fn(&&'a Bar<_>)`
               found signature `fn(&Bar<_>)`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn dummy2(&self) {}
+   |               ~~~~~
 
 error[E0307]: invalid `self` parameter type: `isize`
   --> $DIR/ufcs-explicit-self-bad.rs:8:18