about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2021-12-13 21:22:02 -0800
committerMichael Goulet <michael@errs.io>2021-12-14 11:32:06 -0800
commitf29fb4792b1fa344817d95e997ef8de4befee302 (patch)
treee9b2bc5ec3174bb223db1fe4fe31b2b032355456
parent8f117a77d0880ed59afcc1a19c72ec5c1e44b97c (diff)
downloadrust-f29fb4792b1fa344817d95e997ef8de4befee302.tar.gz
rust-f29fb4792b1fa344817d95e997ef8de4befee302.zip
Make TyS::is_suggestable more structual
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs64
-rw-r--r--src/test/ui/associated-types/defaults-in-other-trait-items.rs1
-rw-r--r--src/test/ui/associated-types/defaults-in-other-trait-items.stderr6
-rw-r--r--src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr4
-rw-r--r--src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr8
-rw-r--r--src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr2
-rw-r--r--src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr2
-rw-r--r--src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr6
-rw-r--r--src/test/ui/half-open-range-patterns/pat-tuple-5.stderr2
-rw-r--r--src/test/ui/issues/issue-11844.stderr2
-rw-r--r--src/test/ui/issues/issue-12552.stderr5
-rw-r--r--src/test/ui/issues/issue-13466.stderr5
-rw-r--r--src/test/ui/issues/issue-3680.stderr2
-rw-r--r--src/test/ui/issues/issue-66706.stderr6
-rw-r--r--src/test/ui/issues/issue-72574-1.stderr2
-rw-r--r--src/test/ui/mismatched_types/E0409.stderr2
-rw-r--r--src/test/ui/mut/mut-pattern-mismatched.stderr6
-rw-r--r--src/test/ui/never_type/diverging-tuple-parts-39485.stderr6
-rw-r--r--src/test/ui/or-patterns/already-bound-name.stderr5
-rw-r--r--src/test/ui/or-patterns/inconsistent-modes.stderr5
-rw-r--r--src/test/ui/pattern/issue-74702.stderr4
-rw-r--r--src/test/ui/pattern/pat-tuple-overfield.stderr5
-rw-r--r--src/test/ui/return/return-type.stderr14
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr8
-rw-r--r--src/test/ui/slightly-nice-generic-literal-messages.stderr2
-rw-r--r--src/test/ui/structs/structure-constructor-type-mismatch.stderr6
-rw-r--r--src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr2
-rw-r--r--src/test/ui/typeck/issue-91334.stderr2
-rw-r--r--src/test/ui/typeck/return_type_containing_closure.rs10
-rw-r--r--src/test/ui/typeck/return_type_containing_closure.stderr17
30 files changed, 112 insertions, 99 deletions
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index 1acb3ec57de..ee00f6c62f3 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -1,7 +1,12 @@
 //! Diagnostics related methods for `TyS`.
 
+use crate::ty::subst::{GenericArg, GenericArgKind};
 use crate::ty::TyKind::*;
-use crate::ty::{InferTy, TyCtxt, TyS};
+use crate::ty::{
+    ConstKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, InferTy,
+    ProjectionTy, TyCtxt, TyS, TypeAndMut,
+};
+
 use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
