diff --git a/Cargo.lock b/Cargo.lock
index 2a88152b5194a..4bea3af7f3bfa 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5034,18 +5034,18 @@ checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af"
 
 [[package]]
 name = "semver"
-version = "1.0.14"
+version = "1.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
+checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"
 dependencies = [
  "serde",
 ]
 
 [[package]]
 name = "serde"
-version = "1.0.152"
+version = "1.0.147"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
+checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
 dependencies = [
  "serde_derive",
 ]
@@ -5062,9 +5062,9 @@ dependencies = [
 
 [[package]]
 name = "serde_derive"
-version = "1.0.152"
+version = "1.0.147"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
+checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -5082,9 +5082,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.91"
+version = "1.0.85"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
+checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
 dependencies = [
  "indexmap",
  "itoa",
@@ -5400,9 +5400,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
 
 [[package]]
 name = "syn"
-version = "1.0.107"
+version = "1.0.102"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
+checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -5576,7 +5576,6 @@ dependencies = [
  "lazy_static",
  "miropt-test-tools",
  "regex",
- "semver",
  "termcolor",
  "walkdir",
 ]
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 3b664363d232f..745eb8e6e1499 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -659,8 +659,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         if !self.maybe_suggest_bad_array_definition(&mut err, call_expr, callee_expr) {
-            if let Some((maybe_def, output_ty, _)) =
-                self.extract_callable_info(callee_expr, callee_ty)
+            if let Some((maybe_def, output_ty, _)) = self.extract_callable_info(callee_ty)
                 && !self.type_is_sized_modulo_regions(self.param_env, output_ty, callee_expr.span)
             {
                 let descr = match maybe_def {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 91498265259de..36742275186b6 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -11,7 +11,6 @@ use rustc_hir::{
     Expr, ExprKind, GenericBound, Node, Path, QPath, Stmt, StmtKind, TyKind, WherePredicate,
 };
 use rustc_hir_analysis::astconv::AstConv;
-use rustc_infer::infer;
 use rustc_infer::traits::{self, StatementAsExpression};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{
@@ -23,9 +22,9 @@ use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::{Span, Symbol};
 use rustc_trait_selection::infer::InferCtxtExt;
+use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt;
 use rustc_trait_selection::traits::error_reporting::DefIdOrName;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
-use rustc_trait_selection::traits::NormalizeExt;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub(crate) fn body_fn_sig(&self) -> Option<ty::FnSig<'tcx>> {
@@ -94,7 +93,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         found: Ty<'tcx>,
         can_satisfy: impl FnOnce(Ty<'tcx>) -> bool,
     ) -> bool {
-        let Some((def_id_or_name, output, inputs)) = self.extract_callable_info(expr, found)
+        let Some((def_id_or_name, output, inputs)) = self.extract_callable_info(found)
             else { return false; };
         if can_satisfy(output) {
             let (sugg_call, mut applicability) = match inputs.len() {
@@ -163,99 +162,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// because the callable type must also be well-formed to be called.
     pub(in super::super) fn extract_callable_info(
         &self,
-        expr: &Expr<'_>,
-        found: Ty<'tcx>,
+        ty: Ty<'tcx>,
     ) -> Option<(DefIdOrName, Ty<'tcx>, Vec<Ty<'tcx>>)> {
-        // Autoderef is useful here because sometimes we box callables, etc.
-        let Some((def_id_or_name, output, inputs)) = self.autoderef(expr.span, found).silence_errors().find_map(|(found, _)| {
-            match *found.kind() {
-                ty::FnPtr(fn_sig) =>
-                    Some((DefIdOrName::Name("function pointer"), fn_sig.output(), fn_sig.inputs())),
-                ty::FnDef(def_id, _) => {
-                    let fn_sig = found.fn_sig(self.tcx);
-                    Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs()))
-                }
-                ty::Closure(def_id, substs) => {
-                    let fn_sig = substs.as_closure().sig();
-                    Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs().map_bound(|inputs| &inputs[1..])))
-                }
-                ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
-                    self.tcx.bound_item_bounds(def_id).subst(self.tcx, substs).iter().find_map(|pred| {
-                        if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder()
-                        && Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
-                        // args tuple will always be substs[1]
-                        && let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
-                        {
-                            Some((
-                                DefIdOrName::DefId(def_id),
-                                pred.kind().rebind(proj.term.ty().unwrap()),
-                                pred.kind().rebind(args.as_slice()),
-                            ))
-                        } else {
-                            None
-                        }
-                    })
-                }
-                ty::Dynamic(data, _, ty::Dyn) => {
-                    data.iter().find_map(|pred| {
-                        if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder()
-                        && Some(proj.def_id) == self.tcx.lang_items().fn_once_output()
-                        // for existential projection, substs are shifted over by 1
-                        && let ty::Tuple(args) = proj.substs.type_at(0).kind()
-                        {
-                            Some((
-                                DefIdOrName::Name("trait object"),
-                                pred.rebind(proj.term.ty().unwrap()),
-                                pred.rebind(args.as_slice()),
-                            ))
-                        } else {
-                            None
-                        }
-                    })
-                }
-                ty::Param(param) => {
-                    let def_id = self.tcx.generics_of(self.body_id.owner).type_param(&param, self.tcx).def_id;
-                    self.tcx.predicates_of(self.body_id.owner).predicates.iter().find_map(|(pred, _)| {
-                        if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder()
-                        && Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
-                        && proj.projection_ty.self_ty() == found
-                        // args tuple will always be substs[1]
-                        && let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
-                        {
-                            Some((
-                                DefIdOrName::DefId(def_id),
-                                pred.kind().rebind(proj.term.ty().unwrap()),
-                                pred.kind().rebind(args.as_slice()),
-                            ))
-                        } else {
-                            None
-                        }
-                    })
-                }
-                _ => None,
-            }
-        }) else { return None; };
-
-        let output = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, output);
-        let inputs = inputs
-            .skip_binder()
-            .iter()
-            .map(|ty| {
-                self.replace_bound_vars_with_fresh_vars(
-                    expr.span,
-                    infer::FnCall,
-                    inputs.rebind(*ty),
-                )
-            })
-            .collect();
-
-        // We don't want to register any extra obligations, which should be
-        // implied by wf, but also because that would possibly result in
-        // erroneous errors later on.
-        let infer::InferOk { value: output, obligations: _ } =
-            self.at(&self.misc(expr.span), self.param_env).normalize(output);
-
-        if output.is_ty_var() { None } else { Some((def_id_or_name, output, inputs)) }
+        self.err_ctxt().extract_callable_info(self.body_id, self.param_env, ty)
     }
 
     pub fn suggest_two_fn_call(
@@ -267,9 +176,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         rhs_ty: Ty<'tcx>,
         can_satisfy: impl FnOnce(Ty<'tcx>, Ty<'tcx>) -> bool,
     ) -> bool {
-        let Some((_, lhs_output_ty, lhs_inputs)) = self.extract_callable_info(lhs_expr, lhs_ty)
+        let Some((_, lhs_output_ty, lhs_inputs)) = self.extract_callable_info(lhs_ty)
             else { return false; };
-        let Some((_, rhs_output_ty, rhs_inputs)) = self.extract_callable_info(rhs_expr, rhs_ty)
+        let Some((_, rhs_output_ty, rhs_inputs)) = self.extract_callable_info(rhs_ty)
             else { return false; };
 
         if can_satisfy(lhs_output_ty, rhs_output_ty) {
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 62e80659486a8..963f18447c05b 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -2655,8 +2655,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         found: Ty<'tcx>,
         expected: Ty<'tcx>,
     ) -> bool {
-        let Some((_def_id_or_name, output, _inputs)) = self.extract_callable_info(expr, found)
-        else { return false; };
+        let Some((_def_id_or_name, output, _inputs)) =
+            self.extract_callable_info(found) else {
+                return false;
+        };
 
         if !self.can_coerce(output, expected) {
             return false;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 66db1a2f92890..9747f360eca48 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2144,18 +2144,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         // suggest adding an explicit lifetime bound to it.
         let generics = self.tcx.generics_of(generic_param_scope);
         // type_param_span is (span, has_bounds)
+        let mut is_synthetic = false;
+        let mut ast_generics = None;
         let type_param_span = match bound_kind {
             GenericKind::Param(ref param) => {
                 // Account for the case where `param` corresponds to `Self`,
                 // which doesn't have the expected type argument.
                 if !(generics.has_self && param.index == 0) {
                     let type_param = generics.type_param(param, self.tcx);
+                    is_synthetic = type_param.kind.is_synthetic();
                     type_param.def_id.as_local().map(|def_id| {
                         // Get the `hir::Param` to verify whether it already has any bounds.
                         // We do this to avoid suggesting code that ends up as `T: 'a'b`,
                         // instead we suggest `T: 'a + 'b` in that case.
                         let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
-                        let ast_generics = self.tcx.hir().get_generics(hir_id.owner.def_id);
+                        ast_generics = self.tcx.hir().get_generics(hir_id.owner.def_id);
                         let bounds =
                             ast_generics.and_then(|g| g.bounds_span_for_suggestions(def_id));
                         // `sp` only covers `T`, change it so that it covers
@@ -2187,11 +2190,64 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 .unwrap_or("'lt".to_string())
         };
 
-        let add_lt_sugg = generics
-            .params
-            .first()
-            .and_then(|param| param.def_id.as_local())
-            .map(|def_id| (self.tcx.def_span(def_id).shrink_to_lo(), format!("{}, ", new_lt)));
+        let mut add_lt_suggs: Vec<Option<_>> = vec![];
+        if is_synthetic {
+            if let Some(ast_generics) = ast_generics {
+                let named_lifetime_param_exist = ast_generics.params.iter().any(|p| {
+                    matches!(
+                        p.kind,
+                        hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }
+                    )
+                });
+                if named_lifetime_param_exist && let [param, ..] = ast_generics.params
+                {
+                    add_lt_suggs.push(Some((
+                        self.tcx.def_span(param.def_id).shrink_to_lo(),
+                        format!("{new_lt}, "),
+                    )));
+                } else {
+                    add_lt_suggs
+                        .push(Some((ast_generics.span.shrink_to_hi(), format!("<{new_lt}>"))));
+                }
+            }
+        } else {
+            if let [param, ..] = &generics.params[..] && let Some(def_id) = param.def_id.as_local()
+            {
+                add_lt_suggs
+                    .push(Some((self.tcx.def_span(def_id).shrink_to_lo(), format!("{new_lt}, "))));
+            }
+        }
+
+        if let Some(ast_generics) = ast_generics {
+            for p in ast_generics.params {
+                if p.is_elided_lifetime() {
+                    if self
+                        .tcx
+                        .sess
+                        .source_map()
+                        .span_to_prev_source(p.span.shrink_to_hi())
+                        .ok()
+                        .map_or(false, |s| *s.as_bytes().last().unwrap() == b'&')
+                    {
+                        add_lt_suggs
+                            .push(Some(
+                                (
+                                    p.span.shrink_to_hi(),
+                                    if let Ok(snip) = self.tcx.sess.source_map().span_to_next_source(p.span)
+                                        && snip.starts_with(' ')
+                                    {
+                                        format!("{new_lt}")
+                                    } else {
+                                        format!("{new_lt} ")
+                                    }
+                                )
+                            ));
+                    } else {
+                        add_lt_suggs.push(Some((p.span.shrink_to_hi(), format!("<{new_lt}>"))));
+                    }
+                }
+            }
+        }
 
         let labeled_user_string = match bound_kind {
             GenericKind::Param(ref p) => format!("the parameter type `{}`", p),
@@ -2215,20 +2271,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             );
         }
 
-        fn binding_suggestion<S: fmt::Display>(
+        fn binding_suggestion<'tcx, S: fmt::Display>(
             err: &mut Diagnostic,
             type_param_span: Option<(Span, bool)>,
-            bound_kind: GenericKind<'_>,
+            bound_kind: GenericKind<'tcx>,
             sub: S,
-            add_lt_sugg: Option<(Span, String)>,
+            add_lt_suggs: Vec<Option<(Span, String)>>,
         ) {
             let msg = "consider adding an explicit lifetime bound";
             if let Some((sp, has_lifetimes)) = type_param_span {
                 let suggestion =
                     if has_lifetimes { format!(" + {}", sub) } else { format!(": {}", sub) };
                 let mut suggestions = vec![(sp, suggestion)];
-                if let Some(add_lt_sugg) = add_lt_sugg {
-                    suggestions.push(add_lt_sugg);
+                for add_lt_sugg in add_lt_suggs {
+                    if let Some(add_lt_sugg) = add_lt_sugg {
+                        suggestions.push(add_lt_sugg);
+                    }
                 }
                 err.multipart_suggestion_verbose(
                     format!("{msg}..."),
@@ -2252,9 +2310,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     };
                     let mut sugg =
                         vec![(sp, suggestion), (span.shrink_to_hi(), format!(" + {}", new_lt))];
-                    if let Some(lt) = add_lt_sugg.clone() {
-                        sugg.push(lt);
-                        sugg.rotate_right(1);
+                    for add_lt_sugg in add_lt_suggs.clone() {
+                        if let Some(lt) = add_lt_sugg {
+                            sugg.push(lt);
+                            sugg.rotate_right(1);
+                        }
                     }
                     // `MaybeIncorrect` due to issue #41966.
                     err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect);
@@ -2358,7 +2418,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 // for the bound is not suitable for suggestions when `-Zverbose` is set because it
                 // uses `Debug` output, so we handle it specially here so that suggestions are
                 // always correct.
-                binding_suggestion(&mut err, type_param_span, bound_kind, name, None);
+                binding_suggestion(&mut err, type_param_span, bound_kind, name, vec![]);
                 err
             }
 
@@ -2371,7 +2431,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     "{} may not live long enough",
                     labeled_user_string
                 );
-                binding_suggestion(&mut err, type_param_span, bound_kind, "'static", None);
+                binding_suggestion(&mut err, type_param_span, bound_kind, "'static", vec![]);
                 err
             }
 
@@ -2410,7 +2470,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                                 type_param_span,
                                 bound_kind,
                                 new_lt,
-                                add_lt_sugg,
+                                add_lt_suggs,
                             );
                         }
                     }
diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs
index cd147d7e55813..b9c5a4e0d0d49 100644
--- a/compiler/rustc_middle/src/ty/_match.rs
+++ b/compiler/rustc_middle/src/ty/_match.rs
@@ -89,7 +89,9 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
                 Err(TypeError::Sorts(relate::expected_found(self, a, b)))
             }
 
-            (&ty::Error(_), _) | (_, &ty::Error(_)) => Ok(self.tcx().ty_error()),
+            (&ty::Error(guar), _) | (_, &ty::Error(guar)) => {
+                Ok(self.tcx().ty_error_with_guaranteed(guar))
+            }
 
             _ => relate::super_relate_tys(self, a, b),
         }
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 4d34ca3d66b5f..65fd8d9753de1 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -414,7 +414,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
             bug!("bound types encountered in super_relate_tys")
         }
 
-        (&ty::Error(_), _) | (_, &ty::Error(_)) => Ok(tcx.ty_error()),
+        (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(tcx.ty_error_with_guaranteed(guar)),
 
         (&ty::Never, _)
         | (&ty::Char, _)
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 5f06c4d82828e..e11db925a6270 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -2884,6 +2884,7 @@ impl<'tcx> ty::TypeVisitor<'tcx> for HasNumericInferVisitor {
     }
 }
 
+#[derive(Copy, Clone)]
 pub enum DefIdOrName {
     DefId(DefId),
     Name(&'static str),
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 53769742c47a7..648e9a97759e2 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -213,6 +213,13 @@ pub trait TypeErrCtxtExt<'tcx> {
         trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> bool;
 
+    fn extract_callable_info(
+        &self,
+        hir_id: HirId,
+        param_env: ty::ParamEnv<'tcx>,
+        found: Ty<'tcx>,
+    ) -> Option<(DefIdOrName, Ty<'tcx>, Vec<Ty<'tcx>>)>;
+
     fn suggest_add_reference_to_arg(
         &self,
         obligation: &PredicateObligation<'tcx>,
@@ -882,92 +889,19 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             return false;
         }
 
-        // This is duplicated from `extract_callable_info` in typeck, which
-        // relies on autoderef, so we can't use it here.
-        let found = trait_pred.self_ty().skip_binder().peel_refs();
-        let Some((def_id_or_name, output, inputs)) = (match *found.kind()
-        {
-            ty::FnPtr(fn_sig) => {
-                Some((DefIdOrName::Name("function pointer"), fn_sig.output(), fn_sig.inputs()))
-            }
-            ty::FnDef(def_id, _) => {
-                let fn_sig = found.fn_sig(self.tcx);
-                Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs()))
-            }
-            ty::Closure(def_id, substs) => {
-                let fn_sig = substs.as_closure().sig();
-                Some((
-                    DefIdOrName::DefId(def_id),
-                    fn_sig.output(),
-                    fn_sig.inputs().map_bound(|inputs| &inputs[1..]),
-                ))
-            }
-            ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
-                self.tcx.bound_item_bounds(def_id).subst(self.tcx, substs).iter().find_map(|pred| {
-                    if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder()
-                    && Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
-                    // args tuple will always be substs[1]
-                    && let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
-                    {
-                        Some((
-                            DefIdOrName::DefId(def_id),
-                            pred.kind().rebind(proj.term.ty().unwrap()),
-                            pred.kind().rebind(args.as_slice()),
-                        ))
-                    } else {
-                        None
-                    }
-                })
-            }
-            ty::Dynamic(data, _, ty::Dyn) => {
-                data.iter().find_map(|pred| {
-                    if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder()
-                    && Some(proj.def_id) == self.tcx.lang_items().fn_once_output()
-                    // for existential projection, substs are shifted over by 1
-                    && let ty::Tuple(args) = proj.substs.type_at(0).kind()
-                    {
-                        Some((
-                            DefIdOrName::Name("trait object"),
-                            pred.rebind(proj.term.ty().unwrap()),
-                            pred.rebind(args.as_slice()),
-                        ))
-                    } else {
-                        None
-                    }
-                })
-            }
-            ty::Param(_) => {
-                obligation.param_env.caller_bounds().iter().find_map(|pred| {
-                    if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder()
-                    && Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
-                    && proj.projection_ty.self_ty() == found
-                    // args tuple will always be substs[1]
-                    && let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
-                    {
-                        Some((
-                            DefIdOrName::Name("type parameter"),
-                            pred.kind().rebind(proj.term.ty().unwrap()),
-                            pred.kind().rebind(args.as_slice()),
-                        ))
-                    } else {
-                        None
-                    }
-                })
-            }
-            _ => None,
-        }) else { return false; };
-        let output = self.replace_bound_vars_with_fresh_vars(
-            obligation.cause.span,
+        let self_ty = self.replace_bound_vars_with_fresh_vars(
+            DUMMY_SP,
             LateBoundRegionConversionTime::FnCall,
-            output,
+            trait_pred.self_ty(),
         );
-        let inputs = inputs.skip_binder().iter().map(|ty| {
-            self.replace_bound_vars_with_fresh_vars(
-                obligation.cause.span,
-                LateBoundRegionConversionTime::FnCall,
-                inputs.rebind(*ty),
-            )
-        });
+
+        // This is duplicated from `extract_callable_info` in typeck, which
+        // relies on autoderef, so we can't use it here.
+        let Some((def_id_or_name, output, inputs)) = self.extract_callable_info(
+            obligation.cause.body_id,
+            obligation.param_env,
+            self_ty,
+        ) else { return false; };
 
         // Remapping bound vars here
         let trait_pred_and_self = trait_pred.map_bound(|trait_pred| (trait_pred, output));
@@ -995,6 +929,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         };
 
         let args = inputs
+            .into_iter()
             .map(|ty| {
                 if ty.is_suggestable(self.tcx, false) {
                     format!("/* {ty} */")
@@ -1158,6 +1093,126 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         false
     }
 
+    /// Extracts information about a callable type for diagnostics. This is a
+    /// heuristic -- it doesn't necessarily mean that a type is always callable,
+    /// because the callable type must also be well-formed to be called.
+    fn extract_callable_info(
+        &self,
+        hir_id: HirId,
+        param_env: ty::ParamEnv<'tcx>,
+        found: Ty<'tcx>,
+    ) -> Option<(DefIdOrName, Ty<'tcx>, Vec<Ty<'tcx>>)> {
+        // Autoderef is useful here because sometimes we box callables, etc.
+        let Some((def_id_or_name, output, inputs)) = Autoderef::new(
+            self,
+            param_env,
+            hir_id,
+            DUMMY_SP,
+            found,
+        ).silence_errors().find_map(|(found, _)| {
+            match *found.kind() {
+                ty::FnPtr(fn_sig) =>
+                    Some((DefIdOrName::Name("function pointer"), fn_sig.output(), fn_sig.inputs())),
+                ty::FnDef(def_id, _) => {
+                    let fn_sig = found.fn_sig(self.tcx);
+                    Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs()))
+                }
+                ty::Closure(def_id, substs) => {
+                    let fn_sig = substs.as_closure().sig();
+                    Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs().map_bound(|inputs| &inputs[1..])))
+                }
+                ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
+                    self.tcx.bound_item_bounds(def_id).subst(self.tcx, substs).iter().find_map(|pred| {
+                        if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder()
+                        && Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
+                        // args tuple will always be substs[1]
+                        && let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
+                        {
+                            Some((
+                                DefIdOrName::DefId(def_id),
+                                pred.kind().rebind(proj.term.ty().unwrap()),
+                                pred.kind().rebind(args.as_slice()),
+                            ))
+                        } else {
+                            None
+                        }
+                    })
+                }
+                ty::Dynamic(data, _, ty::Dyn) => {
+                    data.iter().find_map(|pred| {
+                        if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder()
+                        && Some(proj.def_id) == self.tcx.lang_items().fn_once_output()
+                        // for existential projection, substs are shifted over by 1
+                        && let ty::Tuple(args) = proj.substs.type_at(0).kind()
+                        {
+                            Some((
+                                DefIdOrName::Name("trait object"),
+                                pred.rebind(proj.term.ty().unwrap()),
+                                pred.rebind(args.as_slice()),
+                            ))
+                        } else {
+                            None
+                        }
+                    })
+                }
+                ty::Param(param) => {
+                    let generics = self.tcx.generics_of(hir_id.owner.to_def_id());
+                    let name = if generics.count() > param.index as usize
+                        && let def = generics.param_at(param.index as usize, self.tcx)
+                        && matches!(def.kind, ty::GenericParamDefKind::Type { .. })
+                        && def.name == param.name
+                    {
+                        DefIdOrName::DefId(def.def_id)
+                    } else {
+                        DefIdOrName::Name("type parameter")
+                    };
+                    param_env.caller_bounds().iter().find_map(|pred| {
+                        if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder()
+                        && Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
+                        && proj.projection_ty.self_ty() == found
+                        // args tuple will always be substs[1]
+                        && let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
+                        {
+                            Some((
+                                name,
+                                pred.kind().rebind(proj.term.ty().unwrap()),
+                                pred.kind().rebind(args.as_slice()),
+                            ))
+                        } else {
+                            None
+                        }
+                    })
+                }
+                _ => None,
+            }
+        }) else { return None; };
+
+        let output = self.replace_bound_vars_with_fresh_vars(
+            DUMMY_SP,
+            LateBoundRegionConversionTime::FnCall,
+            output,
+        );
+        let inputs = inputs
+            .skip_binder()
+            .iter()
+            .map(|ty| {
+                self.replace_bound_vars_with_fresh_vars(
+                    DUMMY_SP,
+                    LateBoundRegionConversionTime::FnCall,
+                    inputs.rebind(*ty),
+                )
+            })
+            .collect();
+
+        // We don't want to register any extra obligations, which should be
+        // implied by wf, but also because that would possibly result in
+        // erroneous errors later on.
+        let InferOk { value: output, obligations: _ } =
+            self.at(&ObligationCause::dummy(), param_env).normalize(output);
+
+        if output.is_ty_var() { None } else { Some((def_id_or_name, output, inputs)) }
+    }
+
     fn suggest_add_reference_to_arg(
         &self,
         obligation: &PredicateObligation<'tcx>,
@@ -1358,57 +1413,117 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         err: &mut Diagnostic,
         trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> bool {
-        let span = obligation.cause.span;
+        let mut span = obligation.cause.span;
+        let mut trait_pred = trait_pred;
+        let mut code = obligation.cause.code();
+        while let Some((c, Some(parent_trait_pred))) = code.parent() {
+            // We want the root obligation, in order to detect properly handle
+            // `for _ in &mut &mut vec![] {}`.
+            code = c;
+            trait_pred = parent_trait_pred;
+        }
+        while span.desugaring_kind().is_some() {
+            // Remove all the hir desugaring contexts while maintaining the macro contexts.
+            span.remove_mark();
+        }
+        let mut expr_finder = super::FindExprBySpan::new(span);
+        let Some(hir::Node::Expr(body)) = self.tcx.hir().find(obligation.cause.body_id) else {
+            return false;
+        };
+        expr_finder.visit_expr(&body);
+        let mut maybe_suggest = |suggested_ty, count, suggestions| {
+            // Remapping bound vars here
+            let trait_pred_and_suggested_ty =
+                trait_pred.map_bound(|trait_pred| (trait_pred, suggested_ty));
+
+            let new_obligation = self.mk_trait_obligation_with_new_self_ty(
+                obligation.param_env,
+                trait_pred_and_suggested_ty,
+            );
 
-        let mut suggested = false;
-        if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
-            let refs_number =
-                snippet.chars().filter(|c| !c.is_whitespace()).take_while(|c| *c == '&').count();
-            if let Some('\'') = snippet.chars().filter(|c| !c.is_whitespace()).nth(refs_number) {
-                // Do not suggest removal of borrow from type arguments.
-                return false;
+            if self.predicate_may_hold(&new_obligation) {
+                let msg = if count == 1 {
+                    "consider removing the leading `&`-reference".to_string()
+                } else {
+                    format!("consider removing {count} leading `&`-references")
+                };
+
+                err.multipart_suggestion_verbose(
+                    &msg,
+                    suggestions,
+                    Applicability::MachineApplicable,
+                );
+                true
+            } else {
+                false
             }
+        };
 
-            // Skipping binder here, remapping below
-            let mut suggested_ty = trait_pred.self_ty().skip_binder();
+        // Maybe suggest removal of borrows from types in type parameters, like in
+        // `src/test/ui/not-panic/not-panic-safe.rs`.
+        let mut count = 0;
+        let mut suggestions = vec![];
+        // Skipping binder here, remapping below
+        let mut suggested_ty = trait_pred.self_ty().skip_binder();
+        if let Some(mut hir_ty) = expr_finder.ty_result {
+            while let hir::TyKind::Ref(_, mut_ty) = &hir_ty.kind {
+                count += 1;
+                let span = hir_ty.span.until(mut_ty.ty.span);
+                suggestions.push((span, String::new()));
 
-            for refs_remaining in 0..refs_number {
                 let ty::Ref(_, inner_ty, _) = suggested_ty.kind() else {
                     break;
                 };
                 suggested_ty = *inner_ty;
 
-                // Remapping bound vars here
-                let trait_pred_and_suggested_ty =
-                    trait_pred.map_bound(|trait_pred| (trait_pred, suggested_ty));
+                hir_ty = mut_ty.ty;
 
-                let new_obligation = self.mk_trait_obligation_with_new_self_ty(
-                    obligation.param_env,
-                    trait_pred_and_suggested_ty,
-                );
+                if maybe_suggest(suggested_ty, count, suggestions.clone()) {
+                    return true;
+                }
+            }
+        }
 
-                if self.predicate_may_hold(&new_obligation) {
-                    let sp = self
-                        .tcx
-                        .sess
-                        .source_map()
-                        .span_take_while(span, |c| c.is_whitespace() || *c == '&');
+        // Maybe suggest removal of borrows from expressions, like in `for i in &&&foo {}`.
+        let Some(mut expr) = expr_finder.result else { return false; };
+        let mut count = 0;
+        let mut suggestions = vec![];
+        // Skipping binder here, remapping below
+        let mut suggested_ty = trait_pred.self_ty().skip_binder();
+        'outer: loop {
+            while let hir::ExprKind::AddrOf(_, _, borrowed) = expr.kind {
+                count += 1;
+                let span = if expr.span.eq_ctxt(borrowed.span) {
+                    expr.span.until(borrowed.span)
+                } else {
+                    expr.span.with_hi(expr.span.lo() + BytePos(1))
+                };
+                suggestions.push((span, String::new()));
 
-                    let remove_refs = refs_remaining + 1;
+                let ty::Ref(_, inner_ty, _) = suggested_ty.kind() else {
+                    break 'outer;
+                };
+                suggested_ty = *inner_ty;
 
-                    let msg = if remove_refs == 1 {
-                        "consider removing the leading `&`-reference".to_string()
-                    } else {
-                        format!("consider removing {} leading `&`-references", remove_refs)
-                    };
+                expr = borrowed;
 
-                    err.span_suggestion_short(sp, &msg, "", Applicability::MachineApplicable);
-                    suggested = true;
-                    break;
+                if maybe_suggest(suggested_ty, count, suggestions.clone()) {
+                    return true;
                 }
             }
+            if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
+                && let hir::def::Res::Local(hir_id) = path.res
+                && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(hir_id)
+                && let Some(hir::Node::Local(local)) = self.tcx.hir().find_parent(binding.hir_id)
+                && let None = local.ty
+                && let Some(binding_expr) = local.init
+            {
+                expr = binding_expr;
+            } else {
+                break 'outer;
+            }
         }
-        suggested
+        false
     }
 
     fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic) {
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index c54d901e9b10a..170c1673dbd77 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -174,7 +174,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             .param_env
             .caller_bounds()
             .iter()
-            .filter_map(|o| o.to_opt_poly_trait_pred());
+            .filter_map(|p| p.to_opt_poly_trait_pred())
+            .filter(|p| !p.references_error());
 
         // Micro-optimization: filter out predicates relating to different traits.
         let matching_bounds =
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 3f14491f8032f..2615e2622821d 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2377,6 +2377,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id);
 
         let impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs);
+        if impl_trait_ref.references_error() {
+            return Err(());
+        }
 
         debug!(?impl_trait_ref);
 
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 3f8acc8505ff1..2eb29d4f9c574 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -622,9 +622,8 @@ impl<P: Deref> Pin<P> {
     /// that the closure is pinned.
     ///
     /// The better alternative is to avoid all that trouble and do the pinning in the outer function
-    /// instead (here using the unstable `pin` macro):
+    /// instead (here using the [`pin!`][crate::pin::pin] macro):
     /// ```
-    /// #![feature(pin_macro)]
     /// use std::pin::pin;
     /// use std::task::Context;
     /// use std::future::Future;
@@ -1026,7 +1025,6 @@ impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P> where P: DispatchFromDyn<U> {}
 /// ### Basic usage
 ///
 /// ```rust
-/// #![feature(pin_macro)]
 /// # use core::marker::PhantomPinned as Foo;
 /// use core::pin::{pin, Pin};
 ///
@@ -1044,7 +1042,6 @@ impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P> where P: DispatchFromDyn<U> {}
 /// ### Manually polling a `Future` (without `Unpin` bounds)
 ///
 /// ```rust
-/// #![feature(pin_macro)]
 /// use std::{
 ///     future::Future,
 ///     pin::pin,
@@ -1083,7 +1080,7 @@ impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P> where P: DispatchFromDyn<U> {}
 /// ### With `Generator`s
 ///
 /// ```rust
-/// #![feature(generators, generator_trait, pin_macro)]
+/// #![feature(generators, generator_trait)]
 /// use core::{
 ///     ops::{Generator, GeneratorState},
 ///     pin::pin,
@@ -1126,7 +1123,6 @@ impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P> where P: DispatchFromDyn<U> {}
 /// The following, for instance, fails to compile:
 ///
 /// ```rust,compile_fail
-/// #![feature(pin_macro)]
 /// use core::pin::{pin, Pin};
 /// # use core::{marker::PhantomPinned as Foo, mem::drop as stuff};
 ///
@@ -1168,7 +1164,7 @@ impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P> where P: DispatchFromDyn<U> {}
 /// constructor.
 ///
 /// [`Box::pin`]: ../../std/boxed/struct.Box.html#method.pin
-#[unstable(feature = "pin_macro", issue = "93178")]
+#[stable(feature = "pin_macro", since = "CURRENT_RUSTC_VERSION")]
 #[rustc_macro_transparency = "semitransparent"]
 #[allow_internal_unstable(unsafe_pin_internals)]
 pub macro pin($value:expr $(,)?) {
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index c910cb65c55de..42a26ae1675c1 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -48,7 +48,6 @@
 #![feature(is_sorted)]
 #![feature(layout_for_ptr)]
 #![feature(pattern)]
-#![feature(pin_macro)]
 #![feature(sort_internals)]
 #![feature(slice_take)]
 #![feature(slice_from_ptr_range)]
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 7acda8e98f18f..692ff0cbca68b 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -177,6 +177,12 @@ use crate::sys_common::thread_parking::Parker;
 use crate::sys_common::{AsInner, IntoInner};
 use crate::time::Duration;
 
+#[stable(feature = "scoped_threads", since = "1.63.0")]
+mod scoped;
+
+#[stable(feature = "scoped_threads", since = "1.63.0")]
+pub use scoped::{scope, Scope, ScopedJoinHandle};
+
 ////////////////////////////////////////////////////////////////////////////////
 // Thread-local storage
 ////////////////////////////////////////////////////////////////////////////////
@@ -184,12 +190,6 @@ use crate::time::Duration;
 #[macro_use]
 mod local;
 
-#[stable(feature = "scoped_threads", since = "1.63.0")]
-mod scoped;
-
-#[stable(feature = "scoped_threads", since = "1.63.0")]
-pub use scoped::{scope, Scope, ScopedJoinHandle};
-
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::local::{AccessError, LocalKey};
 
@@ -209,7 +209,6 @@ pub use self::local::{AccessError, LocalKey};
 ))]
 #[doc(hidden)]
 pub use self::local::fast::Key as __FastLocalKeyInner;
