about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_error_messages/locales/en-US/parse.ftl3
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs104
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs53
-rw-r--r--compiler/rustc_parse/src/errors.rs8
-rw-r--r--compiler/rustc_parse/src/parser/item.rs20
-rw-r--r--compiler/rustc_session/src/errors.rs33
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs79
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs34
-rw-r--r--library/core/src/iter/traits/iterator.rs1
-rw-r--r--library/core/src/option.rs44
-rw-r--r--library/core/src/result.rs7
-rw-r--r--src/test/ui/array-slice-vec/infer_array_len.stderr4
-rw-r--r--src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr4
-rw-r--r--src/test/ui/closures/issue-52437.stderr4
-rw-r--r--src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr6
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-105608.rs15
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-105608.stderr14
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-83249.stderr4
-rw-r--r--src/test/ui/error-codes/E0282.stderr4
-rw-r--r--src/test/ui/error-codes/E0401.stderr2
-rw-r--r--src/test/ui/illegal-sized-bound/mutability-mismatch.rs34
-rw-r--r--src/test/ui/illegal-sized-bound/mutability-mismatch.stderr24
-rw-r--r--src/test/ui/illegal-sized-bound/regular.rs32
-rw-r--r--src/test/ui/illegal-sized-bound/regular.stderr20
-rw-r--r--src/test/ui/impl-trait/issues/issue-86719.stderr4
-rw-r--r--src/test/ui/inference/erase-type-params-in-label.stderr12
-rw-r--r--src/test/ui/inference/issue-72690.stderr4
-rw-r--r--src/test/ui/issues/issue-18159.stderr4
-rw-r--r--src/test/ui/issues/issue-2151.stderr4
-rw-r--r--src/test/ui/issues/issue-24036.stderr4
-rw-r--r--src/test/ui/lazy-type-alias-impl-trait/branches3.stderr16
-rw-r--r--src/test/ui/lifetimes/issue-34979.stderr1
-rw-r--r--src/test/ui/match/match-unresolved-one-arm.stderr4
-rw-r--r--src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.rs34
-rw-r--r--src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.stderr50
-rw-r--r--src/test/ui/parser/issue-105366.fixed12
-rw-r--r--src/test/ui/parser/issue-105366.rs12
-rw-r--r--src/test/ui/parser/issue-105366.stderr13
-rw-r--r--src/test/ui/pattern/pat-tuple-bad-type.stderr4
-rw-r--r--src/test/ui/pattern/rest-pat-semantic-disallowed.stderr4
-rw-r--r--src/test/ui/resolve/issue-85348.stderr4
-rw-r--r--src/test/ui/span/method-and-field-eager-resolution.stderr8
-rw-r--r--src/test/ui/traits/issue-77982.stderr10
-rw-r--r--src/test/ui/traits/issue-85735.stderr3
-rw-r--r--src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.fixed14
-rw-r--r--src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.rs14
-rw-r--r--src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.stderr15
-rw-r--r--src/test/ui/type-alias-impl-trait/closures_in_branches.stderr8
-rw-r--r--src/test/ui/type/type-annotation-needed.stderr2
-rw-r--r--src/test/ui/type/type-check/unknown_type_for_closure.stderr4
-rw-r--r--src/test/ui/type/type-path-err-node-types.stderr4
54 files changed, 637 insertions, 189 deletions
diff --git a/compiler/rustc_error_messages/locales/en-US/parse.ftl b/compiler/rustc_error_messages/locales/en-US/parse.ftl
index 114b7ec1628..b53550e5fd5 100644
--- a/compiler/rustc_error_messages/locales/en-US/parse.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/parse.ftl
@@ -362,3 +362,6 @@ parse_fn_ptr_with_generics = function pointer types may not have generic paramet
 
 parse_invalid_identifier_with_leading_number = expected identifier, found number literal
     .label = identifiers cannot start with a number
+
+parse_maybe_fn_typo_with_impl = you might have meant to write `impl` instead of `fn`
+    .suggestion = replace `fn` with `impl` here
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index b15c086ffad..a7eae392de1 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -209,7 +209,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     ProbeScope::TraitsInScope,
                 ) {
                     Ok(ref new_pick) if pick.differs_from(new_pick) => {
-                        needs_mut = true;
+                        needs_mut = new_pick.self_ty.ref_mutability() != self_ty.ref_mutability();
                     }
                     _ => {}
                 }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 4f9e069c176..a4c36b4c9cd 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -20,7 +20,7 @@ use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
 use rustc_middle::ty::{self, DefIdTree, InferConst};
 use rustc_middle::ty::{GenericArg, GenericArgKind, SubstsRef};
 use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults};
-use rustc_span::symbol::{kw, Ident};
+use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::{BytePos, Span};
 use std::borrow::Cow;
 use std::iter;