@@ -63,16 +68,55 @@ impl<'tcx> TyS<'tcx> {
 
     /// Whether the type can be safely suggested during error recovery.
     pub fn is_suggestable(&self) -> bool {
-        !matches!(
-            self.kind(),
+        fn generic_arg_is_suggestible(arg: GenericArg<'_>) -> bool {
+            match arg.unpack() {
+                GenericArgKind::Type(ty) => ty.is_suggestable(),
+                GenericArgKind::Const(c) => const_is_suggestable(c.val),
+                _ => true,
+            }
+        }
+
+        fn const_is_suggestable(kind: ConstKind<'_>) -> bool {
+            match kind {
+                ConstKind::Infer(..)
+                | ConstKind::Bound(..)
+                | ConstKind::Placeholder(..)
+                | ConstKind::Error(..) => false,
+                _ => true,
+            }
+        }
+
+        // FIXME(compiler-errors): Some types are still not good to suggest,
+        // specifically references with lifetimes within the function. Not
+        //sure we have enough information to resolve whether a region is
+        // temporary, so I'll leave this as a fixme.
+
+        match self.kind() {
             Opaque(..)
-                | FnDef(..)
-                | FnPtr(..)
-                | Dynamic(..)
-                | Closure(..)
-                | Infer(..)
-                | Projection(..)
-        )
+            | FnDef(..)
+            | Closure(..)
+            | Infer(..)
+            | Generator(..)
+            | GeneratorWitness(..)
+            | Bound(_, _)
+            | Placeholder(_)
+            | Error(_) => false,
+            Dynamic(dty, _) => dty.iter().all(|pred| match pred.skip_binder() {
+                ExistentialPredicate::Trait(ExistentialTraitRef { substs, .. }) => {
+                    substs.iter().all(generic_arg_is_suggestible)
+                }
+                ExistentialPredicate::Projection(ExistentialProjection { substs, ty, .. }) => {
+                    ty.is_suggestable() && substs.iter().all(generic_arg_is_suggestible)
+                }
+                _ => true,
+            }),
+            Projection(ProjectionTy { substs: args, .. }) | Adt(_, args) | Tuple(args) => {
+                args.iter().all(generic_arg_is_suggestible)
+            }
+            Slice(ty) | RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => ty.is_suggestable(),
+            Array(ty, c) => ty.is_suggestable() && const_is_suggestable(c.val),
+            _ => true,
+        }
     }
 }
 
diff --git a/src/test/ui/associated-types/defaults-in-other-trait-items.rs b/src/test/ui/associated-types/defaults-in-other-trait-items.rs
index 4014f46285d..505751969b6 100644
--- a/src/test/ui/associated-types/defaults-in-other-trait-items.rs
+++ b/src/test/ui/associated-types/defaults-in-other-trait-items.rs
@@ -10,6 +10,7 @@ trait Tr {
         //~^ ERROR mismatched types
         //~| NOTE expected associated type, found `()`
         //~| NOTE expected associated type `<Self as Tr>::A`
+        //~| NOTE this expression has type `<Self as Tr>::A`
     }
 }
 
diff --git a/src/test/ui/associated-types/defaults-in-other-trait-items.stderr b/src/test/ui/associated-types/defaults-in-other-trait-items.stderr
index 493df30a64d..71d421926e7 100644
--- a/src/test/ui/associated-types/defaults-in-other-trait-items.stderr
+++ b/src/test/ui/associated-types/defaults-in-other-trait-items.stderr
@@ -5,13 +5,15 @@ LL |     type A = ();
    |     ------------ associated type defaults can't be assumed inside the trait defining them
 ...
 LL |         let () = p;
-   |             ^^ expected associated type, found `()`
+   |             ^^   - this expression has type `<Self as Tr>::A`
+   |             |
+   |             expected associated type, found `()`
    |
    = note: expected associated type `<Self as Tr>::A`
                     found unit type `()`
 
 error[E0308]: mismatched types
-  --> $DIR/defaults-in-other-trait-items.rs:35:25
+  --> $DIR/defaults-in-other-trait-items.rs:36:25
    |
 LL |     type Ty = u8;
    |     ------------- associated type defaults can't be assumed inside the trait defining them
diff --git a/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr b/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr
index e6161fdfa24..9ea78bd0974 100644
--- a/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr
+++ b/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr
@@ -2,9 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/default-match-bindings-forbidden.rs:6:5
    |
 LL |     (x, y) = &(1, 2);
-   |     ^^^^^^   ------- this expression has type `&({integer}, {integer})`
-   |     |
-   |     expected reference, found tuple
+   |     ^^^^^^ expected reference, found tuple
    |
    = note: expected type `&({integer}, {integer})`
              found tuple `(_, _)`
diff --git a/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr b/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr
index 1146b88278d..79ac1518766 100644
--- a/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr
+++ b/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr
@@ -10,9 +10,7 @@ error[E0308]: mismatched types
   --> $DIR/tuple_destructure_fail.rs:8:5
    |
 LL |     (a, a, b) = (1, 2);
-   |     ^^^^^^^^^   ------ this expression has type `({integer}, {integer})`
-   |     |
-   |     expected a tuple with 2 elements, found one with 3 elements
+   |     ^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements
    |
    = note: expected type `({integer}, {integer})`
              found tuple `(_, _, _)`
@@ -29,9 +27,7 @@ error[E0308]: mismatched types
   --> $DIR/tuple_destructure_fail.rs:10:5
    |
 LL |     (_,) = (1, 2);
