diff --git a/compiler/rustc_hir_analysis/src/check/callee.rs b/compiler/rustc_hir_analysis/src/check/callee.rs
index f0a7c91090611..088de1979babe 100644
--- a/compiler/rustc_hir_analysis/src/check/callee.rs
+++ b/compiler/rustc_hir_analysis/src/check/callee.rs
@@ -1,6 +1,6 @@
 use super::method::probe::{IsSuggestion, Mode, ProbeScope};
 use super::method::MethodCallee;
-use super::{DefIdOrName, Expectation, FnCtxt, TupleArgumentsFlag};
+use super::{Expectation, FnCtxt, TupleArgumentsFlag};
 use crate::type_error_struct;
 
 use rustc_ast::util::parser::PREC_POSTFIX;
@@ -27,6 +27,7 @@ use rustc_span::Span;
 use rustc_target::spec::abi;
 use rustc_trait_selection::autoderef::Autoderef;
 use rustc_trait_selection::infer::InferCtxtExt as _;
+use rustc_trait_selection::traits::error_reporting::DefIdOrName;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 
 use std::iter;
diff --git a/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs
index 7a40def177ac9..08b21b82faf5a 100644
--- a/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs
@@ -2,7 +2,6 @@ use super::FnCtxt;
 use crate::astconv::AstConv;
 use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel};
 
-use hir::def_id::DefId;
 use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
 use rustc_errors::{Applicability, Diagnostic, MultiSpan};
 use rustc_hir as hir;
@@ -19,6 +18,7 @@ use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 use rustc_trait_selection::infer::InferCtxtExt;
+use rustc_trait_selection::traits::error_reporting::DefIdOrName;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -90,7 +90,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             if ty.is_suggestable(self.tcx, false) {
                                 format!("/* {ty} */")
                             } else {
-                                "".to_string()
+                                "/* value */".to_string()
                             }
                         })
                         .collect::<Vec<_>>()
@@ -102,10 +102,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             let msg = match def_id_or_name {
                 DefIdOrName::DefId(def_id) => match self.tcx.def_kind(def_id) {
-                    DefKind::Ctor(CtorOf::Struct, _) => "instantiate this tuple struct".to_string(),
-                    DefKind::Ctor(CtorOf::Variant, _) => {
-                        "instantiate this tuple variant".to_string()
-                    }
+                    DefKind::Ctor(CtorOf::Struct, _) => "construct this tuple struct".to_string(),
+                    DefKind::Ctor(CtorOf::Variant, _) => "construct this tuple variant".to_string(),
                     kind => format!("call this {}", kind.descr(def_id)),
                 },
                 DefIdOrName::Name(name) => format!("call this {name}"),
@@ -1209,8 +1207,3 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 }
-
-pub enum DefIdOrName {
-    DefId(DefId),
-    Name(&'static str),
-}
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index b89db79bef8d9..ff32329e431b6 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -252,9 +252,13 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
             ) => {
                 // For shortcircuiting operators, mark the RHS as a terminating
                 // scope since it only executes conditionally.
-                terminating(r.hir_id.local_id);
-            }
 
+                // `Let` expressions (in a let-chain) shouldn't be terminating, as their temporaries
+                // should live beyond the immediate expression
+                if !matches!(r.kind, hir::ExprKind::Let(_)) {
+                    terminating(r.hir_id.local_id);
+                }
+            }
             hir::ExprKind::If(_, ref then, Some(ref otherwise)) => {
                 terminating(then.hir_id.local_id);
                 terminating(otherwise.hir_id.local_id);
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index a0a857a73a2c4..ef2c7a003fafa 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -20,19 +20,19 @@ use rustc_span::def_id::LOCAL_CRATE;
 // as they will raise an fatal error on query cycles instead.
 rustc_queries! {
     query trigger_delay_span_bug(key: DefId) -> () {
-        desc { "trigger a delay span bug" }
+        desc { "triggering a delay span bug" }
     }
 
     query resolutions(_: ()) -> &'tcx ty::ResolverOutputs {
         eval_always
         no_hash
-        desc { "get the resolver outputs" }
+        desc { "getting the resolver outputs" }
     }
 
     query resolver_for_lowering(_: ()) -> &'tcx Steal<ty::ResolverAstLowering> {
         eval_always
         no_hash
-        desc { "get the resolver for lowering" }
+        desc { "getting the resolver for lowering" }
     }
 
     /// Return the span for a definition.