@@ -79,7 +79,7 @@ impl InferenceDiagnosticsData {
 
     fn where_x_is_kind(&self, in_type: Ty<'_>) -> &'static str {
         if in_type.is_ty_infer() {
-            "empty"
+            ""
         } else if self.name == "_" {
             // FIXME: Consider specializing this message if there is a single `_`
             // in the type.
@@ -183,13 +183,24 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte
     printer
 }
 
-fn ty_to_string<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String {
+fn ty_to_string<'tcx>(
+    infcx: &InferCtxt<'tcx>,
+    ty: Ty<'tcx>,
+    called_method_def_id: Option<DefId>,
+) -> String {
     let printer = fmt_printer(infcx, Namespace::TypeNS);
     let ty = infcx.resolve_vars_if_possible(ty);
-    match ty.kind() {
+    match (ty.kind(), called_method_def_id) {
         // We don't want the regular output for `fn`s because it includes its path in
         // invalid pseudo-syntax, we want the `fn`-pointer output instead.
-        ty::FnDef(..) => ty.fn_sig(infcx.tcx).print(printer).unwrap().into_buffer(),
+        (ty::FnDef(..), _) => ty.fn_sig(infcx.tcx).print(printer).unwrap().into_buffer(),
+        (_, Some(def_id))
+            if ty.is_ty_infer()
+                && infcx.tcx.get_diagnostic_item(sym::iterator_collect_fn) == Some(def_id) =>
+        {
+            "Vec<_>".to_string()
+        }
+        _ if ty.is_ty_infer() => "/* Type */".to_string(),
         // FIXME: The same thing for closures, but this only works when the closure
         // does not capture anything.
         //
@@ -213,7 +224,7 @@ fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String {
         .map(|args| {
             args.tuple_fields()
                 .iter()
-                .map(|arg| ty_to_string(infcx, arg))
+                .map(|arg| ty_to_string(infcx, arg, None))
                 .collect::<Vec<_>>()
                 .join(", ")
         })
@@ -221,7 +232,7 @@ fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String {
     let ret = if fn_sig.output().skip_binder().is_unit() {
         String::new()
     } else {
-        format!(" -> {}", ty_to_string(infcx, fn_sig.output().skip_binder()))
+        format!(" -> {}", ty_to_string(infcx, fn_sig.output().skip_binder(), None))
     };
     format!("fn({}){}", args, ret)
 }
@@ -368,6 +379,7 @@ impl<'tcx> InferCtxt<'tcx> {
 }
 
 impl<'tcx> TypeErrCtxt<'_, 'tcx> {
+    #[instrument(level = "debug", skip(self, error_code))]
     pub fn emit_inference_failure_err(
         &self,
         body_id: Option<hir::BodyId>,
@@ -406,7 +418,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         let mut infer_subdiags = Vec::new();
         let mut multi_suggestions = Vec::new();
         match kind {
-            InferSourceKind::LetBinding { insert_span, pattern_name, ty } => {
+            InferSourceKind::LetBinding { insert_span, pattern_name, ty, def_id } => {
                 infer_subdiags.push(SourceKindSubdiag::LetLike {
                     span: insert_span,
                     name: pattern_name.map(|name| name.to_string()).unwrap_or_else(String::new),
@@ -415,7 +427,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
                     arg_name: arg_data.name,
                     kind: if pattern_name.is_some() { "with_pattern" } else { "other" },
-                    type_name: ty_to_string(self, ty),
+                    type_name: ty_to_string(self, ty, def_id),
                 });
             }
             InferSourceKind::ClosureArg { insert_span, ty } => {
@@ -427,7 +439,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
                     arg_name: arg_data.name,
                     kind: "closure",
-                    type_name: ty_to_string(self, ty),
+                    type_name: ty_to_string(self, ty, None),
                 });
             }
             InferSourceKind::GenericArg {
@@ -456,33 +468,39 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     parent_name,
                 });
 
-                let args = fmt_printer(self, Namespace::TypeNS)
-                    .comma_sep(generic_args.iter().copied().map(|arg| {
-                        if arg.is_suggestable(self.tcx, true) {
-                            return arg;
-                        }
+                let args = if self.infcx.tcx.get_diagnostic_item(sym::iterator_collect_fn)
+                    == Some(generics_def_id)
+                {
+                    "Vec<_>".to_string()
+                } else {
+                    fmt_printer(self, Namespace::TypeNS)
+                        .comma_sep(generic_args.iter().copied().map(|arg| {
+                            if arg.is_suggestable(self.tcx, true) {
+                                return arg;
+                            }
 
-                        match arg.unpack() {
-                            GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
-                            GenericArgKind::Type(_) => self
-                                .next_ty_var(TypeVariableOrigin {
-                                    span: rustc_span::DUMMY_SP,
-                                    kind: TypeVariableOriginKind::MiscVariable,
-                                })
-                                .into(),
-                            GenericArgKind::Const(arg) => self
-                                .next_const_var(
-                                    arg.ty(),
-                                    ConstVariableOrigin {
+                            match arg.unpack() {
+                                GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
+                                GenericArgKind::Type(_) => self
+                                    .next_ty_var(TypeVariableOrigin {
                                         span: rustc_span::DUMMY_SP,
-                                        kind: ConstVariableOriginKind::MiscVariable,
-                                    },
-                                )
-                                .into(),
-                        }
-                    }))
-                    .unwrap()
-                    .into_buffer();
+                                        kind: TypeVariableOriginKind::MiscVariable,
+                                    })
+                                    .into(),
+                                GenericArgKind::Const(arg) => self
+                                    .next_const_var(
+                                        arg.ty(),
+                                        ConstVariableOrigin {
+                                            span: rustc_span::DUMMY_SP,
+                                            kind: ConstVariableOriginKind::MiscVariable,
+                                        },
+                                    )
+                                    .into(),
+                            }
+                        }))
+                        .unwrap()
+                        .into_buffer()
+                };
 
                 if !have_turbofish {
                     infer_subdiags.push(SourceKindSubdiag::GenericSuggestion {
@@ -520,7 +538,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 ));
             }
             InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => {
-                let ty_info = ty_to_string(self, ty);
+                let ty_info = ty_to_string(self, ty, None);
                 multi_suggestions.push(SourceKindMultiSuggestion::new_closure_return(
                     ty_info,
                     data,
@@ -608,6 +626,7 @@ enum InferSourceKind<'tcx> {
         insert_span: Span,
         pattern_name: Option<Ident>,
         ty: Ty<'tcx>,
+        def_id: Option<DefId>,
     },
     ClosureArg {
         insert_span: Span,
@@ -662,7 +681,7 @@ impl<'tcx> InferSourceKind<'tcx> {
                 if ty.is_closure() {
                     ("closure", closure_as_fn_str(infcx, ty))
                 } else if !ty.is_ty_infer() {
-                    ("normal", ty_to_string(infcx, ty))
+                    ("normal", ty_to_string(infcx, ty, None))
                 } else {
                     ("other", String::new())
                 }
@@ -788,10 +807,18 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
     /// Uses `fn source_cost` to determine whether this inference source is preferable to
     /// previous sources. We generally prefer earlier sources.
     #[instrument(level = "debug", skip(self))]
-    fn update_infer_source(&mut self, new_source: InferSource<'tcx>) {
+    fn update_infer_source(&mut self, mut new_source: InferSource<'tcx>) {
         let cost = self.source_cost(&new_source) + self.attempt;
         debug!(?cost);
         self.attempt += 1;
+        if let Some(InferSource { kind: InferSourceKind::GenericArg { def_id: did, ..}, .. }) = self.infer_source
+            && let InferSourceKind::LetBinding { ref ty, ref mut def_id, ..} = new_source.kind
+            && ty.is_ty_infer()
+        {
+            // Customize the output so we talk about `let x: Vec<_> = iter.collect();` instead of
+            // `let x: _ = iter.collect();`, as this is a very common case.
+            *def_id = Some(did);
+        }
         if cost < self.infer_source_cost {
             self.infer_source_cost = cost;
             self.infer_source = Some(new_source);
@@ -1092,6 +1119,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
                                 insert_span: local.pat.span.shrink_to_hi(),
                                 pattern_name: local.pat.simple_ident(),
                                 ty,
+                                def_id: None,
                             },
                         })
                     }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 2ce7cd8beba..996148a7090 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -2014,31 +2014,54 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>(
     tcx: TyCtxt<'tcx>,
     substs: SubstsRef<'tcx>,
 ) -> SubstsRef<'tcx> {
-    tcx.mk_substs(substs.iter().enumerate().map(|(idx, arg)| {
-        match arg.unpack() {
-            GenericArgKind::Type(_) if arg.has_non_region_param() || arg.has_non_region_infer() => {
-                tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
+    struct ReplaceParamAndInferWithPlaceholder<'tcx> {
+        tcx: TyCtxt<'tcx>,
+        idx: usize,
+    }
+
+    impl<'tcx> TypeFolder<'tcx> for ReplaceParamAndInferWithPlaceholder<'tcx> {
+        fn tcx(&self) -> TyCtxt<'tcx> {
+            self.tcx
+        }
+
+        fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+            if let ty::Infer(_) = t.kind() {
+                self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
                     universe: ty::UniverseIndex::ROOT,
-                    name: ty::BoundVar::from_usize(idx),
+                    name: ty::BoundVar::from_usize({
+                        let idx = self.idx;
+                        self.idx += 1;
+                        idx
+                    }),
                 }))
-                .into()
+            } else {
+                t.super_fold_with(self)
             }
-            GenericArgKind::Const(ct) if ct.has_non_region_infer() || ct.has_non_region_param() => {
-                let ty = ct.ty();
-                // If the type references param or infer, replace that too...
+        }
+
+        fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
+            if let ty::ConstKind::Infer(_) = c.kind() {
+                let ty = c.ty();
+                // If the type references param or infer then ICE ICE ICE
                 if ty.has_non_region_param() || ty.has_non_region_infer() {
-                    bug!("const `{ct}`'s type should not reference params or types");
+                    bug!("const `{c}`'s type should not reference params or types");
                 }
-                tcx.mk_const(
+                self.tcx.mk_const(
                     ty::PlaceholderConst {
                         universe: ty::UniverseIndex::ROOT,
-                        name: ty::BoundVar::from_usize(idx),
+                        name: ty::BoundVar::from_usize({
+                            let idx = self.idx;
+                            self.idx += 1;
+                            idx
+                        }),
                     },
                     ty,
                 )
-                .into()
+            } else {
+                c.super_fold_with(self)
             }
-            _ => arg,
         }
-    }))
+    }
+
+    substs.fold_with(&mut ReplaceParamAndInferWithPlaceholder { tcx, idx: 0 })
 }
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 9875cde4a05..18a0bee9c2e 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -1221,3 +1221,11 @@ pub(crate) struct UnexpectedIfWithIf(
     #[suggestion(applicability = "machine-applicable", code = " ", style = "verbose")]
     pub Span,
 );
+
+#[derive(Diagnostic)]
+#[diag(parse_maybe_fn_typo_with_impl)]
+pub(crate) struct FnTypoWithImpl {
+    #[primary_span]
+    #[suggestion(applicability = "maybe-incorrect", code = "impl", style = "verbose")]
+    pub fn_span: Span,
+}
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index beb9d55d454..7c2d01509de 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -3,6 +3,7 @@ use crate::errors::{DocCommentDoesNotDocumentAnything, UseEmptyBlockNotSemi};
 use super::diagnostics::{dummy_arg, ConsumeClosingDelim};
 use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
 use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
+use crate::errors::FnTypoWithImpl;
 use rustc_ast::ast::*;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, TokenKind};
@@ -2131,11 +2132,26 @@ impl<'a> Parser<'a> {
         vis: &Visibility,
         case: Case,
     ) -> PResult<'a, (Ident, FnSig, Generics, Option<P<Block>>)> {
+        let fn_span = self.token.span;
         let header = self.parse_fn_front_matter(vis, case)?; // `const ... fn`
         let ident = self.parse_ident()?; // `foo`
         let mut generics = self.parse_generics()?; // `<'a, T, ...>`
-        let decl =
-            self.parse_fn_decl(fn_parse_mode.req_name, AllowPlus::Yes, RecoverReturnSign::Yes)?; // `(p: u8, ...)`
+        let decl = match self.parse_fn_decl(
+            fn_parse_mode.req_name,
+            AllowPlus::Yes,
+            RecoverReturnSign::Yes,
+        ) {
+            Ok(decl) => decl,
+            Err(old_err) => {
+                // If we see `for Ty ...` then user probably meant `impl` item.
+                if self.token.is_keyword(kw::For) {
+                    old_err.cancel();
+                    return Err(self.sess.create_err(FnTypoWithImpl { fn_span }));
+                } else {
+                    return Err(old_err);
+                }
+            }
+        };
         generics.where_clause = self.parse_where_clause()?; // `where T: Ord`
 
         let mut sig_hi = self.prev_token.span;
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index ee492f802a7..4266430c4c6 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -291,20 +291,33 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
         s.len() > 1 && s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit())
     }
 
-    // Try to lowercase the prefix if it's a valid base prefix.
-    fn fix_base_capitalisation(s: &str) -> Option<String> {
-        if let Some(stripped) = s.strip_prefix('B') {
-            Some(format!("0b{stripped}"))
-        } else if let Some(stripped) = s.strip_prefix('O') {
-            Some(format!("0o{stripped}"))
-        } else if let Some(stripped) = s.strip_prefix('X') {
-            Some(format!("0x{stripped}"))
+    // Try to lowercase the prefix if the prefix and suffix are valid.
+    fn fix_base_capitalisation(prefix: &str, suffix: &str) -> Option<String> {
+        let mut chars = suffix.chars();
+
+        let base_char = chars.next().unwrap();
+        let base = match base_char {
+            'B' => 2,
+            'O' => 8,
+            'X' => 16,
+            _ => return None,
+        };
+
+        // check that the suffix contains only base-appropriate characters
+        let valid = prefix == "0"
+            && chars
+                .filter(|c| *c != '_')
+                .take_while(|c| *c != 'i' && *c != 'u')
+                .all(|c| c.to_digit(base).is_some());
+
+        if valid {
+            Some(format!("0{}{}", base_char.to_ascii_lowercase(), &suffix[1..]))
         } else {
             None
         }
     }
 
-    let token::Lit { kind, suffix, .. } = lit;
+    let token::Lit { kind, symbol, suffix, .. } = lit;
     match err {
         // `LexerError` is an error, but it was already reported
         // by lexer, so here we don't report it the second time.
@@ -320,7 +333,7 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
             if looks_like_width_suffix(&['i', 'u'], suf) {
                 // If it looks like a width, try to be helpful.
                 sess.emit_err(InvalidIntLiteralWidth { span, width: suf[1..].into() });
-            } else if let Some(fixed) = fix_base_capitalisation(suf) {
+            } else if let Some(fixed) = fix_base_capitalisation(symbol.as_str(), suf) {
                 sess.emit_err(InvalidNumLiteralBasePrefix { span, fixed });
             } else {
                 sess.emit_err(InvalidNumLiteralSuffix { span, suffix: suf.to_string() });
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 85d416c43f9..ace095736c9 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -827,6 +827,7 @@ symbols! {
         item_like_imports,
         iter,
         iter_repeat,
+        iterator_collect_fn,
         kcfi,
         keyword,
         kind,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 19a1f248177..c68da3e24a1 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -42,7 +42,7 @@ use rustc_middle::ty::{
 };
 use rustc_session::Limit;
 use rustc_span::def_id::LOCAL_CRATE;
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::sym;
 use rustc_span::{ExpnKind, Span, DUMMY_SP};
 use std::fmt;
 use std::iter;
@@ -980,6 +980,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                 trait_ref,
                                 obligation.cause.body_id,
                                 &mut err,
+                                true,
                             ) {
                                 // This is *almost* equivalent to
                                 // `obligation.cause.code().peel_derives()`, but it gives us the
@@ -1015,6 +1016,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                         trait_ref,
                                         obligation.cause.body_id,
                                         &mut err,
+                                        true,
                                     );
                                 }
                             }
@@ -1434,6 +1436,7 @@ trait InferCtxtPrivExt<'tcx> {
         trait_ref: ty::PolyTraitRef<'tcx>,
         body_id: hir::HirId,
         err: &mut Diagnostic,
+        other: bool,
     ) -> bool;
 
     /// Gets the parent trait chain start
@@ -1888,7 +1891,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         trait_ref: ty::PolyTraitRef<'tcx>,
         body_id: hir::HirId,
         err: &mut Diagnostic,
+        other: bool,
     ) -> bool {
+        let other = if other { "other " } else { "" };
         let report = |mut candidates: Vec<TraitRef<'tcx>>, err: &mut Diagnostic| {
             candidates.sort();
             candidates.dedup();
@@ -1939,7 +1944,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             candidates.dedup();
             let end = if candidates.len() <= 9 { candidates.len() } else { 8 };
             err.help(&format!(
-                "the following other types implement trait `{}`:{}{}",
+                "the following {other}types implement trait `{}`:{}{}",
                 trait_ref.print_only_trait_path(),
                 candidates[..end].join(""),
                 if len > 9 { format!("\nand {} others", len - 8) } else { String::new() }
@@ -2180,7 +2185,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             trait_ref.skip_binder().substs.types().any(|t| !t.is_ty_infer());
                         // It doesn't make sense to talk about applicable impls if there are more
                         // than a handful of them.
-                        if impls.len() > 1 && impls.len() < 5 && has_non_region_infer {
+                        if impls.len() > 1 && impls.len() < 10 && has_non_region_infer {
                             self.annotate_source_of_ambiguity(&mut err, &impls, predicate);
                         } else {
                             if self.tainted_by_errors().is_some() {
@@ -2188,6 +2193,18 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                 return;
                             }
                             err.note(&format!("cannot satisfy `{}`", predicate));
+                            let impl_candidates = self.find_similar_impl_candidates(
+                                predicate.to_opt_poly_trait_pred().unwrap(),
+                            );
+                            if impl_candidates.len() < 10 {
+                                self.report_similar_impl_candidates(
+                                    impl_candidates,
+                                    trait_ref,
+                                    body_id.map(|id| id.hir_id).unwrap_or(obligation.cause.body_id),
+                                    &mut err,
+                                    false,
+                                );
+                            }
                         }
                     }
                     _ => {
@@ -2199,60 +2216,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     }
                 }
 
-                if let ObligationCauseCode::ItemObligation(def_id) | ObligationCauseCode::ExprItemObligation(def_id, ..) = *obligation.cause.code() {
-                    self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
-                } else if let Ok(snippet) = &self.tcx.sess.source_map().span_to_snippet(span)
-                    && let ObligationCauseCode::BindingObligation(def_id, _) | ObligationCauseCode::ExprBindingObligation(def_id, ..)
-                        = *obligation.cause.code()
+                if let ObligationCauseCode::ItemObligation(def_id)
+                | ObligationCauseCode::ExprItemObligation(def_id, ..) = *obligation.cause.code()
                 {
-                    let generics = self.tcx.generics_of(def_id);
-                    if generics.params.iter().any(|p| p.name != kw::SelfUpper)
-                        && !snippet.ends_with('>')
-                        && !generics.has_impl_trait()
-                        && !self.tcx.is_fn_trait(def_id)
-                    {
-                        // FIXME: To avoid spurious suggestions in functions where type arguments
-                        // where already supplied, we check the snippet to make sure it doesn't
-                        // end with a turbofish. Ideally we would have access to a `PathSegment`
-                        // instead. Otherwise we would produce the following output:
-                        //
-                        // error[E0283]: type annotations needed
-                        //   --> $DIR/issue-54954.rs:3:24
-                        //    |
-                        // LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
-                        //    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
-                        //    |                        |
-                        //    |                        cannot infer type
-                        //    |                        help: consider specifying the type argument
-                        //    |                        in the function call:
-                        //    |                        `Tt::const_val::<[i8; 123]>::<T>`
-                        // ...
-                        // LL |     const fn const_val<T: Sized>() -> usize {
-                        //    |                        - required by this bound in `Tt::const_val`
-                        //    |
-                        //    = note: cannot satisfy `_: Tt`
-
-                        // Clear any more general suggestions in favor of our specific one
-                        err.clear_suggestions();
-
-                        err.span_suggestion_verbose(
-                            span.shrink_to_hi(),
-                            &format!(
-                                "consider specifying the type argument{} in the function call",
-                                pluralize!(generics.params.len()),
-                            ),
-                            format!(
-                                "::<{}>",
-                                generics
-                                    .params
-                                    .iter()
-                                    .map(|p| p.name.to_string())
-                                    .collect::<Vec<String>>()
-                                    .join(", ")
-                            ),
-                            Applicability::HasPlaceholders,
-                        );
-                    }
+                    self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
                 }
 
                 if let (Some(body_id), Some(ty::subst::GenericArgKind::Type(_))) =
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index e17c3777485..55a05df763f 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -696,7 +696,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> bool {
         // It only make sense when suggesting dereferences for arguments
-        let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code()
+        let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, call_hir_id, .. } = obligation.cause.code()
             else { return false; };
         let Some(typeck_results) = &self.typeck_results
             else { return false; };
@@ -775,12 +775,33 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         real_trait_pred_and_base_ty,
                     );
                     if self.predicate_may_hold(&obligation) {
-                        err.span_suggestion_verbose(
-                            span.shrink_to_lo(),
-                            "consider dereferencing here",
-                            "*",
-                            Applicability::MachineApplicable,
+                        let call_node = self.tcx.hir().get(*call_hir_id);
+                        let msg = "consider dereferencing here";
+                        let is_receiver = matches!(
+                            call_node,
+                            Node::Expr(hir::Expr {
+                                kind: hir::ExprKind::MethodCall(_, receiver_expr, ..),
+                                ..
+                            })
+                            if receiver_expr.hir_id == *arg_hir_id
                         );
+                        if is_receiver {
+                            err.multipart_suggestion_verbose(
+                                msg,
+                                vec![
+                                    (span.shrink_to_lo(), "(*".to_string()),
+                                    (span.shrink_to_hi(), ")".to_string()),
+                                ],
+                                Applicability::MachineApplicable,
+                            )
+                        } else {
+                            err.span_suggestion_verbose(
+                                span.shrink_to_lo(),
+                                msg,
+                                '*',
+                                Applicability::MachineApplicable,
+                            )
+                        };
                         return true;
                     }
                 }
@@ -2854,6 +2875,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 arg_hir_id,
                 call_hir_id,
                 ref parent_code,
+                ..
             } => {
                 self.function_argument_obligation(
                     arg_hir_id,
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 83c7e8977e9..1cdee992137 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -1829,6 +1829,7 @@ pub trait Iterator {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "iterator_collect_fn")]
     fn collect<B: FromIterator<Self::Item>>(self) -> B
     where
         Self: Sized,
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 505d964e518..39462dca4ff 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -72,6 +72,50 @@
 //! }
 //! ```
 //!
+//! # The question mark operator, `?`
+//!
+//! Similar to the [`Result`] type, when writing code that calls many functions that return the
+//! [`Option`] type, handling `Some`/`None` can be tedious. The question mark
+//! operator, [`?`], hides some of the boilerplate of propagating values
+//! up the call stack.
+//!
+//! It replaces this:
+//!
+//! ```
+//! # #![allow(dead_code)]
+//! fn add_last_numbers(stack: &mut Vec<i32>) -> Option<i32> {
+//!     let a = stack.pop();
+//!     let b = stack.pop();
+//!
+//!     match (a, b) {
+//!         (Some(x), Some(y)) => Some(x + y),
+//!         _ => None,
+//!     }
+//! }
+//!
+//! ```
+//!
+//! With this:
+//!
+//! ```
+//! # #![allow(dead_code)]
+//! fn add_last_numbers(stack: &mut Vec<i32>) -> Option<i32> {
+//!     Some(stack.pop()? + stack.pop()?)
+//! }
+//! ```
+//!
+//! *It's much nicer!*
+//!
+//! Ending the expression with [`?`] will result in the [`Some`]'s unwrapped value, unless the
+//! result is [`None`], in which case [`None`] is returned early from the enclosing function.
+//!
+//! [`?`] can be used in functions that return [`Option`] because of the
+//! early return of [`None`] that it provides.
+//!
+//! [`?`]: crate::ops::Try
+//! [`Some`]: Some
+//! [`None`]: None
+//!
 //! # Representation
 //!
 //! Rust guarantees to optimize the following types `T` such that
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 3f33c5fd6ca..f00c40f35d5 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -209,11 +209,10 @@
 //!
 //! *It's much nicer!*
 //!
-//! Ending the expression with [`?`] will result in the unwrapped
-//! success ([`Ok`]) value, unless the result is [`Err`], in which case
-//! [`Err`] is returned early from the enclosing function.
+//! Ending the expression with [`?`] will result in the [`Ok`]'s unwrapped value, unless the result
+//! is [`Err`], in which case [`Err`] is returned early from the enclosing function.
 //!
-//! [`?`] can only be used in functions that return [`Result`] because of the
+//! [`?`] can be used in functions that return [`Result`] because of the
 //! early return of [`Err`] that it provides.
 //!
 //! [`expect`]: Result::expect
diff --git a/src/test/ui/array-slice-vec/infer_array_len.stderr b/src/test/ui/array-slice-vec/infer_array_len.stderr
index 919550cac30..c2a509a1963 100644
--- a/src/test/ui/array-slice-vec/infer_array_len.stderr
+++ b/src/test/ui/array-slice-vec/infer_array_len.stderr
@@ -6,8 +6,8 @@ LL |     let [_, _] = a.into();
    |
 help: consider giving this pattern a type
    |
-LL |     let [_, _]: _ = a.into();
-   |               +++
+LL |     let [_, _]: /* Type */ = a.into();
+   |               ++++++++++++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr b/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr
index d5432755cfe..7a04ed7381e 100644
--- a/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr
+++ b/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr
@@ -6,8 +6,8 @@ LL |     with_closure(|x: u32, y| {});
    |
 help: consider giving this closure parameter an explicit type
    |
-LL |     with_closure(|x: u32, y: _| {});
-   |                            +++
+LL |     with_closure(|x: u32, y: /* Type */| {});
+   |                            ++++++++++++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/issue-52437.stderr b/src/test/ui/closures/issue-52437.stderr
index 4c24a54bbbe..9ba24c7a886 100644
--- a/src/test/ui/closures/issue-52437.stderr
+++ b/src/test/ui/closures/issue-52437.stderr
@@ -12,8 +12,8 @@ LL |     [(); &(&'static: loop { |x| {}; }) as *const _ as usize]
    |
 help: consider giving this closure parameter an explicit type
    |
-LL |     [(); &(&'static: loop { |x: _| {}; }) as *const _ as usize]
-   |                               +++
+LL |     [(); &(&'static: loop { |x: /* Type */| {}; }) as *const _ as usize]
+   |                               ++++++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr b/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr
index 293ca6232b1..13ea4a295af 100644
--- a/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr
+++ b/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr
@@ -5,6 +5,12 @@ LL |     let y = Mask::<_, _>::splat(false);
    |         ^   ------------------- type must be known at this point
    |
    = note: cannot satisfy `_: MaskElement`
+   = help: the following types implement trait `MaskElement`:
+             i16
+             i32
+             i64
+             i8
+             isize
 note: required by a bound in `Mask::<T, LANES>::splat`
   --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL
 help: consider giving `y` an explicit type, where the type for type parameter `T` is specified
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-105608.rs b/src/test/ui/const-generics/generic_const_exprs/issue-105608.rs
new file mode 100644
index 00000000000..e28ba3b1ada
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-105608.rs
@@ -0,0 +1,15 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+struct Combination<const STRATEGIES: usize>;
+
+impl<const STRATEGIES: usize> Combination<STRATEGIES> {
+    fn and<M>(self) -> Combination<{ STRATEGIES + 1 }> {
+        Combination
+    }
+}
+
+pub fn main() {
+    Combination::<0>.and::<_>().and::<_>();
+    //~^ ERROR: type annotations needed
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-105608.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-105608.stderr
new file mode 100644
index 00000000000..0be4c43daac
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-105608.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+  --> $DIR/issue-105608.rs:13:22
+   |
+LL |     Combination::<0>.and::<_>().and::<_>();
+   |                      ^^^ cannot infer type of the type parameter `M` declared on the associated function `and`
+   |
+help: consider specifying the generic argument
+   |
+LL |     Combination::<0>.and::<_>().and::<_>();
+   |                         ~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
index 4d0d0253f1b..e0444042614 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
@@ -41,6 +41,7 @@ LL |     IsLessOrEqual<I, 8>: True,
    |                          ^^^^
    |
    = note: cannot satisfy `IsLessOrEqual<I, 8>: True`
+   = help: the trait `True` is implemented for `IsLessOrEqual<LHS, RHS>`
 
 error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual<I, 8>: True`
   --> $DIR/issue-72787.rs:21:26
@@ -49,6 +50,7 @@ LL |     IsLessOrEqual<I, 8>: True,
    |                          ^^^^
    |
    = note: cannot satisfy `IsLessOrEqual<I, 8>: True`
+   = help: the trait `True` is implemented for `IsLessOrEqual<LHS, RHS>`
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/const-generics/issues/issue-83249.stderr b/src/test/ui/const-generics/issues/issue-83249.stderr
index 362b8554b2f..7491fdc8a69 100644
--- a/src/test/ui/const-generics/issues/issue-83249.stderr
+++ b/src/test/ui/const-generics/issues/issue-83249.stderr
@@ -6,8 +6,8 @@ LL |     let _ = foo([0; 1]);
    |
 help: consider giving this pattern a type
    |
-LL |     let _: _ = foo([0; 1]);
-   |          +++
+LL |     let _: /* Type */ = foo([0; 1]);
+   |          ++++++++++++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0282.stderr b/src/test/ui/error-codes/E0282.stderr
index d01aa3617c7..892d3a81f27 100644
--- a/src/test/ui/error-codes/E0282.stderr
+++ b/src/test/ui/error-codes/E0282.stderr
@@ -6,8 +6,8 @@ LL |     let x = "hello".chars().rev().collect();
    |
 help: consider giving `x` an explicit type
    |
-LL |     let x: _ = "hello".chars().rev().collect();
-   |          +++
+LL |     let x: Vec<_> = "hello".chars().rev().collect();
+   |          ++++++++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr
index 9687eca61fa..fa4b91cacef 100644
--- a/src/test/ui/error-codes/E0401.stderr
+++ b/src/test/ui/error-codes/E0401.stderr
@@ -59,7 +59,7 @@ note: required by a bound in `bfnr`
    |
 LL |     fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) {
    |                              ^^^^ required by this bound in `bfnr`
-help: consider specifying the type arguments in the function call
+help: consider specifying the generic arguments
    |
 LL |     bfnr::<U, V, W>(x);
    |         +++++++++++
diff --git a/src/test/ui/illegal-sized-bound/mutability-mismatch.rs b/src/test/ui/illegal-sized-bound/mutability-mismatch.rs
new file mode 100644
index 00000000000..deb84f6fe97
--- /dev/null
+++ b/src/test/ui/illegal-sized-bound/mutability-mismatch.rs
@@ -0,0 +1,34 @@
+struct MutType;
+
+pub trait MutTrait {
+    fn function(&mut self)
+    where
+        Self: Sized;
+    //~^ this has a `Sized` requirement
+}
+
+impl MutTrait for MutType {
+    fn function(&mut self) {}
+}
+
+struct Type;
+
+pub trait Trait {
+    fn function(&self)
+    where
+        Self: Sized;
+    //~^ this has a `Sized` requirement
+}
+
+impl Trait for Type {
+    fn function(&self) {}
+}
+
+fn main() {
+    (&MutType as &dyn MutTrait).function();
+    //~^ ERROR the `function` method cannot be invoked on a trait object
+    //~| NOTE you need `&mut dyn MutTrait` instead of `&dyn MutTrait`
+    (&mut Type as &mut dyn Trait).function();
+    //~^ ERROR the `function` method cannot be invoked on a trait object
+    //~| NOTE you need `&dyn Trait` instead of `&mut dyn Trait`
+}
diff --git a/src/test/ui/illegal-sized-bound/mutability-mismatch.stderr b/src/test/ui/illegal-sized-bound/mutability-mismatch.stderr
new file mode 100644
index 00000000000..dbbf79a4f1a
--- /dev/null
+++ b/src/test/ui/illegal-sized-bound/mutability-mismatch.stderr
@@ -0,0 +1,24 @@
+error: the `function` method cannot be invoked on a trait object
+  --> $DIR/mutability-mismatch.rs:28:33
+   |
+LL |         Self: Sized;
+   |               ----- this has a `Sized` requirement
+...
+LL |     (&MutType as &dyn MutTrait).function();
+   |                                 ^^^^^^^^
+   |
+   = note: you need `&mut dyn MutTrait` instead of `&dyn MutTrait`
+
+error: the `function` method cannot be invoked on a trait object
+  --> $DIR/mutability-mismatch.rs:31:35
+   |
+LL |         Self: Sized;
+   |               ----- this has a `Sized` requirement
+...
+LL |     (&mut Type as &mut dyn Trait).function();
+   |                                   ^^^^^^^^
+   |
+   = note: you need `&dyn Trait` instead of `&mut dyn Trait`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/illegal-sized-bound/regular.rs b/src/test/ui/illegal-sized-bound/regular.rs
new file mode 100644
index 00000000000..7abd27ef983
--- /dev/null
+++ b/src/test/ui/illegal-sized-bound/regular.rs
@@ -0,0 +1,32 @@
+struct MutType;
+
+pub trait MutTrait {
+    fn function(&mut self)
+    where
+        Self: Sized;
+    //~^ this has a `Sized` requirement
+}
+
+impl MutTrait for MutType {
+    fn function(&mut self) {}
+}
+
+struct Type;
+
+pub trait Trait {
+    fn function(&self)
+    where
+        Self: Sized;
+    //~^ this has a `Sized` requirement
+}
+
+impl Trait for Type {
+    fn function(&self) {}
+}
+
+fn main() {
+    (&mut MutType as &mut dyn MutTrait).function();
+    //~^ ERROR the `function` method cannot be invoked on a trait object
+    (&Type as &dyn Trait).function();
+    //~^ ERROR the `function` method cannot be invoked on a trait object
+}
diff --git a/src/test/ui/illegal-sized-bound/regular.stderr b/src/test/ui/illegal-sized-bound/regular.stderr
new file mode 100644
index 00000000000..7f3744145d9
--- /dev/null
+++ b/src/test/ui/illegal-sized-bound/regular.stderr
@@ -0,0 +1,20 @@
+error: the `function` method cannot be invoked on a trait object
+  --> $DIR/regular.rs:28:41
+   |
+LL |         Self: Sized;
+   |               ----- this has a `Sized` requirement
+...
+LL |     (&mut MutType as &mut dyn MutTrait).function();
+   |                                         ^^^^^^^^
+
+error: the `function` method cannot be invoked on a trait object
+  --> $DIR/regular.rs:30:27
+   |
+LL |         Self: Sized;
+   |               ----- this has a `Sized` requirement
+...
+LL |     (&Type as &dyn Trait).function();
+   |                           ^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/impl-trait/issues/issue-86719.stderr b/src/test/ui/impl-trait/issues/issue-86719.stderr
index 09047cdcbe1..7592418fdfd 100644
--- a/src/test/ui/impl-trait/issues/issue-86719.stderr
+++ b/src/test/ui/impl-trait/issues/issue-86719.stderr
@@ -20,8 +20,8 @@ LL |         |_| true
    |
 help: consider giving this closure parameter an explicit type
    |
-LL |         |_: _| true
-   |           +++
+LL |         |_: /* Type */| true
+   |           ++++++++++++
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/inference/erase-type-params-in-label.stderr b/src/test/ui/inference/erase-type-params-in-label.stderr
index 5c52e7bcfab..9be18286480 100644
--- a/src/test/ui/inference/erase-type-params-in-label.stderr
+++ b/src/test/ui/inference/erase-type-params-in-label.stderr
@@ -10,10 +10,10 @@ note: required by a bound in `foo`
    |
 LL | fn foo<T, K, W: Default, Z: Default>(t: T, k: K) -> Foo<T, K, W, Z> {
    |                 ^^^^^^^ required by this bound in `foo`
-help: consider specifying the type arguments in the function call
+help: consider giving `foo` an explicit type, where the type for type parameter `W` is specified
    |
-LL |     let foo = foo::<T, K, W, Z>(1, "");
-   |                  ++++++++++++++
+LL |     let foo: Foo<i32, &str, W, Z> = foo(1, "");
+   |            ++++++++++++++++++++++
 
 error[E0283]: type annotations needed for `Bar<i32, &str, Z>`
   --> $DIR/erase-type-params-in-label.rs:5:9
@@ -27,10 +27,10 @@ note: required by a bound in `bar`
    |
 LL | fn bar<T, K, Z: Default>(t: T, k: K) -> Bar<T, K, Z> {
    |                 ^^^^^^^ required by this bound in `bar`
-help: consider specifying the type arguments in the function call
+help: consider giving `bar` an explicit type, where the type for type parameter `Z` is specified
    |
-LL |     let bar = bar::<T, K, Z>(1, "");
-   |                  +++++++++++
+LL |     let bar: Bar<i32, &str, Z> = bar(1, "");
+   |            +++++++++++++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/inference/issue-72690.stderr b/src/test/ui/inference/issue-72690.stderr
index d4eeda07366..8eda71ec09b 100644
--- a/src/test/ui/inference/issue-72690.stderr
+++ b/src/test/ui/inference/issue-72690.stderr
@@ -32,8 +32,8 @@ LL |     |x| String::from("x".as_ref());
    |
 help: consider giving this closure parameter an explicit type
    |
-LL |     |x: _| String::from("x".as_ref());
-   |       +++
+LL |     |x: /* Type */| String::from("x".as_ref());
+   |       ++++++++++++
 
 error[E0283]: type annotations needed
   --> $DIR/issue-72690.rs:12:26
diff --git a/src/test/ui/issues/issue-18159.stderr b/src/test/ui/issues/issue-18159.stderr
index 605ff3829d1..5e0589eed43 100644
--- a/src/test/ui/issues/issue-18159.stderr
+++ b/src/test/ui/issues/issue-18159.stderr
@@ -6,8 +6,8 @@ LL |     let x;
    |
 help: consider giving `x` an explicit type
    |
-LL |     let x: _;
-   |          +++
+LL |     let x: /* Type */;
+   |          ++++++++++++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-2151.stderr b/src/test/ui/issues/issue-2151.stderr
index 31a8ca5fbfa..c75038b6169 100644
--- a/src/test/ui/issues/issue-2151.stderr
+++ b/src/test/ui/issues/issue-2151.stderr
@@ -8,8 +8,8 @@ LL |     x.clone();
    |
 help: consider giving `x` an explicit type
    |
-LL |     let x: _ = panic!();
-   |          +++
+LL |     let x: /* Type */ = panic!();
+   |          ++++++++++++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-24036.stderr b/src/test/ui/issues/issue-24036.stderr
index a42e35c4cad..0e73a51faed 100644
--- a/src/test/ui/issues/issue-24036.stderr
+++ b/src/test/ui/issues/issue-24036.stderr
@@ -19,8 +19,8 @@ LL |         1 => |c| c + 1,
    |
 help: consider giving this closure parameter an explicit type
    |
-LL |         1 => |c: _| c + 1,
-   |                +++
+LL |         1 => |c: /* Type */| c + 1,
+   |                ++++++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr b/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr
index 420104e526d..fe2631f9474 100644
--- a/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr
+++ b/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr
@@ -6,8 +6,8 @@ LL |         |s| s.len()
    |
 help: consider giving this closure parameter an explicit type
    |
-LL |         |s: _| s.len()
-   |           +++
+LL |         |s: /* Type */| s.len()
+   |           ++++++++++++
 
 error[E0282]: type annotations needed
   --> $DIR/branches3.rs:15:10
@@ -17,8 +17,8 @@ LL |         |s| s.len()
    |
 help: consider giving this closure parameter an explicit type
    |
-LL |         |s: _| s.len()
-   |           +++
+LL |         |s: /* Type */| s.len()
+   |           ++++++++++++
 
 error[E0282]: type annotations needed
   --> $DIR/branches3.rs:23:10
@@ -28,8 +28,8 @@ LL |         |s| s.len()
    |
 help: consider giving this closure parameter an explicit type
    |
-LL |         |s: _| s.len()
-   |           +++
+LL |         |s: /* Type */| s.len()
+   |           ++++++++++++
 
 error[E0282]: type annotations needed
   --> $DIR/branches3.rs:30:10
@@ -39,8 +39,8 @@ LL |         |s| s.len()
    |
 help: consider giving this closure parameter an explicit type
    |
-LL |         |s: _| s.len()
-   |           +++
+LL |         |s: /* Type */| s.len()
+   |           ++++++++++++
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/lifetimes/issue-34979.stderr b/src/test/ui/lifetimes/issue-34979.stderr
index 5832c4d173c..a332c6547b8 100644
--- a/src/test/ui/lifetimes/issue-34979.stderr
+++ b/src/test/ui/lifetimes/issue-34979.stderr
@@ -5,6 +5,7 @@ LL |     &'a (): Foo,
    |             ^^^
    |
    = note: cannot satisfy `&'a (): Foo`
+   = help: the trait `Foo` is implemented for `&'a T`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/match/match-unresolved-one-arm.stderr b/src/test/ui/match/match-unresolved-one-arm.stderr
index 9eadb88a8ba..e3b501b2fd5 100644
--- a/src/test/ui/match/match-unresolved-one-arm.stderr
+++ b/src/test/ui/match/match-unresolved-one-arm.stderr
@@ -6,8 +6,8 @@ LL |     let x = match () {
    |
 help: consider giving `x` an explicit type
    |
-LL |     let x: _ = match () {
-   |          +++
+LL |     let x: /* Type */ = match () {
+   |          ++++++++++++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.rs b/src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.rs
new file mode 100644
index 00000000000..f00cde4a74c
--- /dev/null
+++ b/src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.rs
@@ -0,0 +1,34 @@
+// Checks that integers with seeming uppercase base prefixes do not get bogus capitalization
+// suggestions.
+
+fn main() {
+    _ = 123X1a3;
+    //~^ ERROR invalid suffix `X1a3` for number literal
+    //~| NOTE invalid suffix `X1a3`
+    //~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+    _ = 456O123;
+    //~^ ERROR invalid suffix `O123` for number literal
+    //~| NOTE invalid suffix `O123`
+    //~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+    _ = 789B101;
+    //~^ ERROR invalid suffix `B101` for number literal
+    //~| NOTE invalid suffix `B101`
+    //~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+    _ = 0XYZ;
+    //~^ ERROR invalid suffix `XYZ` for number literal
+    //~| NOTE invalid suffix `XYZ`
+    //~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+    _ = 0OPQ;
+    //~^ ERROR invalid suffix `OPQ` for number literal
+    //~| NOTE invalid suffix `OPQ`
+    //~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+    _ = 0BCD;
+    //~^ ERROR invalid suffix `BCD` for number literal
+    //~| NOTE invalid suffix `BCD`
+    //~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+}
diff --git a/src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.stderr b/src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.stderr
new file mode 100644
index 00000000000..380c16ca789
--- /dev/null
+++ b/src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.stderr
@@ -0,0 +1,50 @@
+error: invalid suffix `X1a3` for number literal
+  --> $DIR/uppercase-base-prefix-invalid-no-fix.rs:5:9
+   |
+LL |     _ = 123X1a3;
+   |         ^^^^^^^ invalid suffix `X1a3`
+   |
+   = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: invalid suffix `O123` for number literal
+  --> $DIR/uppercase-base-prefix-invalid-no-fix.rs:10:9
+   |
+LL |     _ = 456O123;
+   |         ^^^^^^^ invalid suffix `O123`
+   |
+   = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: invalid suffix `B101` for number literal
+  --> $DIR/uppercase-base-prefix-invalid-no-fix.rs:15:9
+   |
+LL |     _ = 789B101;
+   |         ^^^^^^^ invalid suffix `B101`
+   |
+   = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: invalid suffix `XYZ` for number literal
+  --> $DIR/uppercase-base-prefix-invalid-no-fix.rs:20:9
+   |
+LL |     _ = 0XYZ;
+   |         ^^^^ invalid suffix `XYZ`
+   |
+   = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: invalid suffix `OPQ` for number literal
+  --> $DIR/uppercase-base-prefix-invalid-no-fix.rs:25:9
+   |
+LL |     _ = 0OPQ;
+   |         ^^^^ invalid suffix `OPQ`
+   |
+   = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: invalid suffix `BCD` for number literal
+  --> $DIR/uppercase-base-prefix-invalid-no-fix.rs:30:9
+   |
+LL |     _ = 0BCD;
+   |         ^^^^ invalid suffix `BCD`
+   |
+   = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/parser/issue-105366.fixed b/src/test/ui/parser/issue-105366.fixed
new file mode 100644
index 00000000000..ad26643c327
--- /dev/null
+++ b/src/test/ui/parser/issue-105366.fixed
@@ -0,0 +1,12 @@
+// run-rustfix
+
+struct Foo;
+
+impl From<i32> for Foo {
+    //~^ ERROR you might have meant to write `impl` instead of `fn`
+    fn from(_a: i32) -> Self {
+        Foo
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-105366.rs b/src/test/ui/parser/issue-105366.rs
new file mode 100644
index 00000000000..311b6a60f1a
--- /dev/null
+++ b/src/test/ui/parser/issue-105366.rs
@@ -0,0 +1,12 @@
+// run-rustfix
+
+struct Foo;
+
+fn From<i32> for Foo {
+    //~^ ERROR you might have meant to write `impl` instead of `fn`
+    fn from(_a: i32) -> Self {
+        Foo
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-105366.stderr b/src/test/ui/parser/issue-105366.stderr
new file mode 100644
index 00000000000..0a7408e2c17
--- /dev/null
+++ b/src/test/ui/parser/issue-105366.stderr
@@ -0,0 +1,13 @@
+error: you might have meant to write `impl` instead of `fn`
+  --> $DIR/issue-105366.rs:5:1
+   |
+LL | fn From<i32> for Foo {
+   | ^^
+   |
+help: replace `fn` with `impl` here
+   |
+LL | impl From<i32> for Foo {
+   | ~~~~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pattern/pat-tuple-bad-type.stderr b/src/test/ui/pattern/pat-tuple-bad-type.stderr
index 3342b8e4002..da369d33397 100644
--- a/src/test/ui/pattern/pat-tuple-bad-type.stderr
+++ b/src/test/ui/pattern/pat-tuple-bad-type.stderr
@@ -9,8 +9,8 @@ LL |         (..) => {}
    |
 help: consider giving `x` an explicit type
    |
-LL |     let x: _;
-   |          +++
+LL |     let x: /* Type */;
+   |          ++++++++++++
 
 error[E0308]: mismatched types
   --> $DIR/pat-tuple-bad-type.rs:10:9
diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr
index e6a4e5f19b7..beba7def96f 100644
--- a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr
+++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr
@@ -193,8 +193,8 @@ LL |     let x @ ..;
    |
 help: consider giving this pattern a type
    |
-LL |     let x @ ..: _;
-   |               +++
+LL |     let x @ ..: /* Type */;
+   |               ++++++++++++
 
 error: aborting due to 23 previous errors
 
diff --git a/src/test/ui/resolve/issue-85348.stderr b/src/test/ui/resolve/issue-85348.stderr
index f839dd927db..42b43f825d1 100644
--- a/src/test/ui/resolve/issue-85348.stderr
+++ b/src/test/ui/resolve/issue-85348.stderr
@@ -21,8 +21,8 @@ LL |         let mut N;
    |
 help: consider giving `N` an explicit type
    |
-LL |         let mut N: _;
-   |                  +++
+LL |         let mut N: /* Type */;
+   |                  ++++++++++++
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/span/method-and-field-eager-resolution.stderr b/src/test/ui/span/method-and-field-eager-resolution.stderr
index 7d240589a3f..f6efbe40bc2 100644
--- a/src/test/ui/span/method-and-field-eager-resolution.stderr
+++ b/src/test/ui/span/method-and-field-eager-resolution.stderr
@@ -9,8 +9,8 @@ LL |     x.0;
    |
 help: consider giving `x` an explicit type
    |
-LL |     let mut x: _ = Default::default();
-   |              +++
+LL |     let mut x: /* Type */ = Default::default();
+   |              ++++++++++++
 
 error[E0282]: type annotations needed
   --> $DIR/method-and-field-eager-resolution.rs:11:9
@@ -23,8 +23,8 @@ LL |     x[0];
    |
 help: consider giving `x` an explicit type
    |
-LL |     let mut x: _ = Default::default();
-   |              +++
+LL |     let mut x: /* Type */ = Default::default();
+   |              ++++++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/traits/issue-77982.stderr b/src/test/ui/traits/issue-77982.stderr
index 8ab6414d4d8..0b57a8212bd 100644
--- a/src/test/ui/traits/issue-77982.stderr
+++ b/src/test/ui/traits/issue-77982.stderr
@@ -43,7 +43,15 @@ LL |     let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(
    |                                            |
    |                                            required by a bound introduced by this call
    |
-   = note: cannot satisfy `u32: From<_>`
+   = note: multiple `impl`s satisfying `u32: From<_>` found in the following crates: `core`, `std`:
+           - impl From<Ipv4Addr> for u32;
+           - impl From<NonZeroU32> for u32;
+           - impl From<bool> for u32;
+           - impl From<char> for u32;
+           - impl From<u16> for u32;
+           - impl From<u8> for u32;
+           - impl<T> From<!> for T;
+           - impl<T> From<T> for T;
 help: try using a fully qualified path to specify the expected types
    |
 LL |     let ips: Vec<_> = (0..100_000).map(|_| u32::from(<u32 as Into<T>>::into(0u32))).collect();
diff --git a/src/test/ui/traits/issue-85735.stderr b/src/test/ui/traits/issue-85735.stderr
index fa280135beb..930708f9ad8 100644
--- a/src/test/ui/traits/issue-85735.stderr
+++ b/src/test/ui/traits/issue-85735.stderr
@@ -5,6 +5,9 @@ LL |     T: FnMut(&'a ()),
    |        ^^^^^^^^^^^^^
    |
    = note: cannot satisfy `T: FnMut<(&'a (),)>`
+   = help: the following types implement trait `FnMut<Args>`:
+             &F
+             &mut F
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.fixed b/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.fixed
new file mode 100644
index 00000000000..ea3d1bf853a
--- /dev/null
+++ b/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.fixed
@@ -0,0 +1,14 @@
+// run-rustfix
+
+struct TargetStruct;
+
+impl From<usize> for TargetStruct {
+    fn from(_unchecked: usize) -> Self {
+        TargetStruct
+    }
+}
+
+fn main() {
+    let a = &3;
+    let _b: TargetStruct = (*a).into(); //~ ERROR the trait bound `TargetStruct: From<&{integer}>` is not satisfied
+}
diff --git a/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.rs b/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.rs
new file mode 100644
index 00000000000..9eda68027b2
--- /dev/null
+++ b/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.rs
@@ -0,0 +1,14 @@
+// run-rustfix
+
+struct TargetStruct;
+
+impl From<usize> for TargetStruct {
+    fn from(_unchecked: usize) -> Self {
+        TargetStruct
+    }
+}
+
+fn main() {
+    let a = &3;
+    let _b: TargetStruct = a.into(); //~ ERROR the trait bound `TargetStruct: From<&{integer}>` is not satisfied
+}
diff --git a/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.stderr b/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.stderr
new file mode 100644
index 00000000000..ede31a2c7bc
--- /dev/null
+++ b/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `TargetStruct: From<&{integer}>` is not satisfied
+  --> $DIR/suggest-dereferencing-receiver-argument.rs:13:30
+   |
+LL |     let _b: TargetStruct = a.into();
+   |                              ^^^^ the trait `From<&{integer}>` is not implemented for `TargetStruct`
+   |
+   = note: required for `&{integer}` to implement `Into<TargetStruct>`
+help: consider dereferencing here
+   |
+LL |     let _b: TargetStruct = (*a).into();
+   |                            ++ +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr b/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr
index 48b7946ea82..9cc15f14a99 100644
--- a/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr
+++ b/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr
@@ -6,8 +6,8 @@ LL |         |x| x.len()
    |
 help: consider giving this closure parameter an explicit type
    |
-LL |         |x: _| x.len()
-   |           +++
+LL |         |x: /* Type */| x.len()
+   |           ++++++++++++
 
 error[E0282]: type annotations needed
   --> $DIR/closures_in_branches.rs:21:10
@@ -17,8 +17,8 @@ LL |         |x| x.len()
    |
 help: consider giving this closure parameter an explicit type
    |
-LL |         |x: _| x.len()
-   |           +++
+LL |         |x: /* Type */| x.len()
+   |           ++++++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/type/type-annotation-needed.stderr b/src/test/ui/type/type-annotation-needed.stderr
index 4af4c22f751..87bba3166be 100644
--- a/src/test/ui/type/type-annotation-needed.stderr
+++ b/src/test/ui/type/type-annotation-needed.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `foo`
    |
 LL | fn foo<T: Into<String>>(x: i32) {}
    |           ^^^^^^^^^^^^ required by this bound in `foo`
-help: consider specifying the type argument in the function call
+help: consider specifying the generic argument
    |
 LL |     foo::<T>(42);
    |        +++++
diff --git a/src/test/ui/type/type-check/unknown_type_for_closure.stderr b/src/test/ui/type/type-check/unknown_type_for_closure.stderr
index 9ae97f390d3..e5e29aabf37 100644
--- a/src/test/ui/type/type-check/unknown_type_for_closure.stderr
+++ b/src/test/ui/type/type-check/unknown_type_for_closure.stderr
@@ -12,8 +12,8 @@ LL |     let x = |_| {};
    |
 help: consider giving this closure parameter an explicit type
    |
-LL |     let x = |_: _| {};
-   |               +++
+LL |     let x = |_: /* Type */| {};
+   |               ++++++++++++
 
 error[E0282]: type annotations needed
   --> $DIR/unknown_type_for_closure.rs:10:14
diff --git a/src/test/ui/type/type-path-err-node-types.stderr b/src/test/ui/type/type-path-err-node-types.stderr
index c1ae10efac4..1aed1dbe4ba 100644
--- a/src/test/ui/type/type-path-err-node-types.stderr
+++ b/src/test/ui/type/type-path-err-node-types.stderr
@@ -30,8 +30,8 @@ LL |     let _ = |a, b: _| -> _ { 0 };
    |
 help: consider giving this closure parameter an explicit type
    |
-LL |     let _ = |a: _, b: _| -> _ { 0 };
-   |               +++
+LL |     let _ = |a: /* Type */, b: _| -> _ { 0 };
+   |               ++++++++++++
 
 error: aborting due to 5 previous errors