-
 // when building for tests, use real std's type
 #[unstable(feature = "libstd_thread_internals", issue = "none")]
 #[cfg(test)]
@@ -220,12 +219,21 @@ pub use self::local::fast::Key as __FastLocalKeyInner;
 pub use realstd::thread::__FastLocalKeyInner;
 
 #[unstable(feature = "libstd_thread_internals", issue = "none")]
+#[cfg(not(test))]
 #[cfg(all(
     not(target_thread_local),
     not(all(target_family = "wasm", not(target_feature = "atomics"))),
 ))]
 #[doc(hidden)]
 pub use self::local::os::Key as __OsLocalKeyInner;
+// when building for tests, use real std's type
+#[unstable(feature = "libstd_thread_internals", issue = "none")]
+#[cfg(test)]
+#[cfg(all(
+    not(target_thread_local),
+    not(all(target_family = "wasm", not(target_feature = "atomics"))),
+))]
+pub use realstd::thread::__OsLocalKeyInner;
 
 #[unstable(feature = "libstd_thread_internals", issue = "none")]
 #[cfg(all(target_family = "wasm", not(target_feature = "atomics")))]
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index f3998e98583ec..9cf43fc7a2193 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -934,7 +934,8 @@ def main():
     if len(sys.argv) > 1 and sys.argv[1] == 'help':
         sys.argv = [sys.argv[0], '-h'] + sys.argv[2:]
 