-   |     ^^^^   ------ this expression has type `({integer}, {integer})`
-   |     |
-   |     expected a tuple with 2 elements, found one with 1 element
+   |     ^^^^ expected a tuple with 2 elements, found one with 1 element
    |
    = note: expected type `({integer}, {integer})`
              found tuple `(_,)`
diff --git a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr
index a6f8563a047..241485db49b 100644
--- a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr
+++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr
@@ -1,8 +1,6 @@
 error[E0308]: mismatched types
   --> $DIR/exclusive_range_pattern_syntax_collision.rs:6:13
    |
-LL |     match [5..4, 99..105, 43..44] {
-   |           ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
 LL |         [_, 99.., _] => {},
    |             ^^ expected struct `std::ops::Range`, found integer
    |
diff --git a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr
index 4e0102c930d..777d029d7dd 100644
--- a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr
+++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr
@@ -7,8 +7,6 @@ LL |         [_, 99..] => {},
 error[E0308]: mismatched types
   --> $DIR/exclusive_range_pattern_syntax_collision2.rs:6:13
    |
-LL |     match [5..4, 99..105, 43..44] {
-   |           ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
 LL |         [_, 99..] => {},
    |             ^^ expected struct `std::ops::Range`, found integer
    |
diff --git a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr
index 665eef2fcb9..6119733a7d8 100644
--- a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr
+++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr
@@ -1,8 +1,6 @@
 error[E0308]: mismatched types
   --> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:12
    |
-LL |     match [5..4, 99..105, 43..44] {
-   |           ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
 LL |         [..9, 99..100, _] => {},
    |            ^ expected struct `std::ops::Range`, found integer
    |
@@ -12,8 +10,6 @@ LL |         [..9, 99..100, _] => {},
 error[E0308]: mismatched types
   --> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:15
    |
-LL |     match [5..4, 99..105, 43..44] {
-   |           ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
 LL |         [..9, 99..100, _] => {},
    |               ^^  --- this is of type `{integer}`
    |               |
@@ -25,8 +21,6 @@ LL |         [..9, 99..100, _] => {},
 error[E0308]: mismatched types
   --> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:19
    |
-LL |     match [5..4, 99..105, 43..44] {
-   |           ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
 LL |         [..9, 99..100, _] => {},
    |               --  ^^^ expected struct `std::ops::Range`, found integer
    |               |
diff --git a/src/test/ui/half-open-range-patterns/pat-tuple-5.stderr b/src/test/ui/half-open-range-patterns/pat-tuple-5.stderr
index 307ad711b74..31ea3a17871 100644
--- a/src/test/ui/half-open-range-patterns/pat-tuple-5.stderr
+++ b/src/test/ui/half-open-range-patterns/pat-tuple-5.stderr
@@ -1,8 +1,6 @@
 error[E0308]: mismatched types
   --> $DIR/pat-tuple-5.rs:8:10
    |
-LL |     match (0, 1) {
-   |           ------ this expression has type `({integer}, {integer})`
 LL |         (PAT ..) => {}
    |          ^^^ expected tuple, found `u8`
    |
diff --git a/src/test/ui/issues/issue-11844.stderr b/src/test/ui/issues/issue-11844.stderr
index 9d7470e7af9..ecab1074a29 100644
--- a/src/test/ui/issues/issue-11844.stderr
+++ b/src/test/ui/issues/issue-11844.stderr
@@ -1,8 +1,6 @@
 error[E0308]: mismatched types
   --> $DIR/issue-11844.rs:6:9
    |
-LL |     match a {
-   |           - this expression has type `Option<Box<{integer}>>`
 LL |         Ok(a) =>
    |         ^^^^^ expected enum `Option`, found enum `Result`
    |
diff --git a/src/test/ui/issues/issue-12552.stderr b/src/test/ui/issues/issue-12552.stderr
index 3d8852ca748..1ba6852b17c 100644
--- a/src/test/ui/issues/issue-12552.stderr
+++ b/src/test/ui/issues/issue-12552.stderr
@@ -1,8 +1,6 @@
 error[E0308]: mismatched types
   --> $DIR/issue-12552.rs:6:5
    |
-LL |   match t {
-   |         - this expression has type `Result<_, {integer}>`
 LL |     Some(k) => match k {
    |     ^^^^^^^ expected enum `Result`, found enum `Option`
    |
@@ -12,9 +10,6 @@ LL |     Some(k) => match k {
 error[E0308]: mismatched types
   --> $DIR/issue-12552.rs:9:5
    |
-LL |   match t {
-   |         - this expression has type `Result<_, {integer}>`
-...
 LL |     None => ()
    |     ^^^^ expected enum `Result`, found enum `Option`
    |
diff --git a/src/test/ui/issues/issue-13466.stderr b/src/test/ui/issues/issue-13466.stderr
index c78466f4e8c..15ee49a5fdd 100644
--- a/src/test/ui/issues/issue-13466.stderr
+++ b/src/test/ui/issues/issue-13466.stderr
@@ -1,8 +1,6 @@
 error[E0308]: mismatched types
   --> $DIR/issue-13466.rs:8:9
    |
-LL |     let _x: usize = match Some(1) {
-   |                           ------- this expression has type `Option<{integer}>`
 LL |         Ok(u) => u,
    |         ^^^^^ expected enum `Option`, found enum `Result`
    |
@@ -12,9 +10,6 @@ LL |         Ok(u) => u,
 error[E0308]: mismatched types
   --> $DIR/issue-13466.rs:14:9
    |
-LL |     let _x: usize = match Some(1) {
-   |                           ------- this expression has type `Option<{integer}>`
-...
 LL |         Err(e) => panic!(e)
    |         ^^^^^^ expected enum `Option`, found enum `Result`
    |
diff --git a/src/test/ui/issues/issue-3680.stderr b/src/test/ui/issues/issue-3680.stderr
index e8fafa76b91..8dc0dfa2356 100644
--- a/src/test/ui/issues/issue-3680.stderr
+++ b/src/test/ui/issues/issue-3680.stderr
@@ -1,8 +1,6 @@
 error[E0308]: mismatched types
   --> $DIR/issue-3680.rs:3:9
    |
-LL |     match None {
-   |           ---- this expression has type `Option<_>`
 LL |         Err(_) => ()
    |         ^^^^^^ expected enum `Option`, found enum `Result`
    |
diff --git a/src/test/ui/issues/issue-66706.stderr b/src/test/ui/issues/issue-66706.stderr
index f0b93ac9111..3e933a0f01b 100644
--- a/src/test/ui/issues/issue-66706.stderr
+++ b/src/test/ui/issues/issue-66706.stderr
@@ -36,7 +36,7 @@ error[E0308]: mismatched types
   --> $DIR/issue-66706.rs:2:5
    |
 LL | fn a() {
-   |        - help: try adding a return type: `-> [{integer}; _]`
+   |        - possibly return type missing here?
 LL |     [0; [|_: _ &_| ()].len()]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
 
@@ -44,7 +44,7 @@ error[E0308]: mismatched types
   --> $DIR/issue-66706.rs:14:5
    |
 LL | fn c() {
-   |        - help: try adding a return type: `-> [{integer}; _]`
+   |        - possibly return type missing here?
 LL |     [0; [|&_: _ &_| {}; 0 ].len()]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
 
@@ -52,7 +52,7 @@ error[E0308]: mismatched types
   --> $DIR/issue-66706.rs:20:5
    |
 LL | fn d() {
-   |        - help: try adding a return type: `-> [{integer}; _]`
+   |        - possibly return type missing here?
 LL |     [0; match [|f @ &ref _| () ] {} ]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
 
diff --git a/src/test/ui/issues/issue-72574-1.stderr b/src/test/ui/issues/issue-72574-1.stderr
index 653869a237d..5d3d390a95d 100644
--- a/src/test/ui/issues/issue-72574-1.stderr
+++ b/src/test/ui/issues/issue-72574-1.stderr
@@ -21,8 +21,6 @@ LL |         (_a, _x @ ..) => {}
 error[E0308]: mismatched types
   --> $DIR/issue-72574-1.rs:4:9
    |
-LL |     match x {
-   |           - this expression has type `({integer}, {integer}, {integer})`
 LL |         (_a, _x @ ..) => {}
    |         ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements
    |
diff --git a/src/test/ui/mismatched_types/E0409.stderr b/src/test/ui/mismatched_types/E0409.stderr
index ef03b67b1b0..eb884bcc622 100644
--- a/src/test/ui/mismatched_types/E0409.stderr
+++ b/src/test/ui/mismatched_types/E0409.stderr
@@ -9,8 +9,6 @@ LL |         (0, ref y) | (y, 0) => {}
 error[E0308]: mismatched types
   --> $DIR/E0409.rs:5:23
    |
-LL |     match x {
-   |           - this expression has type `({integer}, {integer})`
 LL |         (0, ref y) | (y, 0) => {}
    |             -----     ^ expected `&{integer}`, found integer
    |             |
diff --git a/src/test/ui/mut/mut-pattern-mismatched.stderr b/src/test/ui/mut/mut-pattern-mismatched.stderr
index cad1cef5155..ccc8ac1278c 100644
--- a/src/test/ui/mut/mut-pattern-mismatched.stderr
+++ b/src/test/ui/mut/mut-pattern-mismatched.stderr
@@ -3,9 +3,6 @@ error[E0308]: mismatched types
    |
 LL |      let &_
    |          ^^ types differ in mutability
-...
-LL |         = foo;
-   |           --- this expression has type `&mut {integer}`
    |
    = note: expected mutable reference `&mut {integer}`
                       found reference `&_`
@@ -15,9 +12,6 @@ error[E0308]: mismatched types
    |
 LL |     let &mut _
    |         ^^^^^^ types differ in mutability
-...
-LL |          = bar;
-   |            --- this expression has type `&{integer}`
    |
    = note:      expected reference `&{integer}`
            found mutable reference `&mut _`
diff --git a/src/test/ui/never_type/diverging-tuple-parts-39485.stderr b/src/test/ui/never_type/diverging-tuple-parts-39485.stderr
index 32967b376ca..e99a38aaaee 100644
--- a/src/test/ui/never_type/diverging-tuple-parts-39485.stderr
+++ b/src/test/ui/never_type/diverging-tuple-parts-39485.stderr
@@ -1,15 +1,13 @@
 error[E0308]: mismatched types
   --> $DIR/diverging-tuple-parts-39485.rs:8:5
    |
+LL | fn g() {
+   |        - possibly return type missing here?
 LL |     &panic!()
    |     ^^^^^^^^^ expected `()`, found reference
    |
    = note: expected unit type `()`
               found reference `&_`
-help: try adding a return type
-   |
-LL | fn g() -> &_ {
-   |        +++++
 help: consider removing the borrow
    |
 LL -     &panic!()
diff --git a/src/test/ui/or-patterns/already-bound-name.stderr b/src/test/ui/or-patterns/already-bound-name.stderr
index 66112165622..92416a0d5cb 100644
--- a/src/test/ui/or-patterns/already-bound-name.stderr
+++ b/src/test/ui/or-patterns/already-bound-name.stderr
@@ -86,9 +86,8 @@ error[E0308]: mismatched types
   --> $DIR/already-bound-name.rs:30:32
    |
 LL |     let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1));
-   |              -                 ^                     ------- this expression has type `E<E<{integer}>>`
-   |              |                 |
-   |              |                 expected integer, found enum `E`
+   |              -                 ^ expected integer, found enum `E`
+   |              |
    |              first introduced with type `{integer}` here
    |
    = note: expected type `{integer}`
diff --git a/src/test/ui/or-patterns/inconsistent-modes.stderr b/src/test/ui/or-patterns/inconsistent-modes.stderr
index dae6bb41e74..95e8618808c 100644
--- a/src/test/ui/or-patterns/inconsistent-modes.stderr
+++ b/src/test/ui/or-patterns/inconsistent-modes.stderr
@@ -65,9 +65,8 @@ error[E0308]: mismatched types
   --> $DIR/inconsistent-modes.rs:13:32
    |
 LL |     let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0));
-   |              -----             ^^^^^^^^^             ----------- this expression has type `Result<({integer}, &{integer}), (_, _)>`
-   |              |                 |
-   |              |                 types differ in mutability
+   |              -----             ^^^^^^^^^ types differ in mutability
+   |              |
    |              first introduced with type `&{integer}` here
    |
    = note: expected type `&{integer}`
diff --git a/src/test/ui/pattern/issue-74702.stderr b/src/test/ui/pattern/issue-74702.stderr
index f2e2c8f021b..53dcf97f81c 100644
--- a/src/test/ui/pattern/issue-74702.stderr
+++ b/src/test/ui/pattern/issue-74702.stderr
@@ -22,9 +22,7 @@ error[E0308]: mismatched types
   --> $DIR/issue-74702.rs:2:9
    |
 LL |     let (foo @ ..,) = (0, 0);
-   |         ^^^^^^^^^^^   ------ this expression has type `({integer}, {integer})`
-   |         |
-   |         expected a tuple with 2 elements, found one with 1 element
+   |         ^^^^^^^^^^^ expected a tuple with 2 elements, found one with 1 element
    |
    = note: expected tuple `({integer}, {integer})`
               found tuple `(_,)`
diff --git a/src/test/ui/pattern/pat-tuple-overfield.stderr b/src/test/ui/pattern/pat-tuple-overfield.stderr
index 1c44f7e5f6f..64b6e5eec55 100644
--- a/src/test/ui/pattern/pat-tuple-overfield.stderr
+++ b/src/test/ui/pattern/pat-tuple-overfield.stderr
@@ -150,8 +150,6 @@ LL |         E1::Z0 => {}
 error[E0308]: mismatched types
   --> $DIR/pat-tuple-overfield.rs:19:9
    |
-LL |     match (1, 2, 3) {
-   |           --------- this expression has type `({integer}, {integer}, {integer})`
 LL |         (1, 2, 3, 4) => {}
    |         ^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 4 elements
    |
@@ -161,9 +159,6 @@ LL |         (1, 2, 3, 4) => {}
 error[E0308]: mismatched types
   --> $DIR/pat-tuple-overfield.rs:20:9
    |
-LL |     match (1, 2, 3) {
-   |           --------- this expression has type `({integer}, {integer}, {integer})`
-LL |         (1, 2, 3, 4) => {}
 LL |         (1, 2, .., 3, 4) => {}
    |         ^^^^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 4 elements
    |
diff --git a/src/test/ui/return/return-type.stderr b/src/test/ui/return/return-type.stderr
index 5af136e6011..f86209a651d 100644
--- a/src/test/ui/return/return-type.stderr
+++ b/src/test/ui/return/return-type.stderr
@@ -1,19 +1,15 @@
 error[E0308]: mismatched types
   --> $DIR/return-type.rs:10:5
    |
+LL | fn bar() {
+   |          - possibly return type missing here?
 LL |     foo(4 as usize)
-   |     ^^^^^^^^^^^^^^^ expected `()`, found struct `S`
+   |     ^^^^^^^^^^^^^^^- help: consider using a semicolon here: `;`
+   |     |
+   |     expected `()`, found struct `S`
    |
    = note: expected unit type `()`
                  found struct `S<usize>`
-help: consider using a semicolon here
-   |
-LL |     foo(4 as usize);
-   |                    +
-help: try adding a return type
-   |
-LL | fn bar() -> S<usize> {
-   |          +++++++++++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
index 3fc5cb1b079..1433a16d727 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
@@ -644,7 +644,9 @@ error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:76:12
    |
 LL |     if let Range { start: F, end } = F..|| true {}
-   |            ^^^^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found struct `std::ops::Range`
+   |            ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
+   |            |
+   |            expected fn pointer, found struct `std::ops::Range`
    |
    = note: expected fn pointer `fn() -> bool`
                   found struct `std::ops::Range<_>`
@@ -832,7 +834,9 @@ error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:140:15
    |
 LL |     while let Range { start: F, end } = F..|| true {}
-   |               ^^^^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found struct `std::ops::Range`
+   |               ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
+   |               |
+   |               expected fn pointer, found struct `std::ops::Range`
    |
    = note: expected fn pointer `fn() -> bool`
                   found struct `std::ops::Range<_>`
diff --git a/src/test/ui/slightly-nice-generic-literal-messages.stderr b/src/test/ui/slightly-nice-generic-literal-messages.stderr
index 14f01f0ebdf..61eabed9504 100644
--- a/src/test/ui/slightly-nice-generic-literal-messages.stderr
+++ b/src/test/ui/slightly-nice-generic-literal-messages.stderr
@@ -1,8 +1,6 @@
 error[E0308]: mismatched types
   --> $DIR/slightly-nice-generic-literal-messages.rs:7:9
    |
-LL |     match Foo(1.1, marker::PhantomData) {
-   |           ----------------------------- this expression has type `Foo<{float}, _>`
 LL |         1 => {}
    |         ^ expected struct `Foo`, found integer
    |
diff --git a/src/test/ui/structs/structure-constructor-type-mismatch.stderr b/src/test/ui/structs/structure-constructor-type-mismatch.stderr
index 3d64fc601df..98972a12159 100644
--- a/src/test/ui/structs/structure-constructor-type-mismatch.stderr
+++ b/src/test/ui/structs/structure-constructor-type-mismatch.stderr
@@ -101,8 +101,6 @@ LL | type PointF = Point<f32>;
 error[E0308]: mismatched types
   --> $DIR/structure-constructor-type-mismatch.rs:54:9
    |
-LL |     match (Point { x: 1, y: 2 }) {
-   |           ---------------------- this expression has type `Point<{integer}>`
 LL |         PointF::<u32> { .. } => {}
    |         ^^^^^^^^^^^^^^^^^^^^ expected integer, found `f32`
    |
@@ -112,8 +110,6 @@ LL |         PointF::<u32> { .. } => {}
 error[E0308]: mismatched types
   --> $DIR/structure-constructor-type-mismatch.rs:59:9
    |
-LL |     match (Point { x: 1, y: 2 }) {
-   |           ---------------------- this expression has type `Point<{integer}>`
 LL |         PointF { .. } => {}
    |         ^^^^^^^^^^^^^ expected integer, found `f32`
    |
@@ -123,8 +119,6 @@ LL |         PointF { .. } => {}
 error[E0308]: mismatched types
   --> $DIR/structure-constructor-type-mismatch.rs:67:9
    |
-LL |     match (Pair { x: 1, y: 2 }) {
-   |           --------------------- this expression has type `Pair<{integer}, {integer}>`
 LL |         PairF::<u32> { .. } => {}
    |         ^^^^^^^^^^^^^^^^^^^ expected integer, found `f32`
    |
diff --git a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr
index b4d7dfe06be..b92a6f2ec2b 100644
--- a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr
+++ b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/issue-57673-ice-on-deref-of-boxed-trait.rs:5:5
    |
 LL | fn ice(x: Box<dyn Iterator<Item=()>>) {
-   |                                       - possibly return type missing here?
+   |                                       - help: try adding a return type: `-> (dyn Iterator<Item = ()> + 'static)`
 LL |     *x
    |     ^^ expected `()`, found trait object `dyn Iterator`
    |
diff --git a/src/test/ui/typeck/issue-91334.stderr b/src/test/ui/typeck/issue-91334.stderr
index 358cc771b7c..0872e83ea2e 100644
--- a/src/test/ui/typeck/issue-91334.stderr
+++ b/src/test/ui/typeck/issue-91334.stderr
@@ -40,7 +40,7 @@ error[E0308]: mismatched types
 LL | fn f(){||yield(((){),
    |       -^^^^^^^^^^^^^^^ expected `()`, found generator
    |       |
-   |       help: try adding a return type: `-> [generator@$DIR/issue-91334.rs:10:8: 10:23]`
+   |       possibly return type missing here?
    |
    = note: expected unit type `()`
               found generator `[generator@$DIR/issue-91334.rs:10:8: 10:23]`
diff --git a/src/test/ui/typeck/return_type_containing_closure.rs b/src/test/ui/typeck/return_type_containing_closure.rs
new file mode 100644
index 00000000000..aee9769b280
--- /dev/null
+++ b/src/test/ui/typeck/return_type_containing_closure.rs
@@ -0,0 +1,10 @@
+#[allow(unused)]
+fn foo() {
+    //~^ NOTE possibly return type missing here?
+    vec!['a'].iter().map(|c| c)
+    //~^ ERROR mismatched types [E0308]
+    //~| NOTE expected `()`, found struct `Map`
+    //~| NOTE expected unit type `()`
+}
+
+fn main() {}
diff --git a/src/test/ui/typeck/return_type_containing_closure.stderr b/src/test/ui/typeck/return_type_containing_closure.stderr
new file mode 100644
index 00000000000..b08152d6331
--- /dev/null
+++ b/src/test/ui/typeck/return_type_containing_closure.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+  --> $DIR/return_type_containing_closure.rs:4:5
+   |
+LL | fn foo() {
+   |          - possibly return type missing here?
+LL |
+LL |     vec!['a'].iter().map(|c| c)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: consider using a semicolon here: `;`
+   |     |
+   |     expected `()`, found struct `Map`
+   |
+   = note: expected unit type `()`
+                 found struct `Map<std::slice::Iter<'_, char>, [closure@$DIR/return_type_containing_closure.rs:4:26: 4:31]>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.