@@ -40,7 +40,7 @@ rustc_queries! {
     /// This span is meant for dep-tracking rather than diagnostics. It should not be used outside
     /// of rustc_middle::hir::source_map.
     query source_span(key: LocalDefId) -> Span {
-        desc { "get the source span" }
+        desc { "getting the source span" }
     }
 
     /// Represents crate as a whole (as distinct from the top-level crate module).
@@ -52,14 +52,14 @@ rustc_queries! {
     query hir_crate(key: ()) -> Crate<'tcx> {
         arena_cache
         eval_always
-        desc { "get the crate HIR" }
+        desc { "getting the crate HIR" }
     }
 
     /// All items in the crate.
     query hir_crate_items(_: ()) -> rustc_middle::hir::ModuleItems {
         arena_cache
         eval_always
-        desc { "get HIR crate items" }
+        desc { "getting HIR crate items" }
     }
 
     /// The items in a module.
@@ -68,7 +68,7 @@ rustc_queries! {
     /// Avoid calling this query directly.
     query hir_module_items(key: LocalDefId) -> rustc_middle::hir::ModuleItems {
         arena_cache
-        desc { |tcx| "HIR module items in `{}`", tcx.def_path_str(key.to_def_id()) }
+        desc { |tcx| "getting HIR module items in `{}`", tcx.def_path_str(key.to_def_id()) }
         cache_on_disk_if { true }
     }
 
@@ -77,7 +77,7 @@ rustc_queries! {
     /// This can be conveniently accessed by methods on `tcx.hir()`.
     /// Avoid calling this query directly.
     query hir_owner(key: hir::OwnerId) -> Option<crate::hir::Owner<'tcx>> {
-        desc { |tcx| "HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) }
+        desc { |tcx| "getting HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) }
     }
 
     /// Gives access to the HIR ID for the given `LocalDefId` owner `key`.
@@ -85,7 +85,7 @@ rustc_queries! {
     /// This can be conveniently accessed by methods on `tcx.hir()`.
     /// Avoid calling this query directly.
     query local_def_id_to_hir_id(key: LocalDefId) -> hir::HirId {
-        desc { |tcx| "HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) }
+        desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) }
     }
 
     /// Gives access to the HIR node's parent for the HIR owner `key`.
@@ -93,7 +93,7 @@ rustc_queries! {
     /// This can be conveniently accessed by methods on `tcx.hir()`.
     /// Avoid calling this query directly.
     query hir_owner_parent(key: hir::OwnerId) -> hir::HirId {
-        desc { |tcx| "HIR parent of `{}`", tcx.def_path_str(key.to_def_id()) }
+        desc { |tcx| "getting HIR parent of `{}`", tcx.def_path_str(key.to_def_id()) }
     }
 
     /// Gives access to the HIR nodes and bodies inside the HIR owner `key`.
@@ -101,7 +101,7 @@ rustc_queries! {
     /// This can be conveniently accessed by methods on `tcx.hir()`.
     /// Avoid calling this query directly.
     query hir_owner_nodes(key: hir::OwnerId) -> hir::MaybeOwner<&'tcx hir::OwnerNodes<'tcx>> {
-        desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
+        desc { |tcx| "getting HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
     }
 
     /// Gives access to the HIR attributes inside the HIR owner `key`.
@@ -109,7 +109,7 @@ rustc_queries! {
     /// This can be conveniently accessed by methods on `tcx.hir()`.
     /// Avoid calling this query directly.
     query hir_attrs(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> {
-        desc { |tcx| "HIR owner attributes in `{}`", tcx.def_path_str(key.to_def_id()) }
+        desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key.to_def_id()) }
     }
 
     /// Computes the `DefId` of the corresponding const parameter in case the `key` is a
@@ -138,7 +138,7 @@ rustc_queries! {
     /// Given the def_id of a const-generic parameter, computes the associated default const
     /// parameter. e.g. `fn example<const N: usize=3>` called on `N` would return `3`.
     query const_param_default(param: DefId) -> ty::Const<'tcx> {
-        desc { |tcx| "compute const default for a given parameter `{}`", tcx.def_path_str(param)  }
+        desc { |tcx| "computing const default for a given parameter `{}`", tcx.def_path_str(param)  }
         cache_on_disk_if { param.is_local() }
         separate_provide_extern
     }
@@ -167,7 +167,7 @@ rustc_queries! {
     query collect_trait_impl_trait_tys(key: DefId)
         -> Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed>
     {
-        desc { "compare an impl and trait method signature, inferring any hidden `impl Trait` types in the process" }
+        desc { "comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process" }
         cache_on_disk_if { key.is_local() }
         separate_provide_extern
     }
@@ -290,11 +290,11 @@ rustc_queries! {
 
     query parent_module_from_def_id(key: LocalDefId) -> LocalDefId {
         eval_always
-        desc { |tcx| "parent module of `{}`", tcx.def_path_str(key.to_def_id()) }
+        desc { |tcx| "getting the parent module of `{}`", tcx.def_path_str(key.to_def_id()) }
     }
 
     query expn_that_defined(key: DefId) -> rustc_span::ExpnId {
-        desc { |tcx| "expansion that defined `{}`", tcx.def_path_str(key) }
+        desc { |tcx| "getting the expansion that defined `{}`", tcx.def_path_str(key) }
         separate_provide_extern
     }
 
@@ -306,7 +306,7 @@ rustc_queries! {
 
     /// Checks whether a type is representable or infinitely sized
     query representability(_: LocalDefId) -> rustc_middle::ty::Representability {
-        desc { "checking if {:?} is representable", tcx.def_path_str(key.to_def_id()) }
+        desc { "checking if `{}` is representable", tcx.def_path_str(key.to_def_id()) }
         // infinitely sized types will cause a cycle
         cycle_delay_bug
         // we don't want recursive representability calls to be forced with
@@ -317,7 +317,7 @@ rustc_queries! {
 
     /// An implementation detail for the `representability` query
     query representability_adt_ty(_: Ty<'tcx>) -> rustc_middle::ty::Representability {
-        desc { "checking if {:?} is representable", key }
+        desc { "checking if `{}` is representable", key }
         cycle_delay_bug
         anon
     }
@@ -383,7 +383,7 @@ rustc_queries! {
     /// See the README for the `mir` module for details.
     query mir_const(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> {
         desc {
-            |tcx| "processing MIR for {}`{}`",
+            |tcx| "preparing {}`{}` for borrow checking",
             if key.const_param_did.is_some() { "the const argument " } else { "" },
             tcx.def_path_str(key.did.to_def_id()),
         }
@@ -395,7 +395,7 @@ rustc_queries! {
         key: DefId
     ) -> Result<Option<&'tcx [ty::abstract_const::Node<'tcx>]>, ErrorGuaranteed> {
         desc {
-            |tcx| "building an abstract representation for {}", tcx.def_path_str(key),
+            |tcx| "building an abstract representation for `{}`", tcx.def_path_str(key),
         }
         separate_provide_extern
     }
@@ -405,7 +405,7 @@ rustc_queries! {
     ) -> Result<Option<&'tcx [ty::abstract_const::Node<'tcx>]>, ErrorGuaranteed> {
         desc {
             |tcx|
-            "building an abstract representation for the const argument {}",
+            "building an abstract representation for the const argument `{}`",
             tcx.def_path_str(key.0.to_def_id()),
         }
     }
@@ -414,7 +414,7 @@ rustc_queries! {
         ty::ParamEnvAnd<'tcx, (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>
     )>) -> bool {
         desc {
-            |tcx| "trying to unify the generic constants {} and {}",
+            |tcx| "trying to unify the generic constants `{}` and `{}`",
             tcx.def_path_str(key.value.0.def.did), tcx.def_path_str(key.value.1.def.did)
         }
     }
@@ -436,7 +436,7 @@ rustc_queries! {
 
     query mir_for_ctfe_of_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::Body<'tcx> {
         desc {
-            |tcx| "MIR for CTFE of the const argument `{}`",
+            |tcx| "caching MIR for CTFE of the const argument `{}`",
             tcx.def_path_str(key.0.to_def_id())
         }
     }
@@ -448,7 +448,7 @@ rustc_queries! {
         ) {
         no_hash
         desc {
-            |tcx| "processing {}`{}`",
+            |tcx| "processing MIR for {}`{}`",
             if key.const_param_did.is_some() { "the const argument " } else { "" },
             tcx.def_path_str(key.did.to_def_id()),
         }
@@ -459,7 +459,7 @@ rustc_queries! {
     ) -> Vec<rustc_span::Symbol> {
         arena_cache
         desc {
-            |tcx| "symbols for captures of closure `{}` in `{}`",
+            |tcx| "finding symbols for captures of closure `{}` in `{}`",
             tcx.def_path_str(key.1.to_def_id()),
             tcx.def_path_str(key.0.to_def_id())
         }
@@ -521,12 +521,12 @@ rustc_queries! {
         // queries). Making it anonymous avoids hashing the result, which
         // may save a bit of time.
         anon
-        desc { "erasing regions from `{:?}`", ty }
+        desc { "erasing regions from `{}`", ty }
     }
 
     query wasm_import_module_map(_: CrateNum) -> FxHashMap<DefId, String> {
         arena_cache
-        desc { "wasm import module map" }
+        desc { "getting wasm import module map" }
     }
 
     /// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
@@ -706,7 +706,7 @@ rustc_queries! {
     /// Collects the associated items defined on a trait or impl.
     query associated_items(key: DefId) -> ty::AssocItems<'tcx> {
         arena_cache
-        desc { |tcx| "collecting associated items of {}", tcx.def_path_str(key) }
+        desc { |tcx| "collecting associated items of `{}`", tcx.def_path_str(key) }
     }
 
     /// Maps from associated items on a trait to the corresponding associated
@@ -732,7 +732,7 @@ rustc_queries! {
     ///`{ trait_f: impl_f, trait_g: impl_g }`
     query impl_item_implementor_ids(impl_id: DefId) -> FxHashMap<DefId, DefId> {
         arena_cache
-        desc { |tcx| "comparing impl items against trait for {}", tcx.def_path_str(impl_id) }
+        desc { |tcx| "comparing impl items against trait for `{}`", tcx.def_path_str(impl_id) }
     }
 
     /// Given an `impl_id`, return the trait it implements.
@@ -804,7 +804,7 @@ rustc_queries! {
     /// Note that we've liberated the late bound regions of function signatures, so
     /// this can not be used to check whether these types are well formed.
     query assumed_wf_types(key: DefId) -> &'tcx ty::List<Ty<'tcx>> {
-        desc { |tcx| "computing the implied bounds of {}", tcx.def_path_str(key) }
+        desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) }
     }
 
     /// Computes the signature of the function.
@@ -853,7 +853,7 @@ rustc_queries! {
     }
 
     query check_liveness(key: DefId) {
-        desc { |tcx| "checking liveness of variables in {}", tcx.def_path_str(key) }
+        desc { |tcx| "checking liveness of variables in `{}`", tcx.def_path_str(key) }
     }
 
     /// Return the live symbols in the crate for dead code check.
@@ -865,7 +865,7 @@ rustc_queries! {
         FxHashMap<LocalDefId, Vec<(DefId, DefId)>>
     ) {
         arena_cache
-        desc { "find live symbols in crate" }
+        desc { "finding live symbols in crate" }
     }
 
     query check_mod_deathness(key: LocalDefId) -> () {
@@ -913,7 +913,7 @@ rustc_queries! {
     }
 
     query used_trait_imports(key: LocalDefId) -> &'tcx FxHashSet<LocalDefId> {
-        desc { |tcx| "used_trait_imports `{}`", tcx.def_path_str(key.to_def_id()) }
+        desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key.to_def_id()) }
         cache_on_disk_if { true }
     }
 
@@ -942,7 +942,7 @@ rustc_queries! {
     /// Not meant to be used directly outside of coherence.
     query crate_inherent_impls(k: ()) -> CrateInherentImpls {
         arena_cache
-        desc { "all inherent impls defined in crate" }
+        desc { "finding all inherent impls defined in crate" }
     }
 
     /// Checks all types in the crate for overlap in their inherent impls. Reports errors.
@@ -1032,7 +1032,7 @@ rustc_queries! {
     query try_destructure_mir_constant(
         key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>
     ) -> Option<mir::DestructuredConstant<'tcx>> {
-        desc { "destructuring mir constant"}
+        desc { "destructuring MIR constant"}
         remap_env_constness
     }
 
@@ -1041,12 +1041,12 @@ rustc_queries! {
     query deref_mir_constant(
         key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>
     ) -> mir::ConstantKind<'tcx> {
-        desc { "dereferencing mir constant" }
+        desc { "dereferencing MIR constant" }
         remap_env_constness
     }
 
     query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> {
-        desc { "get a &core::panic::Location referring to a span" }
+        desc { "getting a &core::panic::Location referring to a span" }
     }
 
     // FIXME get rid of this with valtrees
@@ -1068,7 +1068,7 @@ rustc_queries! {
     /// Performs part of the privacy check and computes "access levels".
     query privacy_access_levels(_: ()) -> &'tcx AccessLevels {
         eval_always
-        desc { "privacy access levels" }
+        desc { "checking privacy access levels" }
     }
     query check_private_in_public(_: ()) -> () {
         eval_always
@@ -1196,12 +1196,12 @@ rustc_queries! {
     }
 
     query is_ctfe_mir_available(key: DefId) -> bool {
-        desc { |tcx| "checking if item has ctfe mir available: `{}`", tcx.def_path_str(key) }
+        desc { |tcx| "checking if item has CTFE MIR available: `{}`", tcx.def_path_str(key) }
         cache_on_disk_if { key.is_local() }
         separate_provide_extern
     }
     query is_mir_available(key: DefId) -> bool {
-        desc { |tcx| "checking if item has mir available: `{}`", tcx.def_path_str(key) }
+        desc { |tcx| "checking if item has MIR available: `{}`", tcx.def_path_str(key) }
         cache_on_disk_if { key.is_local() }
         separate_provide_extern
     }
@@ -1209,16 +1209,16 @@ rustc_queries! {
     query own_existential_vtable_entries(
         key: ty::PolyExistentialTraitRef<'tcx>
     ) -> &'tcx [DefId] {
-        desc { |tcx| "finding all existential vtable entries for trait {}", tcx.def_path_str(key.def_id()) }
+        desc { |tcx| "finding all existential vtable entries for trait `{}`", tcx.def_path_str(key.def_id()) }
     }
 
     query vtable_entries(key: ty::PolyTraitRef<'tcx>)
                         -> &'tcx [ty::VtblEntry<'tcx>] {
-        desc { |tcx| "finding all vtable entries for trait {}", tcx.def_path_str(key.def_id()) }
+        desc { |tcx| "finding all vtable entries for trait `{}`", tcx.def_path_str(key.def_id()) }
     }
 
     query vtable_trait_upcasting_coercion_new_vptr_slot(key: (Ty<'tcx>, Ty<'tcx>)) -> Option<usize> {
-        desc { |tcx| "finding the slot within vtable for trait object {} vtable ptr during trait upcasting coercion from {} vtable",
+        desc { |tcx| "finding the slot within vtable for trait object `{}` vtable ptr during trait upcasting coercion from `{}` vtable",
             key.1, key.0 }
     }
 
@@ -1238,13 +1238,13 @@ rustc_queries! {
 
     /// Return all `impl` blocks in the current crate.
     query all_local_trait_impls(_: ()) -> &'tcx rustc_data_structures::fx::FxIndexMap<DefId, Vec<LocalDefId>> {
-        desc { "local trait impls" }
+        desc { "finding local trait impls" }
     }
 
     /// Given a trait `trait_id`, return all known `impl` blocks.
     query trait_impls_of(trait_id: DefId) -> ty::trait_def::TraitImpls {
         arena_cache
-        desc { |tcx| "trait impls of `{}`", tcx.def_path_str(trait_id) }
+        desc { |tcx| "finding trait impls of `{}`", tcx.def_path_str(trait_id) }
     }
 
     query specialization_graph_of(trait_id: DefId) -> specialization_graph::Graph {
@@ -1253,7 +1253,7 @@ rustc_queries! {
         cache_on_disk_if { true }
     }
     query object_safety_violations(trait_id: DefId) -> &'tcx [traits::ObjectSafetyViolation] {
-        desc { |tcx| "determine object safety of trait `{}`", tcx.def_path_str(trait_id) }
+        desc { |tcx| "determining object safety of trait `{}`", tcx.def_path_str(trait_id) }
     }
 
     /// Gets the ParameterEnvironment for a given item; this environment
@@ -1311,7 +1311,7 @@ rustc_queries! {
     /// correctly.
     query has_structural_eq_impls(ty: Ty<'tcx>) -> bool {
         desc {
-            "computing whether `{:?}` implements `PartialStructuralEq` and `StructuralEq`",
+            "computing whether `{}` implements `PartialStructuralEq` and `StructuralEq`",
             ty
         }
     }
@@ -1370,13 +1370,13 @@ rustc_queries! {
 
     query dylib_dependency_formats(_: CrateNum)
                                     -> &'tcx [(CrateNum, LinkagePreference)] {
-        desc { "dylib dependency formats of crate" }
+        desc { "getting dylib dependency formats of crate" }
         separate_provide_extern
     }
 
     query dependency_formats(_: ()) -> Lrc<crate::middle::dependency_format::Dependencies> {
         arena_cache
-        desc { "get the linkage format of all dependencies" }
+        desc { "getting the linkage format of all dependencies" }
     }
 
     query is_compiler_builtins(_: CrateNum) -> bool {
@@ -1398,31 +1398,31 @@ rustc_queries! {
     }
     query is_profiler_runtime(_: CrateNum) -> bool {
         fatal_cycle
-        desc { "query a crate is `#![profiler_runtime]`" }
+        desc { "checking if a crate is `#![profiler_runtime]`" }
         separate_provide_extern
     }
     query has_ffi_unwind_calls(key: LocalDefId) -> bool {
-        desc { |tcx| "check if `{}` contains FFI-unwind calls", tcx.def_path_str(key.to_def_id()) }
+        desc { |tcx| "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key.to_def_id()) }
         cache_on_disk_if { true }
     }
     query required_panic_strategy(_: CrateNum) -> Option<PanicStrategy> {
         fatal_cycle
-        desc { "query a crate's required panic strategy" }
+        desc { "getting a crate's required panic strategy" }
         separate_provide_extern
     }
     query panic_in_drop_strategy(_: CrateNum) -> PanicStrategy {
         fatal_cycle
-        desc { "query a crate's configured panic-in-drop strategy" }
+        desc { "getting a crate's configured panic-in-drop strategy" }
         separate_provide_extern
     }
     query is_no_builtins(_: CrateNum) -> bool {
         fatal_cycle
-        desc { "test whether a crate has `#![no_builtins]`" }
+        desc { "getting whether a crate has `#![no_builtins]`" }
         separate_provide_extern
     }
     query symbol_mangling_version(_: CrateNum) -> SymbolManglingVersion {
         fatal_cycle
-        desc { "query a crate's symbol mangling version" }
+        desc { "getting a crate's symbol mangling version" }
         separate_provide_extern
     }
 
@@ -1437,7 +1437,7 @@ rustc_queries! {
     }
     query in_scope_traits_map(_: hir::OwnerId)
         -> Option<&'tcx FxHashMap<ItemLocalId, Box<[TraitCandidate]>>> {
-        desc { "traits in scope at a block" }
+        desc { "getting traits in scope at a block" }
     }
 
     query module_reexports(def_id: LocalDefId) -> Option<&'tcx [ModChild]> {
@@ -1588,17 +1588,17 @@ rustc_queries! {
     }
 
     query is_dllimport_foreign_item(def_id: DefId) -> bool {
-        desc { |tcx| "is_dllimport_foreign_item({})", tcx.def_path_str(def_id) }
+        desc { |tcx| "checking if `{}` is a a dylib", tcx.def_path_str(def_id) }
     }
     query is_statically_included_foreign_item(def_id: DefId) -> bool {
-        desc { |tcx| "is_statically_included_foreign_item({})", tcx.def_path_str(def_id) }
+        desc { |tcx| "checking if `{}` is a staticlib", tcx.def_path_str(def_id) }
     }
     query native_library_kind(def_id: DefId)
         -> Option<NativeLibKind> {
-        desc { |tcx| "native_library_kind({})", tcx.def_path_str(def_id) }
+        desc { |tcx| "getting the native library kind of `{}`", tcx.def_path_str(def_id) }
     }
     query native_library(def_id: DefId) -> Option<&'tcx NativeLib> {
-        desc { |tcx| "native_library({})", tcx.def_path_str(def_id) }
+        desc { |tcx| "getting the native library for `{}`", tcx.def_path_str(def_id) }
     }
 
     /// Does lifetime resolution, but does not descend into trait items. This
@@ -1659,7 +1659,7 @@ rustc_queries! {
     query type_uninhabited_from(
         key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
     ) -> ty::inhabitedness::DefIdForest<'tcx> {
-        desc { "computing the inhabitedness of `{:?}`", key }
+        desc { "computing the inhabitedness of `{}`", key.value }
         remap_env_constness
     }
 
@@ -1698,7 +1698,7 @@ rustc_queries! {
     }
     /// Whether the function is an intrinsic
     query is_intrinsic(def_id: DefId) -> bool {
-        desc { |tcx| "is_intrinsic({})", tcx.def_path_str(def_id) }
+        desc { |tcx| "checking whether `{}` is an intrinsic", tcx.def_path_str(def_id) }
         separate_provide_extern
     }
     /// Returns the lang items defined in another crate by loading it from metadata.
@@ -1765,12 +1765,12 @@ rustc_queries! {
     /// is marked as a private dependency
     query is_private_dep(c: CrateNum) -> bool {
         eval_always
-        desc { "check whether crate {} is a private dependency", c }
+        desc { "checking whether crate `{}` is a private dependency", c }
         separate_provide_extern
     }
     query allocator_kind(_: ()) -> Option<AllocatorKind> {
         eval_always
-        desc { "allocator kind for the current crate" }
+        desc { "getting the allocator kind for the current crate" }
     }
 
     query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>> {
@@ -1783,7 +1783,7 @@ rustc_queries! {
         desc { "looking up all possibly unused extern crates" }
     }
     query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx FxHashSet<Symbol> {
-        desc { |tcx| "names_imported_by_glob_use for `{}`", tcx.def_path_str(def_id.to_def_id()) }
+        desc { |tcx| "finding names imported by glob use for `{}`", tcx.def_path_str(def_id.to_def_id()) }
     }
 
     query stability_index(_: ()) -> stability::Index {
@@ -1809,7 +1809,7 @@ rustc_queries! {
     ///   correspond to a publicly visible symbol in `cnum` machine code.
     /// - The `exported_symbols` sets of different crates do not intersect.
     query exported_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
-        desc { "exported_symbols" }
+        desc { "collecting exported symbols for crate `{}`", cnum}
         cache_on_disk_if { *cnum == LOCAL_CRATE }
         separate_provide_extern
     }
@@ -1818,6 +1818,7 @@ rustc_queries! {
         eval_always
         desc { "collect_and_partition_mono_items" }
     }
+
     query is_codegened_item(def_id: DefId) -> bool {
         desc { |tcx| "determining whether `{}` needs codegen", tcx.def_path_str(def_id) }
     }
@@ -1825,12 +1826,13 @@ rustc_queries! {
     /// All items participating in code generation together with items inlined into them.
     query codegened_and_inlined_items(_: ()) -> &'tcx DefIdSet {
         eval_always
-       desc { "codegened_and_inlined_items" }
+        desc { "collecting codegened and inlined items" }
     }
 
-    query codegen_unit(_: Symbol) -> &'tcx CodegenUnit<'tcx> {
-        desc { "codegen_unit" }
+    query codegen_unit(sym: Symbol) -> &'tcx CodegenUnit<'tcx> {
+        desc { "getting codegen unit `{sym}`" }
     }
+
     query unused_generic_params(key: ty::InstanceDef<'tcx>) -> FiniteBitSet<u32> {
         cache_on_disk_if { key.def_id().is_local() }
         desc {
@@ -1839,6 +1841,7 @@ rustc_queries! {
         }
         separate_provide_extern
     }
+
     query backend_optimization_level(_: ()) -> OptLevel {
         desc { "optimization level used by backend" }
     }
@@ -1849,7 +1852,7 @@ rustc_queries! {
     /// has been destroyed.
     query output_filenames(_: ()) -> &'tcx Arc<OutputFilenames> {
         eval_always
-        desc { "output_filenames" }
+        desc { "getting output filenames" }
     }
 
     /// Do not call this query directly: invoke `normalize` instead.
@@ -1859,7 +1862,7 @@ rustc_queries! {
         &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>,
         NoSolution,
     > {
-        desc { "normalizing `{:?}`", goal }
+        desc { "normalizing `{}`", goal.value.value }
         remap_env_constness
     }
 
@@ -1877,7 +1880,7 @@ rustc_queries! {
         &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
         NoSolution,
     > {
-        desc { "computing implied outlives bounds for `{:?}`", goal }
+        desc { "computing implied outlives bounds for `{}`", goal.value.value }
         remap_env_constness
     }
 
@@ -1889,7 +1892,7 @@ rustc_queries! {
         &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>,
         NoSolution,
     > {
-        desc { "computing dropck types for `{:?}`", goal }
+        desc { "computing dropck types for `{}`", goal.value.value }
         remap_env_constness
     }
 
@@ -1917,7 +1920,7 @@ rustc_queries! {
         &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
         NoSolution,
     > {
-        desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal }
+        desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal.value.value }
         remap_env_constness
     }
 
@@ -1928,7 +1931,7 @@ rustc_queries! {
         &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
         NoSolution,
     > {
-        desc { "evaluating `type_op_eq` `{:?}`", goal }
+        desc { "evaluating `type_op_eq` `{:?}`", goal.value.value }
         remap_env_constness
     }
 
@@ -1939,7 +1942,7 @@ rustc_queries! {
         &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
         NoSolution,
     > {
-        desc { "evaluating `type_op_subtype` `{:?}`", goal }
+        desc { "evaluating `type_op_subtype` `{:?}`", goal.value.value }
         remap_env_constness
     }
 
@@ -1950,7 +1953,7 @@ rustc_queries! {
         &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
         NoSolution,
     > {
-        desc { "evaluating `type_op_prove_predicate` `{:?}`", goal }
+        desc { "evaluating `type_op_prove_predicate` `{:?}`", goal.value.value }
     }
 
     /// Do not call this query directly: part of the `Normalize` type-op
@@ -1960,7 +1963,7 @@ rustc_queries! {
         &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Ty<'tcx>>>,
         NoSolution,
     > {
-        desc { "normalizing `{:?}`", goal }
+        desc { "normalizing `{}`", goal.value.value.value }
         remap_env_constness
     }
 
@@ -1971,7 +1974,7 @@ rustc_queries! {
         &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::Predicate<'tcx>>>,
         NoSolution,
     > {
-        desc { "normalizing `{:?}`", goal }
+        desc { "normalizing `{:?}`", goal.value.value.value }
         remap_env_constness
     }
 
@@ -1982,7 +1985,7 @@ rustc_queries! {
         &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::PolyFnSig<'tcx>>>,
         NoSolution,
     > {
-        desc { "normalizing `{:?}`", goal }
+        desc { "normalizing `{:?}`", goal.value.value.value }
         remap_env_constness
     }
 
@@ -1993,20 +1996,20 @@ rustc_queries! {
         &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::FnSig<'tcx>>>,
         NoSolution,
     > {
-        desc { "normalizing `{:?}`", goal }
+        desc { "normalizing `{:?}`", goal.value.value.value }
         remap_env_constness
     }
 
     query subst_and_check_impossible_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool {
         desc { |tcx|
-            "impossible substituted predicates:`{}`",
+            "checking impossible substituted predicates: `{}`",
             tcx.def_path_str(key.0)
         }
     }
 
     query is_impossible_method(key: (DefId, DefId)) -> bool {
         desc { |tcx|
-            "checking if {} is impossible to call within {}",
+            "checking if `{}` is impossible to call within `{}`",
             tcx.def_path_str(key.1),
             tcx.def_path_str(key.0),
         }
@@ -2015,7 +2018,7 @@ rustc_queries! {
     query method_autoderef_steps(
         goal: CanonicalTyGoal<'tcx>
     ) -> MethodAutoderefStepsResult<'tcx> {
-        desc { "computing autoderef types for `{:?}`", goal }
+        desc { "computing autoderef types for `{}`", goal.value.value }
         remap_env_constness
     }
 
@@ -2063,7 +2066,7 @@ rustc_queries! {
     }
 
     query normalize_opaque_types(key: &'tcx ty::List<ty::Predicate<'tcx>>) -> &'tcx ty::List<ty::Predicate<'tcx>> {
-        desc { "normalizing opaque types in {:?}", key }
+        desc { "normalizing opaque types in `{:?}`", key }
     }
 
     /// Checks whether a type is definitely uninhabited. This is
@@ -2073,7 +2076,7 @@ rustc_queries! {
     /// will be `Abi::Uninhabited`. (Note that uninhabited types may have nonzero
     /// size, to account for partial initialisation. See #49298 for details.)
     query conservative_is_privately_uninhabited(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
-        desc { "conservatively checking if {:?} is privately uninhabited", key }
+        desc { "conservatively checking if `{}` is privately uninhabited", key.value }
         remap_env_constness
     }
 
@@ -2093,7 +2096,7 @@ rustc_queries! {
         arena_cache
         eval_always
         no_hash
-        desc { "performing HIR wf-checking for predicate {:?} at item {:?}", key.0, key.1 }
+        desc { "performing HIR wf-checking for predicate `{:?}` at item `{:?}`", key.0, key.1 }
     }
 
 
@@ -2112,11 +2115,11 @@ rustc_queries! {
     }
 
     query permits_uninit_init(key: TyAndLayout<'tcx>) -> bool {
-        desc { "checking to see if {:?} permits being left uninit", key.ty }
+        desc { "checking to see if `{}` permits being left uninit", key.ty }
     }
 
     query permits_zero_init(key: TyAndLayout<'tcx>) -> bool {
-        desc { "checking to see if {:?} permits being left zeroed", key.ty }
+        desc { "checking to see if `{}` permits being left zeroed", key.ty }
     }
 
     query compare_assoc_const_impl_item_with_trait_item(
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 77ba7a82672bc..59efb5aff7531 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1862,9 +1862,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
         for (index, (pat, ty)) in inputs.enumerate() {
             debug!(?pat, ?ty);
-            if let Some(pat) = pat {
-                self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
-            }
+            self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
+                if let Some(pat) = pat {
+                    this.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
+                }
+            });
             self.visit_ty(ty);
 
             if let Some(ref candidates) = self.lifetime_elision_candidates {
@@ -2834,10 +2836,13 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
 
     fn resolve_params(&mut self, params: &'ast [Param]) {
         let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
-        for Param { pat, ty, .. } in params {
-            self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
+        self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
+            for Param { pat, .. } in params {
+                this.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
+            }
+        });
+        for Param { ty, .. } in params {
             self.visit_ty(ty);
-            debug!("(resolving function / closure) recorded parameter");
         }
     }
 
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 4e8baa2dfab6c..b7e6a564f3953 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -2,10 +2,10 @@ pub mod on_unimplemented;
 pub mod suggestions;
 
 use super::{
-    EvaluationResult, FulfillmentContext, FulfillmentError, FulfillmentErrorCode,
-    MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode,
-    OnUnimplementedDirective, OnUnimplementedNote, OutputTypeParameterMismatch, Overflow,
-    PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
+    FulfillmentContext, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes,
+    Obligation, ObligationCause, ObligationCauseCode, OnUnimplementedDirective,
+    OnUnimplementedNote, OutputTypeParameterMismatch, Overflow, PredicateObligation,
+    SelectionContext, SelectionError, TraitNotObjectSafe,
 };
 
 use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
@@ -2796,3 +2796,8 @@ impl<'tcx> ty::TypeVisitor<'tcx> for HasNumericInferVisitor {
         }
     }
 }
+
+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 4431cf9f4436b..8c41d9d240c70 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1,5 +1,5 @@
 use super::{
-    EvaluationResult, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation,
+    DefIdOrName, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation,
     SelectionContext,
 };
 
@@ -7,6 +7,7 @@ use crate::autoderef::Autoderef;
 use crate::infer::InferCtxt;
 use crate::traits::normalize_to;
 
+use hir::def::CtorOf;
 use hir::HirId;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -22,6 +23,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
 use rustc_infer::infer::error_reporting::TypeErrCtxt;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc_infer::infer::LateBoundRegionConversionTime;
 use rustc_middle::hir::map;
 use rustc_middle::ty::{
     self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
@@ -29,7 +31,7 @@ use rustc_middle::ty::{
     ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
 };
 use rustc_middle::ty::{TypeAndMut, TypeckResults};
-use rustc_span::symbol::{kw, sym, Ident, Symbol};
+use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{BytePos, DesugaringKind, ExpnKind, Span, DUMMY_SP};
 use rustc_target::spec::abi;
 use std::fmt;
@@ -812,74 +814,136 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         err: &mut Diagnostic,
         trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> bool {
-        // Skipping binder here, remapping below
-        let self_ty = trait_pred.self_ty().skip_binder();
-
-        let (def_id, output_ty, callable) = match *self_ty.kind() {
-            ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig().output(), "closure"),
-            ty::FnDef(def_id, _) => (def_id, self_ty.fn_sig(self.tcx).output(), "function"),
-            _ => return false,
-        };
-        let msg = format!("use parentheses to call the {}", callable);
+        if let ty::PredicateKind::Trait(trait_pred) = obligation.predicate.kind().skip_binder()
+            && Some(trait_pred.def_id()) == self.tcx.lang_items().sized_trait()
+        {
+            // Don't suggest calling to turn an unsized type into a sized type
+            return false;
+        }
 
-        // "We should really create a single list of bound vars from the combined vars
-        // from the predicate and function, but instead we just liberate the function bound vars"
-        let output_ty = self.tcx.liberate_late_bound_regions(def_id, output_ty);
+        // 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::Opaque(def_id, substs) => {
+                self.tcx.bound_item_bounds(def_id).subst(self.tcx, substs).iter().find_map(|pred| {
+                    if let ty::PredicateKind::Projection(proj) = pred.kind().skip_binder()
+                    && Some(proj.projection_ty.item_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.item_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::Projection(proj) = pred.kind().skip_binder()
+                    && Some(proj.projection_ty.item_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,
+            LateBoundRegionConversionTime::FnCall,
+            output,
+        );
+        let inputs = inputs.skip_binder().iter().map(|ty| {
+            self.replace_bound_vars_with_fresh_vars(
+                obligation.cause.span,
+                LateBoundRegionConversionTime::FnCall,
+                inputs.rebind(*ty),
+            )
+        });
 
         // Remapping bound vars here
-        let trait_pred_and_self = trait_pred.map_bound(|trait_pred| (trait_pred, output_ty));
+        let trait_pred_and_self = trait_pred.map_bound(|trait_pred| (trait_pred, output));
 
         let new_obligation =
             self.mk_trait_obligation_with_new_self_ty(obligation.param_env, trait_pred_and_self);
-
-        match self.evaluate_obligation(&new_obligation) {
-            Ok(
-                EvaluationResult::EvaluatedToOk
-                | EvaluationResult::EvaluatedToOkModuloRegions
-                | EvaluationResult::EvaluatedToOkModuloOpaqueTypes
-                | EvaluationResult::EvaluatedToAmbig,
-            ) => {}
-            _ => return false,
+        if !self.predicate_must_hold_modulo_regions(&new_obligation) {
+            return false;
         }
-        let hir = self.tcx.hir();
+
         // Get the name of the callable and the arguments to be used in the suggestion.
-        let (snippet, sugg) = match hir.get_if_local(def_id) {
-            Some(hir::Node::Expr(hir::Expr {
-                kind: hir::ExprKind::Closure(hir::Closure { fn_decl, fn_decl_span, .. }),
-                ..
-            })) => {
-                err.span_label(*fn_decl_span, "consider calling this closure");
-                let Some(name) = self.get_closure_name(def_id, err, &msg) else {
-                    return false;
-                };
-                let args = fn_decl.inputs.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
-                let sugg = format!("({})", args);
-                (format!("{}{}", name, sugg), sugg)
-            }
-            Some(hir::Node::Item(hir::Item {
-                ident,
-                kind: hir::ItemKind::Fn(.., body_id),
-                ..
-            })) => {
-                err.span_label(ident.span, "consider calling this function");
-                let body = hir.body(*body_id);
-                let args = body
-                    .params
-                    .iter()
-                    .map(|arg| match &arg.pat.kind {
-                        hir::PatKind::Binding(_, _, ident, None)
-                        // FIXME: provide a better suggestion when encountering `SelfLower`, it
-                        // should suggest a method call.
-                        if ident.name != kw::SelfLower => ident.to_string(),
-                        _ => "_".to_string(),
-                    })
-                    .collect::<Vec<_>>()
-                    .join(", ");
-                let sugg = format!("({})", args);
-                (format!("{}{}", ident, sugg), sugg)
-            }
-            _ => return false,
+        let hir = self.tcx.hir();
+
+        let msg = match def_id_or_name {
+            DefIdOrName::DefId(def_id) => match self.tcx.def_kind(def_id) {
+                DefKind::Ctor(CtorOf::Struct, _) => {
+                    "use parentheses to construct this tuple struct".to_string()
+                }
+                DefKind::Ctor(CtorOf::Variant, _) => {
+                    "use parentheses to construct this tuple variant".to_string()
+                }
+                kind => format!("use parentheses to call this {}", kind.descr(def_id)),
+            },
+            DefIdOrName::Name(name) => format!("use parentheses to call this {name}"),
         };
+
+        let args = inputs
+            .map(|ty| {
+                if ty.is_suggestable(self.tcx, false) {
+                    format!("/* {ty} */")
+                } else {
+                    "/* value */".to_string()
+                }
+            })
+            .collect::<Vec<_>>()
+            .join(", ");
+
         if matches!(obligation.cause.code(), ObligationCauseCode::FunctionArgumentObligation { .. })
             && obligation.cause.span.can_be_used_for_suggestions()
         {
@@ -890,11 +954,36 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             err.span_suggestion_verbose(
                 obligation.cause.span.shrink_to_hi(),
                 &msg,
-                sugg,
+                format!("({args})"),
                 Applicability::HasPlaceholders,
             );
-        } else {
-            err.help(&format!("{}: `{}`", msg, snippet));
+        } else if let DefIdOrName::DefId(def_id) = def_id_or_name {
+            let name = match hir.get_if_local(def_id) {
+                Some(hir::Node::Expr(hir::Expr {
+                    kind: hir::ExprKind::Closure(hir::Closure { fn_decl_span, .. }),
+                    ..
+                })) => {
+                    err.span_label(*fn_decl_span, "consider calling this closure");
+                    let Some(name) = self.get_closure_name(def_id, err, &msg) else {
+                        return false;
+                    };
+                    name.to_string()
+                }
+                Some(hir::Node::Item(hir::Item { ident, kind: hir::ItemKind::Fn(..), .. })) => {
+                    err.span_label(ident.span, "consider calling this function");
+                    ident.to_string()
+                }
+                Some(hir::Node::Ctor(..)) => {
+                    let name = self.tcx.def_path_str(def_id);
+                    err.span_label(
+                        self.tcx.def_span(def_id),
+                        format!("consider calling the constructor for `{}`", name),
+                    );
+                    name
+                }
+                _ => return false,
+            };
+            err.help(&format!("{msg}: `{name}({args})`"));
         }
         true
     }
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index b2bb7a5b2e659..b5b2eb0ece0ee 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -2193,7 +2193,6 @@ impl<T, A: Allocator> Vec<T, A> {
     /// static_ref[0] += 1;
     /// assert_eq!(static_ref, &[2, 2, 3]);
     /// ```
-    #[cfg(not(no_global_oom_handling))]
     #[stable(feature = "vec_leak", since = "1.47.0")]
     #[inline]
     pub fn leak<'a>(self) -> &'a mut [T]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index da84763836eb4..2fd8180f8b2a2 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -217,6 +217,7 @@
 #![feature(unboxed_closures)]
 #![feature(unsized_fn_params)]
 #![feature(asm_const)]
+#![feature(const_transmute_copy)]
 //
 // Target features:
 #![feature(arm_target_feature)]
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 2ae9636762813..efad9a9391b4c 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -1297,7 +1297,8 @@ impl<T, const N: usize> MaybeUninit<[T; N]> {
     /// let data: [MaybeUninit<u8>; 1000] = MaybeUninit::uninit().transpose();
     /// ```
     #[unstable(feature = "maybe_uninit_uninit_array_transpose", issue = "96097")]
-    pub fn transpose(self) -> [MaybeUninit<T>; N] {
+    #[inline]
+    pub const fn transpose(self) -> [MaybeUninit<T>; N] {
         // SAFETY: T and MaybeUninit<T> have the same layout
         unsafe { super::transmute_copy(&ManuallyDrop::new(self)) }
     }
@@ -1316,7 +1317,8 @@ impl<T, const N: usize> [MaybeUninit<T>; N] {
     /// let data: MaybeUninit<[u8; 1000]> = data.transpose();
     /// ```
     #[unstable(feature = "maybe_uninit_uninit_array_transpose", issue = "96097")]
-    pub fn transpose(self) -> MaybeUninit<[T; N]> {
+    #[inline]
+    pub const fn transpose(self) -> MaybeUninit<[T; N]> {
         // SAFETY: T and MaybeUninit<T> have the same layout
         unsafe { super::transmute_copy(&ManuallyDrop::new(self)) }
     }
diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr
index e6f6e9e9f653f..c5bd520aaea0d 100644
--- a/src/test/ui/async-await/no-const-async.stderr
+++ b/src/test/ui/async-await/no-const-async.stderr
@@ -18,7 +18,7 @@ note: ...which requires borrow-checking `x`...
    |
 LL | pub const async fn x() {}
    | ^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires processing `x`...
+note: ...which requires processing MIR for `x`...
   --> $DIR/no-const-async.rs:4:1
    |
 LL | pub const async fn x() {}
diff --git a/src/test/ui/binop/issue-77910-1.stderr b/src/test/ui/binop/issue-77910-1.stderr
index 9c7bf6228be6e..263a35d982911 100644
--- a/src/test/ui/binop/issue-77910-1.stderr
+++ b/src/test/ui/binop/issue-77910-1.stderr
@@ -19,7 +19,7 @@ LL |     assert_eq!(foo, y);
    |     ^^^^^^^^^^^^^^^^^^ `for<'a> fn(&'a i32) -> &'a i32 {foo}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
    = help: the trait `Debug` is not implemented for fn item `for<'a> fn(&'a i32) -> &'a i32 {foo}`
-   = help: use parentheses to call the function: `foo(s)`
+   = help: use parentheses to call this function: `foo(/* &i32 */)`
    = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/closures/closure-bounds-subtype.stderr b/src/test/ui/closures/closure-bounds-subtype.stderr
index 1a40326d986c4..8ad8273fc2b9b 100644
--- a/src/test/ui/closures/closure-bounds-subtype.stderr
+++ b/src/test/ui/closures/closure-bounds-subtype.stderr
@@ -11,6 +11,10 @@ note: required by a bound in `take_const_owned`
    |
 LL | fn take_const_owned<F>(_: F) where F: FnOnce() + Sync + Send {
    |                                                  ^^^^ required by this bound in `take_const_owned`
+help: use parentheses to call this type parameter
+   |
+LL |     take_const_owned(f());
+   |                       ++
 help: consider further restricting this bound
    |
 LL | fn give_owned<F>(f: F) where F: FnOnce() + Send + std::marker::Sync {
diff --git a/src/test/ui/const-generics/generic_const_exprs/closures.stderr b/src/test/ui/const-generics/generic_const_exprs/closures.stderr
index a15dd2016e9e4..a7d891d77908c 100644
--- a/src/test/ui/const-generics/generic_const_exprs/closures.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/closures.stderr
@@ -1,4 +1,4 @@
-error[E0391]: cycle detected when building an abstract representation for test::{constant#0}
+error[E0391]: cycle detected when building an abstract representation for `test::{constant#0}`
   --> $DIR/closures.rs:3:35
    |
 LL | fn test<const N: usize>() -> [u8; N + (|| 42)()] {}
@@ -14,7 +14,7 @@ note: ...which requires type-checking `test::{constant#0}`...
    |
 LL | fn test<const N: usize>() -> [u8; N + (|| 42)()] {}
    |                                   ^^^^^^^^^^^^^
-   = note: ...which again requires building an abstract representation for test::{constant#0}, completing the cycle
+   = note: ...which again requires building an abstract representation for `test::{constant#0}`, completing the cycle
 note: cycle used when checking that `test` is well-formed
   --> $DIR/closures.rs:3:1
    |
diff --git a/src/test/ui/drop/drop_order.rs b/src/test/ui/drop/drop_order.rs
index ba1ac53aa7ce8..42385216ae765 100644
--- a/src/test/ui/drop/drop_order.rs
+++ b/src/test/ui/drop/drop_order.rs
@@ -129,10 +129,10 @@ impl DropOrderCollector {
         // take the "else" branch
         if self.option_loud_drop(6).is_some() // 2
             && self.option_loud_drop(5).is_some() // 1
-            && let None = self.option_loud_drop(7) { // 3
+            && let None = self.option_loud_drop(8) { // 4
             unreachable!();
         } else {
-            self.print(8); // 4
+            self.print(7); // 3
         }
 
         // let exprs interspersed
diff --git a/src/test/ui/drop/issue-100276.rs b/src/test/ui/drop/issue-100276.rs
new file mode 100644
index 0000000000000..6401a8d148100
--- /dev/null
+++ b/src/test/ui/drop/issue-100276.rs
@@ -0,0 +1,12 @@
+// check-pass
+// compile-flags: -Z validate-mir
+#![feature(let_chains)]
+
+fn let_chains(entry: std::io::Result<std::fs::DirEntry>) {
+    if let Ok(entry) = entry
+        && let Some(s) = entry.file_name().to_str()
+        && s.contains("")
+    {}
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr
index b6e28364768ec..feedfc40aaf49 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.stderr
+++ b/src/test/ui/impl-trait/auto-trait-leak.stderr
@@ -9,12 +9,12 @@ note: ...which requires borrow-checking `cycle1`...
    |
 LL | fn cycle1() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires processing `cycle1`...
+note: ...which requires processing MIR for `cycle1`...
   --> $DIR/auto-trait-leak.rs:12:1
    |
 LL | fn cycle1() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires processing MIR for `cycle1`...
+note: ...which requires preparing `cycle1` for borrow checking...
   --> $DIR/auto-trait-leak.rs:12:1
    |
 LL | fn cycle1() -> impl Clone {
@@ -50,12 +50,12 @@ note: ...which requires borrow-checking `cycle2`...
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires processing `cycle2`...
+note: ...which requires processing MIR for `cycle2`...
   --> $DIR/auto-trait-leak.rs:19:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires processing MIR for `cycle2`...
+note: ...which requires preparing `cycle2` for borrow checking...
   --> $DIR/auto-trait-leak.rs:19:1
    |
 LL | fn cycle2() -> impl Clone {
diff --git a/src/test/ui/issues/issue-35241.stderr b/src/test/ui/issues/issue-35241.stderr
index 9ee7654a0885d..42a78ed97e025 100644
--- a/src/test/ui/issues/issue-35241.stderr
+++ b/src/test/ui/issues/issue-35241.stderr
@@ -11,7 +11,7 @@ LL | fn test() -> Foo { Foo }
    |
    = note: expected struct `Foo`
              found fn item `fn(u32) -> Foo {Foo}`
-help: use parentheses to instantiate this tuple struct
+help: use parentheses to construct this tuple struct
    |
 LL | fn test() -> Foo { Foo(/* u32 */) }
    |                       +++++++++++
diff --git a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr
index 7f29709ce5095..b30bcfb776c8c 100644
--- a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr
+++ b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr
@@ -29,7 +29,7 @@ LL |     assert_eq!(a, 0);
    |     ^^^^^^^^^^^^^^^^ `fn() -> i32 {a}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
    = help: the trait `Debug` is not implemented for fn item `fn() -> i32 {a}`
-   = help: use parentheses to call the function: `a()`
+   = help: use parentheses to call this function: `a()`
    = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/lifetimes/elided-lifetime-in-param-pat.rs b/src/test/ui/lifetimes/elided-lifetime-in-param-pat.rs
new file mode 100644
index 0000000000000..c1425fa4243d5
--- /dev/null
+++ b/src/test/ui/lifetimes/elided-lifetime-in-param-pat.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+struct S<T> {
+    _t: T,
+}
+
+fn f(S::<&i8> { .. }: S<&i8>) {}
+
+fn main() {
+    f(S { _t: &42_i8 });
+}
diff --git a/src/test/ui/mir/mir_let_chains_drop_order.rs b/src/test/ui/mir/mir_let_chains_drop_order.rs
index 536a84a352a49..6471553e93fd1 100644
--- a/src/test/ui/mir/mir_let_chains_drop_order.rs
+++ b/src/test/ui/mir/mir_let_chains_drop_order.rs
@@ -12,7 +12,7 @@ use std::panic;
 pub struct DropLogger<'a, T> {
     extra: T,
     id: usize,
-    log: &'a panic::AssertUnwindSafe<RefCell<Vec<usize>>>
+    log: &'a panic::AssertUnwindSafe<RefCell<Vec<usize>>>,
 }
 
 impl<'a, T> Drop for DropLogger<'a, T> {
@@ -55,9 +55,9 @@ fn main() {
             else {
                 // 10 is not constructed
                 d(10, None)
-            }
+            },
         );
-        assert_eq!(get(), vec![3, 8, 7, 1, 2]);
+        assert_eq!(get(), vec![8, 7, 1, 3, 2]);
     }
     assert_eq!(get(), vec![0, 4, 6, 9, 5]);
 
@@ -89,5 +89,5 @@ fn main() {
             panic::panic_any(InjectedFailure)
         );
     });
-    assert_eq!(get(), vec![14, 19, 20, 17, 15, 11, 18, 16, 12, 13]);
+    assert_eq!(get(), vec![20, 17, 15, 11, 19, 18, 16, 12, 14, 13]);
 }
diff --git a/src/test/ui/parser/fn-header-semantic-fail.stderr b/src/test/ui/parser/fn-header-semantic-fail.stderr
index 800b5a43a0066..038fdfb2d51b2 100644
--- a/src/test/ui/parser/fn-header-semantic-fail.stderr
+++ b/src/test/ui/parser/fn-header-semantic-fail.stderr
@@ -199,7 +199,7 @@ note: ...which requires borrow-checking `main::ff5`...
    |
 LL |     const async unsafe extern "C" fn ff5() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires processing `main::ff5`...
+note: ...which requires processing MIR for `main::ff5`...
   --> $DIR/fn-header-semantic-fail.rs:12:5
    |
 LL |     const async unsafe extern "C" fn ff5() {}
@@ -235,7 +235,7 @@ note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-
    |
 LL |         const async unsafe extern "C" fn ft5() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
+note: ...which requires processing MIR for `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
   --> $DIR/fn-header-semantic-fail.rs:33:9
    |
 LL |         const async unsafe extern "C" fn ft5() {}
@@ -271,7 +271,7 @@ note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-
    |
 LL |         const async unsafe extern "C" fn fi5() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5`...
+note: ...which requires processing MIR for `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5`...
   --> $DIR/fn-header-semantic-fail.rs:45:9
    |
 LL |         const async unsafe extern "C" fn fi5() {}
diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr
index a369dc6db5281..82a4211f08ac3 100644
--- a/src/test/ui/resolve/privacy-enum-ctor.stderr
+++ b/src/test/ui/resolve/privacy-enum-ctor.stderr
@@ -327,7 +327,7 @@ LL |         let _: Z = Z::Fn;
    |
    = note: expected enum `Z`
            found fn item `fn(u8) -> Z {Z::Fn}`
-help: use parentheses to instantiate this tuple variant
+help: use parentheses to construct this tuple variant
    |
 LL |         let _: Z = Z::Fn(/* u8 */);
    |                         ++++++++++
@@ -362,7 +362,7 @@ LL |     let _: E = m::E::Fn;
    |
    = note: expected enum `E`
            found fn item `fn(u8) -> E {E::Fn}`
-help: use parentheses to instantiate this tuple variant
+help: use parentheses to construct this tuple variant
    |
 LL |     let _: E = m::E::Fn(/* u8 */);
    |                        ++++++++++
@@ -397,7 +397,7 @@ LL |     let _: E = E::Fn;
    |
    = note: expected enum `E`
            found fn item `fn(u8) -> E {E::Fn}`
-help: use parentheses to instantiate this tuple variant
+help: use parentheses to construct this tuple variant
    |
 LL |     let _: E = E::Fn(/* u8 */);
    |                     ++++++++++
diff --git a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
index bfd506c9f6e0c..8ed62f854f096 100644
--- a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
+++ b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
@@ -1,9 +1,6 @@
 error[E0277]: `fn() -> impl Future<Output = ()> {foo}` is not a future
   --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:10:9
    |
-LL | async fn foo() {}
-   |          --- consider calling this function
-...
 LL |     bar(foo);
    |     --- ^^^ `fn() -> impl Future<Output = ()> {foo}` is not a future
    |     |
@@ -16,7 +13,7 @@ note: required by a bound in `bar`
    |
 LL | fn bar(f: impl Future<Output=()>) {}
    |                ^^^^^^^^^^^^^^^^^ required by this bound in `bar`
-help: use parentheses to call the function
+help: use parentheses to call this function
    |
 LL |     bar(foo());
    |            ++
@@ -24,8 +21,6 @@ LL |     bar(foo());
 error[E0277]: `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33]` is not a future
   --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:12:9
    |
-LL |     let async_closure = async || ();
-   |                         -------- consider calling this closure
 LL |     bar(async_closure);
    |     --- ^^^^^^^^^^^^^ `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33]` is not a future
    |     |
@@ -38,7 +33,7 @@ note: required by a bound in `bar`
    |
 LL | fn bar(f: impl Future<Output=()>) {}
    |                ^^^^^^^^^^^^^^^^^ required by this bound in `bar`
-help: use parentheses to call the closure
+help: use parentheses to call this closure
    |
 LL |     bar(async_closure());
    |                      ++
diff --git a/src/test/ui/suggestions/call-on-unimplemented-ctor.rs b/src/test/ui/suggestions/call-on-unimplemented-ctor.rs
new file mode 100644
index 0000000000000..5f811044eb349
--- /dev/null
+++ b/src/test/ui/suggestions/call-on-unimplemented-ctor.rs
@@ -0,0 +1,17 @@
+fn main() {
+    insert_resource(Marker);
+    insert_resource(Time);
+    //~^ ERROR the trait bound `fn(u32) -> Time {Time}: Resource` is not satisfied
+    //~| HELP use parentheses to construct this tuple struct
+}
+
+trait Resource {}
+
+fn insert_resource<R: Resource>(resource: R) {}
+
+struct Marker;
+impl Resource for Marker {}
+
+struct Time(u32);
+
+impl Resource for Time {}
diff --git a/src/test/ui/suggestions/call-on-unimplemented-ctor.stderr b/src/test/ui/suggestions/call-on-unimplemented-ctor.stderr
new file mode 100644
index 0000000000000..58612cbfb239e
--- /dev/null
+++ b/src/test/ui/suggestions/call-on-unimplemented-ctor.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the trait bound `fn(u32) -> Time {Time}: Resource` is not satisfied
+  --> $DIR/call-on-unimplemented-ctor.rs:3:21
+   |
+LL |     insert_resource(Time);
+   |     --------------- ^^^^ the trait `Resource` is not implemented for fn item `fn(u32) -> Time {Time}`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `insert_resource`
+  --> $DIR/call-on-unimplemented-ctor.rs:10:23
+   |
+LL | fn insert_resource<R: Resource>(resource: R) {}
+   |                       ^^^^^^^^ required by this bound in `insert_resource`
+help: use parentheses to construct this tuple struct
+   |
+LL |     insert_resource(Time(/* u32 */));
+   |                         +++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/call-on-unimplemented-fn-ptr.rs b/src/test/ui/suggestions/call-on-unimplemented-fn-ptr.rs
new file mode 100644
index 0000000000000..86490c724e018
--- /dev/null
+++ b/src/test/ui/suggestions/call-on-unimplemented-fn-ptr.rs
@@ -0,0 +1,15 @@
+struct Foo;
+
+trait Bar {}
+
+impl Bar for Foo {}
+
+fn needs_bar<T: Bar>(_: T) {}
+
+fn blah(f: fn() -> Foo) {
+    needs_bar(f);
+    //~^ ERROR the trait bound `fn() -> Foo: Bar` is not satisfied
+    //~| HELP use parentheses to call this function pointer
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/call-on-unimplemented-fn-ptr.stderr b/src/test/ui/suggestions/call-on-unimplemented-fn-ptr.stderr
new file mode 100644
index 0000000000000..167f7e592a97c
--- /dev/null
+++ b/src/test/ui/suggestions/call-on-unimplemented-fn-ptr.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the trait bound `fn() -> Foo: Bar` is not satisfied
+  --> $DIR/call-on-unimplemented-fn-ptr.rs:10:15
+   |
+LL |     needs_bar(f);
+   |     --------- ^ the trait `Bar` is not implemented for `fn() -> Foo`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `needs_bar`
+  --> $DIR/call-on-unimplemented-fn-ptr.rs:7:17
+   |
+LL | fn needs_bar<T: Bar>(_: T) {}
+   |                 ^^^ required by this bound in `needs_bar`
+help: use parentheses to call this function pointer
+   |
+LL |     needs_bar(f());
+   |                ++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
index fe603b67575d3..955148315baef 100644
--- a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
+++ b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
@@ -1,9 +1,6 @@
 error[E0277]: the trait bound `fn() -> impl T<O = ()> {foo}: T` is not satisfied
   --> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:17:9
    |
-LL | fn foo() -> impl T<O=()> { S }
-   |    --- consider calling this function
-...
 LL |     bar(foo);
    |     --- ^^^ the trait `T` is not implemented for fn item `fn() -> impl T<O = ()> {foo}`
    |     |
@@ -14,7 +11,7 @@ note: required by a bound in `bar`
    |
 LL | fn bar(f: impl T<O=()>) {}
    |                ^^^^^^^ required by this bound in `bar`
-help: use parentheses to call the function
+help: use parentheses to call this function
    |
 LL |     bar(foo());
    |            ++
@@ -22,8 +19,6 @@ LL |     bar(foo());
 error[E0277]: the trait bound `[closure@$DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:18:19: 18:21]: T` is not satisfied
   --> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:19:9
    |
-LL |     let closure = || S;
-   |                   -- consider calling this closure
 LL |     bar(closure);
    |     --- ^^^^^^^ the trait `T` is not implemented for closure `[closure@$DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:18:19: 18:21]`
    |     |
@@ -34,7 +29,7 @@ note: required by a bound in `bar`
    |
 LL | fn bar(f: impl T<O=()>) {}
    |                ^^^^^^^ required by this bound in `bar`
-help: use parentheses to call the closure
+help: use parentheses to call this closure
    |
 LL |     bar(closure());
    |                ++
diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
index f05dba1d4ca7e..597dc61c3f7e2 100644
--- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
+++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
@@ -49,7 +49,7 @@ LL |     let _: S = S;
    |
    = note: expected struct `S`
              found fn item `fn(usize, usize) -> S {S}`
-help: use parentheses to instantiate this tuple struct
+help: use parentheses to construct this tuple struct
    |
 LL |     let _: S = S(/* usize */, /* usize */);
    |                 ++++++++++++++++++++++++++
@@ -85,7 +85,7 @@ LL |     let _: V = V;
    |
    = note: expected struct `V`
              found fn item `fn() -> V {V}`
-help: use parentheses to instantiate this tuple struct
+help: use parentheses to construct this tuple struct
    |
 LL |     let _: V = V();
    |                 ++
@@ -139,7 +139,7 @@ LL |     let _: E = E::A;
    |
    = note: expected enum `E`
            found fn item `fn(usize) -> E {E::A}`
-help: use parentheses to instantiate this tuple variant
+help: use parentheses to construct this tuple variant
    |
 LL |     let _: E = E::A(/* usize */);
    |                    +++++++++++++
diff --git a/src/test/ui/treat-err-as-bug/delay_span_bug.rs b/src/test/ui/treat-err-as-bug/delay_span_bug.rs
index d4d44049c9186..832afddf89147 100644
--- a/src/test/ui/treat-err-as-bug/delay_span_bug.rs
+++ b/src/test/ui/treat-err-as-bug/delay_span_bug.rs
@@ -1,7 +1,7 @@
 // compile-flags: -Ztreat-err-as-bug
 // failure-status: 101
 // error-pattern: aborting due to `-Z treat-err-as-bug=1`
-// error-pattern: [trigger_delay_span_bug] trigger a delay span bug
+// error-pattern: [trigger_delay_span_bug] triggering a delay span bug
 // normalize-stderr-test "note: .*\n\n" -> ""
 // normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
 // rustc-env:RUST_BACKTRACE=0
diff --git a/src/test/ui/treat-err-as-bug/delay_span_bug.stderr b/src/test/ui/treat-err-as-bug/delay_span_bug.stderr
index c23c2b81b9767..e9457c8faff4d 100644
--- a/src/test/ui/treat-err-as-bug/delay_span_bug.stderr
+++ b/src/test/ui/treat-err-as-bug/delay_span_bug.stderr
@@ -7,5 +7,5 @@ LL | fn main() {}
 error: internal compiler error: unexpected panic
 
 query stack during panic:
-#0 [trigger_delay_span_bug] trigger a delay span bug
+#0 [trigger_delay_span_bug] triggering a delay span bug
 end of query stack
diff --git a/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr b/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr
index a18c54a29b52c..23e7b7cc363fe 100644
--- a/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr
+++ b/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr
@@ -4,7 +4,7 @@ error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo}` in the
 LL |     thing.bar.foo();
    |               ^^^ method not found in `fn() -> Foo {Foo}`
    |
-help: use parentheses to instantiate this tuple struct
+help: use parentheses to construct this tuple struct
    |
 LL |     (thing.bar)().foo();
    |     +         +++
diff --git a/src/test/ui/typeck/issue-87181/enum-variant.stderr b/src/test/ui/typeck/issue-87181/enum-variant.stderr
index 90641410d8e96..2247ea27021f4 100644
--- a/src/test/ui/typeck/issue-87181/enum-variant.stderr
+++ b/src/test/ui/typeck/issue-87181/enum-variant.stderr
@@ -4,7 +4,7 @@ error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo::Tup}` i
 LL |     thing.bar.foo();
    |               ^^^ method not found in `fn() -> Foo {Foo::Tup}`
    |
-help: use parentheses to instantiate this tuple variant
+help: use parentheses to construct this tuple variant
    |
 LL |     (thing.bar)().foo();
    |     +         +++
diff --git a/src/test/ui/typeck/issue-87181/tuple-field.stderr b/src/test/ui/typeck/issue-87181/tuple-field.stderr
index c1ca26ee9af1d..0a7d30b615a63 100644
--- a/src/test/ui/typeck/issue-87181/tuple-field.stderr
+++ b/src/test/ui/typeck/issue-87181/tuple-field.stderr
@@ -4,7 +4,7 @@ error[E0609]: no field `0` on type `fn(char, u16) -> Foo {Foo}`
 LL |     thing.bar.0;
    |               ^
    |
-help: use parentheses to instantiate this tuple struct
+help: use parentheses to construct this tuple struct
    |
 LL |     (thing.bar)(/* char */, /* u16 */).0;
    |     +         ++++++++++++++++++++++++