-    help_triggered = len(sys.argv) == 1 or any(x in ["-h", "--help", "--version"] for x in sys.argv)
+    help_triggered = (
+        '-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1)
     try:
         bootstrap(help_triggered)
         if not help_triggered:
diff --git a/src/test/ui/suggestions/call-on-unimplemented-with-autoderef.rs b/src/test/ui/suggestions/call-on-unimplemented-with-autoderef.rs
new file mode 100644
index 0000000000000..9021dd752e7e9
--- /dev/null
+++ b/src/test/ui/suggestions/call-on-unimplemented-with-autoderef.rs
@@ -0,0 +1,13 @@
+trait Foo {}
+
+impl Foo for i32 {}
+
+fn needs_foo(_: impl Foo) {}
+
+fn test(x: &Box<dyn Fn() -> i32>) {
+    needs_foo(x);
+    //~^ ERROR the trait bound
+    //~| HELP use parentheses to call this trait object
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/call-on-unimplemented-with-autoderef.stderr b/src/test/ui/suggestions/call-on-unimplemented-with-autoderef.stderr
new file mode 100644
index 0000000000000..90f44cce06e44
--- /dev/null
+++ b/src/test/ui/suggestions/call-on-unimplemented-with-autoderef.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the trait bound `&Box<dyn Fn() -> i32>: Foo` is not satisfied
+  --> $DIR/call-on-unimplemented-with-autoderef.rs:8:15
+   |
+LL |     needs_foo(x);
+   |     --------- ^ the trait `Foo` is not implemented for `&Box<dyn Fn() -> i32>`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `needs_foo`
+  --> $DIR/call-on-unimplemented-with-autoderef.rs:5:22
+   |
+LL | fn needs_foo(_: impl Foo) {}
+   |                      ^^^ required by this bound in `needs_foo`
+help: use parentheses to call this trait object
+   |
+LL |     needs_foo(x());
+   |                ++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/tools/miri/tests/pass/issues/issue-miri-2068.rs b/src/tools/miri/tests/pass/issues/issue-miri-2068.rs
index 7576ba78f607d..fe4078f77107b 100644
--- a/src/tools/miri/tests/pass/issues/issue-miri-2068.rs
+++ b/src/tools/miri/tests/pass/issues/issue-miri-2068.rs
@@ -1,5 +1,3 @@
-#![feature(pin_macro)]
-
 use core::future::Future;
 use core::pin::Pin;
 use core::task::{Context, Poll};
diff --git a/src/tools/miri/tests/pass/stacked-borrows/future-self-referential.rs b/src/tools/miri/tests/pass/stacked-borrows/future-self-referential.rs
index 3ba21552fd362..96fc0be344dbf 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/future-self-referential.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/future-self-referential.rs
@@ -1,5 +1,3 @@
-#![feature(pin_macro)]
-
 use std::future::*;
 use std::marker::PhantomPinned;
 use std::pin::*;
diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml
index 5f5ae3a65efa8..fff83a1d097b3 100644
--- a/src/tools/tidy/Cargo.toml
+++ b/src/tools/tidy/Cargo.toml
@@ -11,7 +11,6 @@ miropt-test-tools = { path = "../miropt-test-tools" }
 lazy_static = "1"
 walkdir = "2"
 ignore = "0.4.18"
-semver = "1.0.14"
 termcolor = "1.1.3"
 
 [[bin]]
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 1eb146989e4f8..40375f1306d62 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -69,4 +69,3 @@ pub mod ui_tests;
 pub mod unit_tests;
 pub mod unstable_book;
 pub mod walk;
-pub mod x_version;
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index 79441cda64c05..ea2886a3c2f8f 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -60,7 +60,7 @@ fn main() {
 
                 let handle = s.spawn(|| {
                     let mut flag = false;
-                    $p::check($($args, )* &mut flag);
+                    $p::check($($args),* , &mut flag);
                     if (flag) {
                         bad.store(true, Ordering::Relaxed);
                     }
@@ -113,8 +113,6 @@ fn main() {
         check!(alphabetical, &compiler_path);
         check!(alphabetical, &library_path);
 
-        check!(x_version, &root_path, &cargo);
-
         let collected = {
             drain_handles(&mut handles);
 
diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs
deleted file mode 100644
index 5dc6a0588c32b..0000000000000
--- a/src/tools/tidy/src/x_version.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-use semver::Version;
-use std::io::ErrorKind;
-use std::path::Path;
-use std::process::{Command, Stdio};
-
-pub fn check(root: &Path, cargo: &Path, bad: &mut bool) {
-    let result = Command::new("x").arg("--wrapper-version").stdout(Stdio::piped()).spawn();
-    // This runs the command inside a temporary directory.
-    // This allows us to compare output of result to see if `--wrapper-version` is not a recognized argument to x.
-    let temp_result = Command::new("x")
-        .arg("--wrapper-version")
-        .current_dir(std::env::temp_dir())
-        .stdout(Stdio::piped())
-        .spawn();
-
-    let (child, temp_child) = match (result, temp_result) {
-        (Ok(child), Ok(temp_child)) => (child, temp_child),
-        (Err(e), _) | (_, Err(e)) => match e.kind() {
-            ErrorKind::NotFound => return,
-            _ => return tidy_error!(bad, "failed to run `x`: {}", e),
-        },
-    };
-
-    let output = child.wait_with_output().unwrap();
-    let temp_output = temp_child.wait_with_output().unwrap();
-
-    if output != temp_output {
-        return tidy_error!(
-            bad,
-            "Current version of x does not support the `--wrapper-version` argument\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`"
-        );
-    }
-
-    if output.status.success() {
-        let version = String::from_utf8_lossy(&output.stdout);
-        let version = Version::parse(version.trim_end()).unwrap();
-
-        if let Some(expected) = get_x_wrapper_version(root, cargo) {
-            if version < expected {
-                return tidy_error!(
-                    bad,
-                    "Current version of x is {version}, but the latest version is {expected}\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`"
-                );
-            }
-        } else {
-            return tidy_error!(
-                bad,
-                "Unable to parse the latest version of `x` at `src/tools/x/Cargo.toml`"
-            );
-        }
-    } else {
-        return tidy_error!(bad, "failed to check version of `x`: {}", output.status);
-    }
-}
-
-// Parse latest version out of `x` Cargo.toml
-fn get_x_wrapper_version(root: &Path, cargo: &Path) -> Option<Version> {
-    let mut cmd = cargo_metadata::MetadataCommand::new();
-    cmd.cargo_path(cargo)
-        .manifest_path(root.join("src/tools/x/Cargo.toml"))
-        .no_deps()
-        .features(cargo_metadata::CargoOpt::AllFeatures);
-    let mut metadata = t!(cmd.exec());
-    metadata.packages.pop().map(|x| x.version)
-}
diff --git a/tests/ui/auto-traits/typeck-default-trait-impl-precedence.stderr b/tests/ui/auto-traits/typeck-default-trait-impl-precedence.stderr
index 9aae9013d1b04..bd7aaf6fb6dfc 100644
--- a/tests/ui/auto-traits/typeck-default-trait-impl-precedence.stderr
+++ b/tests/ui/auto-traits/typeck-default-trait-impl-precedence.stderr
@@ -4,7 +4,6 @@ error[E0277]: the trait bound `u32: Signed` is not satisfied
 LL |     is_defaulted::<&'static u32>();
    |                    ^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`
    |
-   = help: the trait `Signed` is implemented for `i32`
 note: required for `&'static u32` to implement `Defaulted`
   --> $DIR/typeck-default-trait-impl-precedence.rs:10:19
    |
@@ -17,6 +16,11 @@ note: required by a bound in `is_defaulted`
    |
 LL | fn is_defaulted<T:Defaulted>() { }
    |                   ^^^^^^^^^ required by this bound in `is_defaulted`
+help: consider removing the leading `&`-reference
+   |
+LL -     is_defaulted::<&'static u32>();
+LL +     is_defaulted::<u32>();
+   |
 
 error: aborting due to previous error
 
diff --git a/tests/ui/c-variadic/issue-86053-1.rs b/tests/ui/c-variadic/issue-86053-1.rs
index b30548e19f9ff..49d5c0390bc13 100644
--- a/tests/ui/c-variadic/issue-86053-1.rs
+++ b/tests/ui/c-variadic/issue-86053-1.rs
@@ -2,7 +2,7 @@
 // error-pattern:unexpected `self` parameter in function
 // error-pattern:`...` must be the last argument of a C-variadic function
 // error-pattern:cannot find type `F` in this scope
-// error-pattern:in type `&'a &'b usize`, reference has a longer lifetime than the data it references
+
 
 #![feature(c_variadic)]
 #![crate_type="lib"]
diff --git a/tests/ui/c-variadic/issue-86053-1.stderr b/tests/ui/c-variadic/issue-86053-1.stderr
index d1f13d52362da..5a02f4aa93a95 100644
--- a/tests/ui/c-variadic/issue-86053-1.stderr
+++ b/tests/ui/c-variadic/issue-86053-1.stderr
@@ -76,24 +76,6 @@ help: you might be missing a type parameter
 LL | fn ordering4 < 'a , 'b, F     > ( a :            ,   self , self ,   self ,
    |                       +++
 
-error[E0491]: in type `&'a &'b usize`, reference has a longer lifetime than the data it references
-  --> $DIR/issue-86053-1.rs:11:52
-   |
-LL |     self , ... ,   self ,   self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
-   |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: the pointer is valid for the lifetime `'a` as defined here
-  --> $DIR/issue-86053-1.rs:10:16
-   |
-LL | fn ordering4 < 'a , 'b     > ( a :            ,   self , self ,   self ,
-   |                ^^
-note: but the referenced data is only valid for the lifetime `'b` as defined here
-  --> $DIR/issue-86053-1.rs:10:21
-   |
-LL | fn ordering4 < 'a , 'b     > ( a :            ,   self , self ,   self ,
-   |                     ^^
-
-error: aborting due to 12 previous errors
+error: aborting due to 11 previous errors
 
-Some errors have detailed explanations: E0412, E0491.
-For more information about an error, try `rustc --explain E0412`.
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
index 0af5493f81675..ea6f5f6927659 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
@@ -17,7 +17,7 @@ LL |     Condition<{ LHS <= RHS }>: True
    = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-72787.rs:25:25
+  --> $DIR/issue-72787.rs:23:25
    |
 LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    |                         ^ cannot perform const operation using `I`
@@ -26,7 +26,7 @@ LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-72787.rs:25:36
+  --> $DIR/issue-72787.rs:23:36
    |
 LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    |                                    ^ cannot perform const operation using `J`
@@ -34,42 +34,5 @@ LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    = help: const parameters may only be used as standalone arguments, i.e. `J`
    = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
-error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual<I, 8>: True`
-  --> $DIR/issue-72787.rs:21:26
-   |
-LL |     IsLessOrEqual<I, 8>: True,
-   |                          ^^^^
-   |
-note: multiple `impl`s or `where` clauses satisfying `IsLessOrEqual<I, 8>: True` found
-  --> $DIR/issue-72787.rs:10:1
-   |
-LL | impl<const LHS: u32, const RHS: u32> True for IsLessOrEqual<LHS, RHS> where
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-...
-LL |     IsLessOrEqual<I, 8>: True,
-   |                          ^^^^
-...
-LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
-   |                                          ^^^^
-
-error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual<I, 8>: True`
-  --> $DIR/issue-72787.rs:21:26
-   |
-LL |     IsLessOrEqual<I, 8>: True,
-   |                          ^^^^
-   |
-note: multiple `impl`s or `where` clauses satisfying `IsLessOrEqual<I, 8>: True` found
-  --> $DIR/issue-72787.rs:10:1
-   |
-LL | impl<const LHS: u32, const RHS: u32> True for IsLessOrEqual<LHS, RHS> where
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-...
-LL |     IsLessOrEqual<I, 8>: True,
-   |                          ^^^^
-...
-LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
-   |                                          ^^^^
-
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72787.rs b/tests/ui/const-generics/generic_const_exprs/issue-72787.rs
index c651bf1c8de9d..657fec2e9cb70 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-72787.rs
+++ b/tests/ui/const-generics/generic_const_exprs/issue-72787.rs
@@ -19,8 +19,6 @@ struct S<const I: u32, const J: u32>;
 impl<const I: u32, const J: u32> S<I, J>
 where
     IsLessOrEqual<I, 8>: True,
-//[min]~^ Error type annotations needed
-//[min]~| Error type annotations needed
     IsLessOrEqual<J, 8>: True,
     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
 //[min]~^ Error generic parameters may not be used in const operations
diff --git a/tests/ui/error-codes/E0311.fixed b/tests/ui/error-codes/E0311.fixed
new file mode 100644
index 0000000000000..4410a4d707af4
--- /dev/null
+++ b/tests/ui/error-codes/E0311.fixed
@@ -0,0 +1,13 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() {
+    with_restriction::<T>(x) //~ ERROR E0311
+}
+
+fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
+    x
+}
+
+fn main() {}
diff --git a/tests/ui/error-codes/E0311.rs b/tests/ui/error-codes/E0311.rs
index 566b518b4331d..99e454f4d75c2 100644
--- a/tests/ui/error-codes/E0311.rs
+++ b/tests/ui/error-codes/E0311.rs
@@ -1,3 +1,7 @@
+// run-rustfix
+
+#![allow(warnings)]
+
 fn no_restriction<T>(x: &()) -> &() {
     with_restriction::<T>(x) //~ ERROR E0311
 }
diff --git a/tests/ui/error-codes/E0311.stderr b/tests/ui/error-codes/E0311.stderr
index 9873b5ae6ff13..b0e6dd1e2727c 100644
--- a/tests/ui/error-codes/E0311.stderr
+++ b/tests/ui/error-codes/E0311.stderr
@@ -1,23 +1,23 @@
 error[E0311]: the parameter type `T` may not live long enough
-  --> $DIR/E0311.rs:2:5
+  --> $DIR/E0311.rs:6:5
    |
 LL |     with_restriction::<T>(x)
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
 note: the parameter type `T` must be valid for the anonymous lifetime defined here...
-  --> $DIR/E0311.rs:1:25
+  --> $DIR/E0311.rs:5:25
    |
 LL | fn no_restriction<T>(x: &()) -> &() {
    |                         ^^^
 note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/E0311.rs:2:5
+  --> $DIR/E0311.rs:6:5
    |
 LL |     with_restriction::<T>(x)
    |     ^^^^^^^^^^^^^^^^^^^^^
 help: consider adding an explicit lifetime bound...
    |
-LL | fn no_restriction<'a, T: 'a>(x: &()) -> &() {
-   |                   +++  ++++
+LL | fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() {
+   |                   +++  ++++      ++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/impl-trait/in-trait/issue-102140.stderr b/tests/ui/impl-trait/in-trait/issue-102140.stderr
index 08602185f50ca..18bb63745d7a5 100644
--- a/tests/ui/impl-trait/in-trait/issue-102140.stderr
+++ b/tests/ui/impl-trait/in-trait/issue-102140.stderr
@@ -2,11 +2,15 @@ error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
   --> $DIR/issue-102140.rs:23:22
    |
 LL |         MyTrait::foo(&self)
-   |         ------------ -^^^^
-   |         |            |
-   |         |            the trait `MyTrait` is not implemented for `&dyn MyTrait`
-   |         |            help: consider removing the leading `&`-reference
+   |         ------------ ^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
+   |         |
    |         required by a bound introduced by this call
+   |
+help: consider removing the leading `&`-reference
+   |
+LL -         MyTrait::foo(&self)
+LL +         MyTrait::foo(self)
+   |
 
 error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
   --> $DIR/issue-102140.rs:23:9
diff --git a/tests/ui/kindck/kindck-copy.stderr b/tests/ui/kindck/kindck-copy.stderr
index 9af89159a8cfc..aee2aa98a60c2 100644
--- a/tests/ui/kindck/kindck-copy.stderr
+++ b/tests/ui/kindck/kindck-copy.stderr
@@ -4,12 +4,16 @@ error[E0277]: the trait bound `&'static mut isize: Copy` is not satisfied
 LL |     assert_copy::<&'static mut isize>();
    |                   ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'static mut isize`
    |
-   = help: the trait `Copy` is implemented for `isize`
 note: required by a bound in `assert_copy`
   --> $DIR/kindck-copy.rs:5:18
    |
 LL | fn assert_copy<T:Copy>() { }
    |                  ^^^^ required by this bound in `assert_copy`
+help: consider removing the leading `&`-reference
+   |
+LL -     assert_copy::<&'static mut isize>();
+LL +     assert_copy::<isize>();
+   |
 
 error[E0277]: the trait bound `&'a mut isize: Copy` is not satisfied
   --> $DIR/kindck-copy.rs:28:19
@@ -17,12 +21,16 @@ error[E0277]: the trait bound `&'a mut isize: Copy` is not satisfied
 LL |     assert_copy::<&'a mut isize>();
    |                   ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'a mut isize`
    |
-   = help: the trait `Copy` is implemented for `isize`
 note: required by a bound in `assert_copy`
   --> $DIR/kindck-copy.rs:5:18
    |
 LL | fn assert_copy<T:Copy>() { }
    |                  ^^^^ required by this bound in `assert_copy`
+help: consider removing the leading `&`-reference
+   |
+LL -     assert_copy::<&'a mut isize>();
+LL +     assert_copy::<isize>();
+   |
 
 error[E0277]: the trait bound `Box<isize>: Copy` is not satisfied
   --> $DIR/kindck-copy.rs:31:19
diff --git a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed
new file mode 100644
index 0000000000000..f977f0bd3a8c2
--- /dev/null
+++ b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed
@@ -0,0 +1,13 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() {
+    with_restriction::<T>(x) //~ ERROR the parameter type `T` may not live long enough
+}
+
+fn with_restriction<'b, T: 'b>(x: &'b ()) -> &'b () {
+    x
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs
index 645bc7db0ddac..d6ce112ec93d4 100644
--- a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs
+++ b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs
@@ -1,3 +1,7 @@
+// run-rustfix
+
+#![allow(warnings)]
+
 fn no_restriction<T>(x: &()) -> &() {
     with_restriction::<T>(x) //~ ERROR the parameter type `T` may not live long enough
 }
diff --git a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr
index 31fd8a4d633e9..2d58d3a02f35e 100644
--- a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr
+++ b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr
@@ -1,23 +1,23 @@
 error[E0311]: the parameter type `T` may not live long enough
-  --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:2:5
+  --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:6:5
    |
 LL |     with_restriction::<T>(x)
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
 note: the parameter type `T` must be valid for the anonymous lifetime defined here...
-  --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:1:25
+  --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:5:25
    |
 LL | fn no_restriction<T>(x: &()) -> &() {
    |                         ^^^
 note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:2:5
+  --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:6:5
    |
 LL |     with_restriction::<T>(x)
    |     ^^^^^^^^^^^^^^^^^^^^^
 help: consider adding an explicit lifetime bound...
    |
-LL | fn no_restriction<'a, T: 'a>(x: &()) -> &() {
-   |                   +++  ++++
+LL | fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() {
+   |                   +++  ++++      ++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/not-panic/not-panic-safe-4.stderr b/tests/ui/not-panic/not-panic-safe-4.stderr
index fc1c594d0d422..9428c125651ec 100644
--- a/tests/ui/not-panic/not-panic-safe-4.stderr
+++ b/tests/ui/not-panic/not-panic-safe-4.stderr
@@ -12,6 +12,11 @@ note: required by a bound in `assert`
    |
 LL | fn assert<T: UnwindSafe + ?Sized>() {}
    |              ^^^^^^^^^^ required by this bound in `assert`
+help: consider removing the leading `&`-reference
+   |
+LL -     assert::<&RefCell<i32>>();
+LL +     assert::<RefCell<i32>>();
+   |
 
 error[E0277]: the type `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
   --> $DIR/not-panic-safe-4.rs:9:14
@@ -28,6 +33,11 @@ note: required by a bound in `assert`
    |
 LL | fn assert<T: UnwindSafe + ?Sized>() {}
    |              ^^^^^^^^^^ required by this bound in `assert`
+help: consider removing the leading `&`-reference
+   |
+LL -     assert::<&RefCell<i32>>();
+LL +     assert::<RefCell<i32>>();
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/not-panic/not-panic-safe.rs b/tests/ui/not-panic/not-panic-safe.rs
index 4165c5dc13aaa..1b3c6482ce94f 100644
--- a/tests/ui/not-panic/not-panic-safe.rs
+++ b/tests/ui/not-panic/not-panic-safe.rs
@@ -5,6 +5,6 @@ use std::panic::UnwindSafe;
 fn assert<T: UnwindSafe + ?Sized>() {}
 
 fn main() {
-    assert::<&mut i32>();
-    //~^ ERROR the type `&mut i32` may not be safely transferred across an unwind boundary
+    assert::<&mut &mut &i32>();
+    //~^ ERROR the type `&mut &mut &i32` may not be safely transferred across an unwind boundary
 }
diff --git a/tests/ui/not-panic/not-panic-safe.stderr b/tests/ui/not-panic/not-panic-safe.stderr
index 2cd51a439988d..37a6aee390669 100644
--- a/tests/ui/not-panic/not-panic-safe.stderr
+++ b/tests/ui/not-panic/not-panic-safe.stderr
@@ -1,19 +1,21 @@
-error[E0277]: the type `&mut i32` may not be safely transferred across an unwind boundary
+error[E0277]: the type `&mut &mut &i32` may not be safely transferred across an unwind boundary
   --> $DIR/not-panic-safe.rs:8:14
    |
-LL |     assert::<&mut i32>();
-   |              -^^^^^^^
-   |              |
-   |              `&mut i32` may not be safely transferred across an unwind boundary
-   |              help: consider removing the leading `&`-reference
+LL |     assert::<&mut &mut &i32>();
+   |              ^^^^^^^^^^^^^^ `&mut &mut &i32` may not be safely transferred across an unwind boundary
    |
-   = help: the trait `UnwindSafe` is not implemented for `&mut i32`
-   = note: `UnwindSafe` is implemented for `&i32`, but not for `&mut i32`
+   = help: the trait `UnwindSafe` is not implemented for `&mut &mut &i32`
+   = note: `UnwindSafe` is implemented for `&&mut &i32`, but not for `&mut &mut &i32`
 note: required by a bound in `assert`
   --> $DIR/not-panic-safe.rs:5:14
    |
 LL | fn assert<T: UnwindSafe + ?Sized>() {}
    |              ^^^^^^^^^^ required by this bound in `assert`
+help: consider removing 2 leading `&`-references
+   |
+LL -     assert::<&mut &mut &i32>();
+LL +     assert::<&i32>();
+   |
 
 error: aborting due to previous error
 
diff --git a/tests/ui/pin-macro/cant_access_internals.rs b/tests/ui/pin-macro/cant_access_internals.rs
index 120d08894f8f7..5826a18b5718b 100644
--- a/tests/ui/pin-macro/cant_access_internals.rs
+++ b/tests/ui/pin-macro/cant_access_internals.rs
@@ -1,5 +1,4 @@
 // edition:2018
-#![feature(pin_macro)]
 
 use core::{
     marker::PhantomPinned,
diff --git a/tests/ui/pin-macro/cant_access_internals.stderr b/tests/ui/pin-macro/cant_access_internals.stderr
index 060c9c48c21c8..d43027657f046 100644
--- a/tests/ui/pin-macro/cant_access_internals.stderr
+++ b/tests/ui/pin-macro/cant_access_internals.stderr
@@ -1,5 +1,5 @@
 error[E0658]: use of unstable library feature 'unsafe_pin_internals'
-  --> $DIR/cant_access_internals.rs:12:15
+  --> $DIR/cant_access_internals.rs:11:15
    |
 LL |     mem::take(phantom_pinned.pointer);
    |               ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs
index ca2b6cf759376..59774bc753dc9 100644
--- a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs
+++ b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs
@@ -1,5 +1,4 @@
 // edition:2018
-#![feature(pin_macro)]
 
 use core::{
     convert::identity,
diff --git a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr
index fc1be052fb791..4ecc6370d3caa 100644
--- a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr
+++ b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr
@@ -1,5 +1,5 @@
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/lifetime_errors_on_promotion_misusage.rs:12:35
+  --> $DIR/lifetime_errors_on_promotion_misusage.rs:11:35
    |
 LL |     let phantom_pinned = identity(pin!(PhantomPinned));
    |                                   ^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
@@ -13,7 +13,7 @@ LL |     stuff(phantom_pinned)
    = note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/lifetime_errors_on_promotion_misusage.rs:19:30
+  --> $DIR/lifetime_errors_on_promotion_misusage.rs:18:30
    |
 LL |     let phantom_pinned = {
    |         -------------- borrow later stored here
diff --git a/tests/ui/suggestions/lifetimes/issue-105544.fixed b/tests/ui/suggestions/lifetimes/issue-105544.fixed
new file mode 100644
index 0000000000000..47087eb474972
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/issue-105544.fixed
@@ -0,0 +1,45 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+fn foo<'a>(d: impl Sized + 'a, p: &'a mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `impl Sized` may not live long enough
+    //~| NOTE ...so that the type `impl Sized` will meet its required lifetime bounds
+}
+
+fn foo1<'b>(d: impl Sized + 'b, p: &'b mut ()) -> impl Sized + '_ {
+//~^ HELP consider adding an explicit lifetime bound...
+    (d, p) //~ NOTE ...so that the type `impl Sized` will meet its required lifetime bounds
+    //~^ ERROR the parameter type `impl Sized` may not live long enough
+}
+
+fn foo2<'b, 'a>(d: impl Sized + 'a + 'b, p: &'b mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized + 'a` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `impl Sized + 'a` may not live long enough
+    //~| NOTE ...so that the type `impl Sized + 'a` will meet its required lifetime bounds
+}
+
+fn bar<'a, T : Sized + 'a>(d: T, p: &'a mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `T` may not live long enough
+    //~| NOTE ...so that the type `T` will meet its required lifetime bounds
+}
+
+fn bar1<'b, T : Sized + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ {
+//~^ HELP consider adding an explicit lifetime bound...
+    (d, p) //~ NOTE ...so that the type `T` will meet its required lifetime bounds
+    //~^ ERROR the parameter type `T` may not live long enough
+}
+
+fn bar2<'b, 'a, T : Sized + 'a + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `T` may not live long enough
+    //~| NOTE ...so that the type `T` will meet its required lifetime bounds
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/lifetimes/issue-105544.rs b/tests/ui/suggestions/lifetimes/issue-105544.rs
new file mode 100644
index 0000000000000..bd3bc1ef9bd2d
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/issue-105544.rs
@@ -0,0 +1,45 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+fn foo(d: impl Sized, p: &mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `impl Sized` may not live long enough
+    //~| NOTE ...so that the type `impl Sized` will meet its required lifetime bounds
+}
+
+fn foo1<'b>(d: impl Sized, p: &'b mut ()) -> impl Sized + '_ {
+//~^ HELP consider adding an explicit lifetime bound...
+    (d, p) //~ NOTE ...so that the type `impl Sized` will meet its required lifetime bounds
+    //~^ ERROR the parameter type `impl Sized` may not live long enough
+}
+
+fn foo2<'a>(d: impl Sized + 'a, p: &mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized + 'a` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `impl Sized + 'a` may not live long enough
+    //~| NOTE ...so that the type `impl Sized + 'a` will meet its required lifetime bounds
+}
+
+fn bar<T : Sized>(d: T, p: & mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `T` may not live long enough
+    //~| NOTE ...so that the type `T` will meet its required lifetime bounds
+}
+
+fn bar1<'b, T : Sized>(d: T, p: &'b mut ()) -> impl Sized + '_ {
+//~^ HELP consider adding an explicit lifetime bound...
+    (d, p) //~ NOTE ...so that the type `T` will meet its required lifetime bounds
+    //~^ ERROR the parameter type `T` may not live long enough
+}
+
+fn bar2<'a, T : Sized + 'a>(d: T, p: &mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `T` may not live long enough
+    //~| NOTE ...so that the type `T` will meet its required lifetime bounds
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/lifetimes/issue-105544.stderr b/tests/ui/suggestions/lifetimes/issue-105544.stderr
new file mode 100644
index 0000000000000..08fe21b11b501
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/issue-105544.stderr
@@ -0,0 +1,110 @@
+error[E0311]: the parameter type `impl Sized` may not live long enough
+  --> $DIR/issue-105544.rs:7:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+   |
+note: the parameter type `impl Sized` must be valid for the anonymous lifetime defined here...
+  --> $DIR/issue-105544.rs:5:26
+   |
+LL | fn foo(d: impl Sized, p: &mut ()) -> impl Sized + '_ {
+   |                          ^^^^^^^
+note: ...so that the type `impl Sized` will meet its required lifetime bounds
+  --> $DIR/issue-105544.rs:7:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+help: consider adding an explicit lifetime bound...
+   |
+LL | fn foo<'a>(d: impl Sized + 'a, p: &'a mut ()) -> impl Sized + '_ {
+   |       ++++               ++++      ++
+
+error[E0309]: the parameter type `impl Sized` may not live long enough
+  --> $DIR/issue-105544.rs:14:5
+   |
+LL |     (d, p)
+   |     ^^^^^^ ...so that the type `impl Sized` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound...
+   |
+LL | fn foo1<'b>(d: impl Sized + 'b, p: &'b mut ()) -> impl Sized + '_ {
+   |                           ++++
+
+error[E0311]: the parameter type `impl Sized + 'a` may not live long enough
+  --> $DIR/issue-105544.rs:20:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+   |
+note: the parameter type `impl Sized + 'a` must be valid for the anonymous lifetime defined here...
+  --> $DIR/issue-105544.rs:18:36
+   |
+LL | fn foo2<'a>(d: impl Sized + 'a, p: &mut ()) -> impl Sized + '_ {
+   |                                    ^^^^^^^
+note: ...so that the type `impl Sized + 'a` will meet its required lifetime bounds
+  --> $DIR/issue-105544.rs:20:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+help: consider adding an explicit lifetime bound...
+   |
+LL | fn foo2<'b, 'a>(d: impl Sized + 'a + 'b, p: &'b mut ()) -> impl Sized + '_ {
+   |         +++                        ++++      ++
+
+error[E0311]: the parameter type `T` may not live long enough
+  --> $DIR/issue-105544.rs:27:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+   |
+note: the parameter type `T` must be valid for the anonymous lifetime defined here...
+  --> $DIR/issue-105544.rs:25:28
+   |
+LL | fn bar<T : Sized>(d: T, p: & mut ()) -> impl Sized + '_ {
+   |                            ^^^^^^^^
+note: ...so that the type `T` will meet its required lifetime bounds
+  --> $DIR/issue-105544.rs:27:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+help: consider adding an explicit lifetime bound...
+   |
+LL | fn bar<'a, T : Sized + 'a>(d: T, p: &'a mut ()) -> impl Sized + '_ {
+   |        +++           ++++            ++
+
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/issue-105544.rs:34:5
+   |
+LL |     (d, p)
+   |     ^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound...
+   |
+LL | fn bar1<'b, T : Sized + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ {
+   |                       ++++
+
+error[E0311]: the parameter type `T` may not live long enough
+  --> $DIR/issue-105544.rs:40:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+   |
+note: the parameter type `T` must be valid for the anonymous lifetime defined here...
+  --> $DIR/issue-105544.rs:38:38
+   |
+LL | fn bar2<'a, T : Sized + 'a>(d: T, p: &mut ()) -> impl Sized + '_ {
+   |                                      ^^^^^^^
+note: ...so that the type `T` will meet its required lifetime bounds
+  --> $DIR/issue-105544.rs:40:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+help: consider adding an explicit lifetime bound...
+   |
+LL | fn bar2<'b, 'a, T : Sized + 'a + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ {
+   |         +++                    ++++            ++
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0309, E0311.
+For more information about an error, try `rustc --explain E0309`.
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.fixed b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.fixed
new file mode 100644
index 0000000000000..4013d98c3cfe7
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.fixed
@@ -0,0 +1,29 @@
+// Regression test for #81650
+// run-rustfix
+
+#![allow(warnings)]
+
+struct Foo<'a> {
+    x: &'a mut &'a i32,
+}
+
+impl<'a> Foo<'a> {
+    fn bar<F, T>(&self, f: F)
+    where
+        F: FnOnce(&Foo<'a>) -> T,
+        F: 'a,
+    {}
+}
+
+trait Test {
+    fn test(&self);
+}
+
+fn func<'a, T: Test + 'a>(foo: &'a Foo<'a>, t: T) {
+    foo.bar(move |_| {
+    //~^ ERROR the parameter type `T` may not live long enough
+        t.test();
+    });
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs
index c6802ac6cc704..4096d95e5fd7f 100644
--- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs
@@ -1,4 +1,7 @@
 // Regression test for #81650
+// run-rustfix
+
+#![allow(warnings)]
 
 struct Foo<'a> {
     x: &'a mut &'a i32,
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr
index 872263fd7311b..936d87f796824 100644
--- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr
@@ -1,5 +1,5 @@
 error[E0311]: the parameter type `T` may not live long enough
-  --> $DIR/missing-lifetimes-in-signature-2.rs:20:5
+  --> $DIR/missing-lifetimes-in-signature-2.rs:23:5
    |
 LL | /     foo.bar(move |_| {
 LL | |
@@ -8,12 +8,12 @@ LL | |     });
    | |______^
    |
 note: the parameter type `T` must be valid for the anonymous lifetime defined here...
-  --> $DIR/missing-lifetimes-in-signature-2.rs:19:24
+  --> $DIR/missing-lifetimes-in-signature-2.rs:22:24
    |
 LL | fn func<T: Test>(foo: &Foo, t: T) {
    |                        ^^^
 note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/missing-lifetimes-in-signature-2.rs:20:5
+  --> $DIR/missing-lifetimes-in-signature-2.rs:23:5
    |
 LL | /     foo.bar(move |_| {
 LL | |
@@ -22,8 +22,8 @@ LL | |     });
    | |______^
 help: consider adding an explicit lifetime bound...
    |
-LL | fn func<'a, T: Test + 'a>(foo: &Foo, t: T) {
-   |         +++         ++++
+LL | fn func<'a, T: Test + 'a>(foo: &'a Foo<'a>, t: T) {
+   |         +++         ++++        ++    ++++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
index fa758bf05df5a..c5c3f7b468c8b 100644
--- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
@@ -47,7 +47,7 @@ LL | |     }
    | |_____^
 help: consider adding an explicit lifetime bound...
    |
-LL ~ fn bar<'a, G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+LL ~ fn bar<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_
 LL | where
 LL ~     G: Get<T> + 'a,
    |
@@ -76,8 +76,8 @@ LL | |     }
    | |_____^
 help: consider adding an explicit lifetime bound...
    |
-LL | fn qux<'b, 'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
-   |        +++           ++++
+LL | fn qux<'b, 'a, G: 'a + 'b, T>(g: G, dest: &'b mut T) -> impl FnOnce() + '_
+   |        +++           ++++                  ++
 
 error[E0311]: the parameter type `G` may not live long enough
   --> $DIR/missing-lifetimes-in-signature.rs:61:9
@@ -103,8 +103,8 @@ LL | |         }
    | |_________^
 help: consider adding an explicit lifetime bound...
    |
-LL |     fn qux<'c, 'b, G: Get<T> + 'b + 'c, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
-   |            +++                    ++++
+LL |     fn qux<'c, 'b, G: Get<T> + 'b + 'c, T>(g: G, dest: &'c mut T) -> impl FnOnce() + '_ {
+   |            +++                    ++++                  ++
 
 error[E0311]: the parameter type `G` may not live long enough
   --> $DIR/missing-lifetimes-in-signature.rs:73:5
@@ -132,8 +132,8 @@ LL | |     }
    | |_____^
 help: consider adding an explicit lifetime bound...
    |
-LL | fn bat<'b, 'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
-   |        +++           ++++
+LL | fn bat<'b, 'a, G: 'a + 'b, T>(g: G, dest: &'b mut T) -> impl FnOnce() + '_ + 'a
+   |        +++           ++++                  ++
 
 error[E0621]: explicit lifetime required in the type of `dest`
   --> $DIR/missing-lifetimes-in-signature.rs:73:5
diff --git a/tests/ui/suggestions/suggest-remove-refs-1.stderr b/tests/ui/suggestions/suggest-remove-refs-1.stderr
index 1a843f3f5097b..387770535f689 100644
--- a/tests/ui/suggestions/suggest-remove-refs-1.stderr
+++ b/tests/ui/suggestions/suggest-remove-refs-1.stderr
@@ -2,13 +2,15 @@ error[E0277]: `&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
   --> $DIR/suggest-remove-refs-1.rs:6:19
    |
 LL |     for (i, _) in &v.iter().enumerate() {
-   |                   -^^^^^^^^^^^^^^^^^^^^
-   |                   |
-   |                   `&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
-   |                   help: consider removing the leading `&`-reference
+   |                   ^^^^^^^^^^^^^^^^^^^^^ `&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `&Enumerate<std::slice::Iter<'_, {integer}>>`
    = note: required for `&Enumerate<std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
+help: consider removing the leading `&`-reference
+   |
+LL -     for (i, _) in &v.iter().enumerate() {
+LL +     for (i, _) in v.iter().enumerate() {
+   |
 
 error: aborting due to previous error
 
diff --git a/tests/ui/suggestions/suggest-remove-refs-2.stderr b/tests/ui/suggestions/suggest-remove-refs-2.stderr
index f39361d529fbf..1632b2abb2f87 100644
--- a/tests/ui/suggestions/suggest-remove-refs-2.stderr
+++ b/tests/ui/suggestions/suggest-remove-refs-2.stderr
@@ -2,13 +2,15 @@ error[E0277]: `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterat
   --> $DIR/suggest-remove-refs-2.rs:6:19
    |
 LL |     for (i, _) in & & & & &v.iter().enumerate() {
-   |                   ---------^^^^^^^^^^^^^^^^^^^^
-   |                   |
-   |                   `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
-   |                   help: consider removing 5 leading `&`-references
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
    = note: required for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
+help: consider removing 5 leading `&`-references
+   |
+LL -     for (i, _) in & & & & &v.iter().enumerate() {
+LL +     for (i, _) in v.iter().enumerate() {
+   |
 
 error: aborting due to previous error
 
diff --git a/tests/ui/suggestions/suggest-remove-refs-3.stderr b/tests/ui/suggestions/suggest-remove-refs-3.stderr
index 31cca323d0e42..7bf421a7729df 100644
--- a/tests/ui/suggestions/suggest-remove-refs-3.stderr
+++ b/tests/ui/suggestions/suggest-remove-refs-3.stderr
@@ -1,18 +1,20 @@
 error[E0277]: `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
   --> $DIR/suggest-remove-refs-3.rs:6:19
    |
-LL |        for (i, _) in & & &
-   |  ____________________^
-   | | ___________________|
-   | ||
-LL | ||         & &v
-   | ||___________- help: consider removing 5 leading `&`-references
-LL | |          .iter()
-LL | |          .enumerate() {
-   | |_____________________^ `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
+LL |       for (i, _) in & & &
+   |  ___________________^
+LL | |         & &v
+LL | |         .iter()
+LL | |         .enumerate() {
+   | |____________________^ `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
    = note: required for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
+help: consider removing 5 leading `&`-references
+   |
+LL -     for (i, _) in & & &
+LL +     for (i, _) in v
+   |
 
 error: aborting due to previous error
 
diff --git a/tests/ui/suggestions/suggest-remove-refs-4.fixed b/tests/ui/suggestions/suggest-remove-refs-4.fixed
new file mode 100644
index 0000000000000..dd63d21597243
--- /dev/null
+++ b/tests/ui/suggestions/suggest-remove-refs-4.fixed
@@ -0,0 +1,5 @@
+// run-rustfix
+fn main() {
+    let foo = [1,2,3].iter();
+    for _i in foo {} //~ ERROR E0277
+}
diff --git a/tests/ui/suggestions/suggest-remove-refs-4.rs b/tests/ui/suggestions/suggest-remove-refs-4.rs
new file mode 100644
index 0000000000000..3c3d9b1b3f981
--- /dev/null
+++ b/tests/ui/suggestions/suggest-remove-refs-4.rs
@@ -0,0 +1,5 @@
+// run-rustfix
+fn main() {
+    let foo = &[1,2,3].iter();
+    for _i in &foo {} //~ ERROR E0277
+}
diff --git a/tests/ui/suggestions/suggest-remove-refs-4.stderr b/tests/ui/suggestions/suggest-remove-refs-4.stderr
new file mode 100644
index 0000000000000..e4ad17e06716f
--- /dev/null
+++ b/tests/ui/suggestions/suggest-remove-refs-4.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `&&std::slice::Iter<'_, {integer}>` is not an iterator
+  --> $DIR/suggest-remove-refs-4.rs:4:15
+   |
+LL |     for _i in &foo {}
+   |               ^^^^ `&&std::slice::Iter<'_, {integer}>` is not an iterator
+   |
+   = help: the trait `Iterator` is not implemented for `&&std::slice::Iter<'_, {integer}>`
+   = note: required for `&&std::slice::Iter<'_, {integer}>` to implement `IntoIterator`
+help: consider removing 2 leading `&`-references
+   |
+LL ~     let foo = [1,2,3].iter();
+LL ~     for _i in foo {}
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/suggestions/suggest-remove-refs-5.fixed b/tests/ui/suggestions/suggest-remove-refs-5.fixed
new file mode 100644
index 0000000000000..9f59f9c199a33
--- /dev/null
+++ b/tests/ui/suggestions/suggest-remove-refs-5.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+fn main() {
+    let v = &mut Vec::<i32>::new();
+    for _ in v {} //~ ERROR E0277
+
+    let v = &mut [1u8];
+    for _ in v {} //~ ERROR E0277
+}
diff --git a/tests/ui/suggestions/suggest-remove-refs-5.rs b/tests/ui/suggestions/suggest-remove-refs-5.rs
new file mode 100644
index 0000000000000..d56aa0c9ca479
--- /dev/null
+++ b/tests/ui/suggestions/suggest-remove-refs-5.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+fn main() {
+    let v = &mut &mut Vec::<i32>::new();
+    for _ in &mut &mut v {} //~ ERROR E0277
+
+    let v = &mut &mut [1u8];
+    for _ in &mut v {} //~ ERROR E0277
+}
diff --git a/tests/ui/suggestions/suggest-remove-refs-5.stderr b/tests/ui/suggestions/suggest-remove-refs-5.stderr
new file mode 100644
index 0000000000000..7de84d6122b58
--- /dev/null
+++ b/tests/ui/suggestions/suggest-remove-refs-5.stderr
@@ -0,0 +1,37 @@
+error[E0277]: `Vec<i32>` is not an iterator
+  --> $DIR/suggest-remove-refs-5.rs:4:14
+   |
+LL |     for _ in &mut &mut v {}
+   |              ^^^^^^^^^^^ `Vec<i32>` is not an iterator; try calling `.into_iter()` or `.iter()`
+   |
+   = help: the trait `Iterator` is not implemented for `Vec<i32>`
+   = note: required for `&mut Vec<i32>` to implement `Iterator`
+   = note: 3 redundant requirements hidden
+   = note: required for `&mut &mut &mut &mut Vec<i32>` to implement `Iterator`
+   = note: required for `&mut &mut &mut &mut Vec<i32>` to implement `IntoIterator`
+help: consider removing 3 leading `&`-references
+   |
+LL ~     let v = &mut Vec::<i32>::new();
+LL ~     for _ in v {}
+   |
+
+error[E0277]: `[u8; 1]` is not an iterator
+  --> $DIR/suggest-remove-refs-5.rs:7:14
+   |
+LL |     for _ in &mut v {}
+   |              ^^^^^^ `[u8; 1]` is not an iterator; try calling `.into_iter()` or `.iter()`
+   |
+   = help: the trait `Iterator` is not implemented for `[u8; 1]`
+   = note: required for `&mut [u8; 1]` to implement `Iterator`
+   = note: 2 redundant requirements hidden
+   = note: required for `&mut &mut &mut [u8; 1]` to implement `Iterator`
+   = note: required for `&mut &mut &mut [u8; 1]` to implement `IntoIterator`
+help: consider removing 2 leading `&`-references
+   |
+LL ~     let v = &mut [1u8];
+LL ~     for _ in v {}
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/ignore-err-impls.rs b/tests/ui/traits/ignore-err-impls.rs
new file mode 100644
index 0000000000000..67e880b006a7f
--- /dev/null
+++ b/tests/ui/traits/ignore-err-impls.rs
@@ -0,0 +1,9 @@
+pub struct S;
+
+trait Generic<T> {}
+
+impl<'a, T> Generic<&'a T> for S {}
+impl Generic<Type> for S {}
+//~^ ERROR cannot find type `Type` in this scope
+
+fn main() {}
diff --git a/tests/ui/traits/ignore-err-impls.stderr b/tests/ui/traits/ignore-err-impls.stderr
new file mode 100644
index 0000000000000..1390106a29125
--- /dev/null
+++ b/tests/ui/traits/ignore-err-impls.stderr
@@ -0,0 +1,11 @@
+error[E0412]: cannot find type `Type` in this scope
+  --> $DIR/ignore-err-impls.rs:6:14
+   |
+LL | impl Generic<Type> for S {}
+   |     -        ^^^^ not found in this scope
+   |     |
+   |     help: you might be missing a type parameter: `<Type>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/typeck/issue-57404.stderr b/tests/ui/typeck/issue-57404.stderr
index 5065ac32ad2b0..a631dbb39fb8f 100644
--- a/tests/ui/typeck/issue-57404.stderr
+++ b/tests/ui/typeck/issue-57404.stderr
@@ -2,14 +2,17 @@ error[E0277]: `&mut ()` is not a tuple
   --> $DIR/issue-57404.rs:6:41
    |
 LL |     handlers.unwrap().as_mut().call_mut(&mut ());
-   |                                -------- -^^^^^^
-   |                                |        |
-   |                                |        the trait `Tuple` is not implemented for `&mut ()`
-   |                                |        help: consider removing the leading `&`-reference
+   |                                -------- ^^^^^^^ the trait `Tuple` is not implemented for `&mut ()`
+   |                                |
    |                                required by a bound introduced by this call
    |
 note: required by a bound in `call_mut`
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
+help: consider removing the leading `&`-reference
+   |
+LL -     handlers.unwrap().as_mut().call_mut(&mut ());
+LL +     handlers.unwrap().as_mut().call_mut(());
+   |
 
 error: aborting due to previous error
 
diff --git a/tests/ui/where-clauses/ignore-err-clauses.rs b/tests/ui/where-clauses/ignore-err-clauses.rs
new file mode 100644
index 0000000000000..c76f0e1a8b2b5
--- /dev/null
+++ b/tests/ui/where-clauses/ignore-err-clauses.rs
@@ -0,0 +1,14 @@
+use std::ops::Add;
+
+fn dbl<T>(x: T) -> <T as Add>::Output
+where
+    T: Copy + Add,
+    UUU: Copy,
+    //~^ ERROR cannot find type `UUU` in this scope
+{
+    x + x
+}
+
+fn main() {
+    println!("{}", dbl(3));
+}
diff --git a/tests/ui/where-clauses/ignore-err-clauses.stderr b/tests/ui/where-clauses/ignore-err-clauses.stderr
new file mode 100644
index 0000000000000..cfddc3e10b64a
--- /dev/null
+++ b/tests/ui/where-clauses/ignore-err-clauses.stderr
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `UUU` in this scope
+  --> $DIR/ignore-err-clauses.rs:6:5
+   |
+LL |     UUU: Copy,
+   |     ^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.