diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 325b0458638af..25013036d8749 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -511,7 +511,7 @@ impl<'a> Resolver<'a> {
                 err.span_label(span, "use of generic parameter from outer function");
 
                 let sm = self.session.source_map();
-                match outer_res {
+                let def_id = match outer_res {
                     Res::SelfTy { trait_: maybe_trait_defid, alias_to: maybe_impl_defid } => {
                         if let Some(impl_span) =
                             maybe_impl_defid.and_then(|(def_id, _)| self.opt_span(def_id))
@@ -536,11 +536,13 @@ impl<'a> Resolver<'a> {
                         if let Some(span) = self.opt_span(def_id) {
                             err.span_label(span, "type parameter from outer function");
                         }
+                        def_id
                     }
                     Res::Def(DefKind::ConstParam, def_id) => {
                         if let Some(span) = self.opt_span(def_id) {
                             err.span_label(span, "const parameter from outer function");
                         }
+                        def_id
                     }
                     _ => {
                         bug!(
@@ -548,28 +550,23 @@ impl<'a> Resolver<'a> {
                             DefKind::TyParam or DefKind::ConstParam"
                         );
                     }
-                }
+                };
 
-                if has_generic_params == HasGenericParams::Yes {
+                if let HasGenericParams::Yes(span) = has_generic_params {
                     // Try to retrieve the span of the function signature and generate a new
                     // message with a local type or const parameter.
                     let sugg_msg = "try using a local generic parameter instead";
-                    if let Some((sugg_span, snippet)) = sm.generate_local_type_param_snippet(span) {
-                        // Suggest the modification to the user
-                        err.span_suggestion(
-                            sugg_span,
-                            sugg_msg,
-                            snippet,
-                            Applicability::MachineApplicable,
-                        );
-                    } else if let Some(sp) = sm.generate_fn_name_span(span) {
-                        err.span_label(
-                            sp,
-                            "try adding a local generic parameter in this method instead",
-                        );
+                    let name = self.opt_name(def_id).unwrap_or(sym::T);
+                    let (span, snippet) = if span.is_empty() {
+                        let snippet = format!("<{}>", name);
+                        (span, snippet)
                     } else {
-                        err.help("try using a local generic parameter instead");
-                    }
+                        let span = sm.span_through_char(span, '<').shrink_to_hi();
+                        let snippet = format!("{}, ", name);
+                        (span, snippet)
+                    };
+                    // Suggest the modification to the user
+                    err.span_suggestion(span, sugg_msg, snippet, Applicability::MaybeIncorrect);
                 }
 
                 err
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 6e6782881427b..41a0c76d83a95 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -13,7 +13,9 @@ use rustc_span::{Span, DUMMY_SP};
 
 use std::ptr;
 
-use crate::late::{ConstantItemKind, HasGenericParams, PathSource, Rib, RibKind};
+use crate::late::{
+    ConstantHasGenerics, ConstantItemKind, HasGenericParams, PathSource, Rib, RibKind,
+};
 use crate::macros::{sub_namespace_match, MacroRulesScope};
 use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize};
 use crate::{ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot};
@@ -1103,7 +1105,7 @@ impl<'a> Resolver<'a> {
                         | ForwardGenericParamBanRibKind => {
                             // Nothing to do. Continue.
                         }
-                        ItemRibKind(_) | FnItemRibKind | AssocItemRibKind => {
+                        ItemRibKind(_) | AssocItemRibKind => {
                             // This was an attempt to access an upvar inside a
                             // named function item. This is not allowed, so we
                             // report an error.
@@ -1168,10 +1170,10 @@ impl<'a> Resolver<'a> {
                     let has_generic_params: HasGenericParams = match rib.kind {
                         NormalRibKind
                         | ClosureOrAsyncRibKind
-                        | AssocItemRibKind
                         | ModuleRibKind(..)
                         | MacroDefinition(..)
                         | InlineAsmSymRibKind
+                        | AssocItemRibKind
                         | ForwardGenericParamBanRibKind => {
                             // Nothing to do. Continue.
                             continue;
@@ -1180,7 +1182,9 @@ impl<'a> Resolver<'a> {
                         ConstantItemRibKind(trivial, _) => {
                             let features = self.session.features_untracked();
                             // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
-                            if !(trivial == HasGenericParams::Yes || features.generic_const_exprs) {
+                            if !(trivial == ConstantHasGenerics::Yes
+                                || features.generic_const_exprs)
+                            {
                                 // HACK(min_const_generics): If we encounter `Self` in an anonymous constant
                                 // we can't easily tell if it's generic at this stage, so we instead remember
                                 // this and then enforce the self type to be concrete later on.
@@ -1207,7 +1211,6 @@ impl<'a> Resolver<'a> {
 
                         // This was an attempt to use a type parameter outside its scope.
                         ItemRibKind(has_generic_params) => has_generic_params,
-                        FnItemRibKind => HasGenericParams::Yes,
                         ConstParamTyRibKind => {
                             if let Some(span) = finalize {
                                 self.report_error(
@@ -1232,28 +1235,22 @@ impl<'a> Resolver<'a> {
                 }
             }
             Res::Def(DefKind::ConstParam, _) => {
-                let mut ribs = ribs.iter().peekable();
-                if let Some(Rib { kind: FnItemRibKind, .. }) = ribs.peek() {
-                    // When declaring const parameters inside function signatures, the first rib
-                    // is always a `FnItemRibKind`. In this case, we can skip it, to avoid it
-                    // (spuriously) conflicting with the const param.
-                    ribs.next();
-                }
-
                 for rib in ribs {
                     let has_generic_params = match rib.kind {
                         NormalRibKind
                         | ClosureOrAsyncRibKind
-                        | AssocItemRibKind
                         | ModuleRibKind(..)
                         | MacroDefinition(..)
                         | InlineAsmSymRibKind
+                        | AssocItemRibKind
                         | ForwardGenericParamBanRibKind => continue,
 
                         ConstantItemRibKind(trivial, _) => {
                             let features = self.session.features_untracked();
                             // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
-                            if !(trivial == HasGenericParams::Yes || features.generic_const_exprs) {
+                            if !(trivial == ConstantHasGenerics::Yes
+                                || features.generic_const_exprs)
+                            {
                                 if let Some(span) = finalize {
                                     self.report_error(
                                         span,
@@ -1272,7 +1269,6 @@ impl<'a> Resolver<'a> {
                         }
 
                         ItemRibKind(has_generic_params) => has_generic_params,
-                        FnItemRibKind => HasGenericParams::Yes,
                         ConstParamTyRibKind => {
                             if let Some(span) = finalize {
                                 self.report_error(
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 58a4cff55db7d..693ec86616ee4 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -91,13 +91,20 @@ enum PatBoundCtx {
 }
 
 /// Does this the item (from the item rib scope) allow generic parameters?
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[derive(Copy, Clone, Debug)]
 pub(crate) enum HasGenericParams {
+    Yes(Span),
+    No,
+}
+
+/// May this constant have generics?
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub(crate) enum ConstantHasGenerics {
     Yes,
     No,
 }
 
-impl HasGenericParams {
+impl ConstantHasGenerics {
     fn force_yes_if(self, b: bool) -> Self {
         if b { Self::Yes } else { self }
     }
@@ -125,10 +132,6 @@ pub(crate) enum RibKind<'a> {
     /// We passed through a closure. Disallow labels.
     ClosureOrAsyncRibKind,
 
-    /// We passed through a function definition. Disallow upvars.
-    /// Permit only those const parameters that are specified in the function's generics.
-    FnItemRibKind,
-
     /// We passed through an item scope. Disallow upvars.
     ItemRibKind(HasGenericParams),
 
@@ -136,7 +139,7 @@ pub(crate) enum RibKind<'a> {
     ///
     /// The item may reference generic parameters in trivial constant expressions.
     /// All other constants aren't allowed to use generic params at all.
-    ConstantItemRibKind(HasGenericParams, Option<(Ident, ConstantItemKind)>),
+    ConstantItemRibKind(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>),
 
     /// We passed through a module.
     ModuleRibKind(Module<'a>),
@@ -165,7 +168,6 @@ impl RibKind<'_> {
         match self {
             NormalRibKind
             | ClosureOrAsyncRibKind
-            | FnItemRibKind
             | ConstantItemRibKind(..)
             | ModuleRibKind(_)
             | MacroDefinition(_)
@@ -182,7 +184,6 @@ impl RibKind<'_> {
 
             AssocItemRibKind
             | ClosureOrAsyncRibKind
-            | FnItemRibKind
             | ItemRibKind(..)
             | ConstantItemRibKind(..)
             | ModuleRibKind(..)
@@ -751,7 +752,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                 self.with_lifetime_rib(LifetimeRibKind::Item, |this| {
                     this.with_generic_param_rib(
                         &generics.params,
-                        ItemRibKind(HasGenericParams::Yes),
+                        ItemRibKind(HasGenericParams::Yes(generics.span)),
                         LifetimeRibKind::Generics {
                             binder: foreign_item.id,
                             kind: LifetimeBinderKind::Item,
@@ -765,7 +766,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                 self.with_lifetime_rib(LifetimeRibKind::Item, |this| {
                     this.with_generic_param_rib(
                         &generics.params,
-                        ItemRibKind(HasGenericParams::Yes),
+                        ItemRibKind(HasGenericParams::Yes(generics.span)),
                         LifetimeRibKind::Generics {
                             binder: foreign_item.id,
                             kind: LifetimeBinderKind::Function,
@@ -786,7 +787,8 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
         }
     }
     fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, fn_id: NodeId) {
-        let rib_kind = match fn_kind {
+        let previous_value = self.diagnostic_metadata.current_function;
+        match fn_kind {
             // Bail if the function is foreign, and thus cannot validly have
             // a body, or if there's no body for some other reason.
             FnKind::Fn(FnCtxt::Foreign, _, sig, _, generics, _)
@@ -809,20 +811,18 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                 );
                 return;
             }
-            FnKind::Fn(FnCtxt::Free, ..) => FnItemRibKind,
-            FnKind::Fn(FnCtxt::Assoc(_), ..) => NormalRibKind,
-            FnKind::Closure(..) => ClosureOrAsyncRibKind,
+            FnKind::Fn(..) => {
+                self.diagnostic_metadata.current_function = Some((fn_kind, sp));
+            }
+            // Do not update `current_function` for closures: it suggests `self` parameters.
+            FnKind::Closure(..) => {}
         };
-        let previous_value = self.diagnostic_metadata.current_function;
-        if matches!(fn_kind, FnKind::Fn(..)) {
-            self.diagnostic_metadata.current_function = Some((fn_kind, sp));
-        }
         debug!("(resolving function) entering function");
 
         // Create a value rib for the function.
-        self.with_rib(ValueNS, rib_kind, |this| {
+        self.with_rib(ValueNS, ClosureOrAsyncRibKind, |this| {
             // Create a label rib for the function.
-            this.with_label_rib(FnItemRibKind, |this| {
+            this.with_label_rib(ClosureOrAsyncRibKind, |this| {
                 match fn_kind {
                     FnKind::Fn(_, _, sig, _, generics, body) => {
                         this.visit_generics(generics);
@@ -995,7 +995,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                             // non-trivial constants this is doesn't matter.
                             self.with_constant_rib(
                                 IsRepeatExpr::No,
-                                HasGenericParams::Yes,
+                                ConstantHasGenerics::Yes,
                                 None,
                                 |this| {
                                     this.smart_resolve_path(
@@ -2071,7 +2071,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         self.with_current_self_item(item, |this| {
             this.with_generic_param_rib(
                 &generics.params,
-                ItemRibKind(HasGenericParams::Yes),
+                ItemRibKind(HasGenericParams::Yes(generics.span)),
                 LifetimeRibKind::Generics {
                     binder: item.id,
                     kind: LifetimeBinderKind::Item,
@@ -2141,7 +2141,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             ItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes),
+                    ItemRibKind(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Item,
@@ -2154,7 +2154,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             ItemKind::Fn(box Fn { ref generics, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes),
+                    ItemRibKind(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Function,
@@ -2186,7 +2186,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 // Create a new rib for the trait-wide type parameters.
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes),
+                    ItemRibKind(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Item,
@@ -2210,7 +2210,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 // Create a new rib for the trait-wide type parameters.
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes),
+                    ItemRibKind(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Item,
@@ -2251,7 +2251,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                             // so it doesn't matter whether this is a trivial constant.
                             this.with_constant_rib(
                                 IsRepeatExpr::No,
-                                HasGenericParams::Yes,
+                                ConstantHasGenerics::Yes,
                                 Some((item.ident, constant_item_kind)),
                                 |this| this.visit_expr(expr),
                             );
@@ -2450,7 +2450,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
     fn with_constant_rib(
         &mut self,
         is_repeat: IsRepeatExpr,
-        may_use_generics: HasGenericParams,
+        may_use_generics: ConstantHasGenerics,
         item: Option<(Ident, ConstantItemKind)>,
         f: impl FnOnce(&mut Self),
     ) {
@@ -2517,7 +2517,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                             |this| {
                                 this.with_constant_rib(
                                     IsRepeatExpr::No,
-                                    HasGenericParams::Yes,
+                                    ConstantHasGenerics::Yes,
                                     None,
                                     |this| this.visit_expr(expr),
                                 )
@@ -2598,7 +2598,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         // If applicable, create a rib for the type parameters.
         self.with_generic_param_rib(
             &generics.params,
-            ItemRibKind(HasGenericParams::Yes),
+            ItemRibKind(HasGenericParams::Yes(generics.span)),
             LifetimeRibKind::Generics {
                 span: generics.span,
                 binder: item_id,
@@ -2689,7 +2689,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
                         this.with_constant_rib(
                             IsRepeatExpr::No,
-                            HasGenericParams::Yes,
+                            ConstantHasGenerics::Yes,
                             None,
                             |this| this.visit_expr(expr),
                         )
@@ -3696,9 +3696,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         self.with_constant_rib(
             is_repeat,
             if constant.value.is_potential_trivial_const_param() {
-                HasGenericParams::Yes
+                ConstantHasGenerics::Yes
             } else {
-                HasGenericParams::No
+                ConstantHasGenerics::No
             },
             None,
             |this| visit::walk_anon_const(this, constant),
@@ -3707,8 +3707,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
 
     fn resolve_inline_const(&mut self, constant: &'ast AnonConst) {
         debug!("resolve_anon_const {constant:?}");
-        self.with_constant_rib(IsRepeatExpr::No, HasGenericParams::Yes, None, |this| {
-            visit::walk_anon_const(this, constant);
+        self.with_constant_rib(IsRepeatExpr::No, ConstantHasGenerics::Yes, None, |this| {
+            visit::walk_anon_const(this, constant)
         });
     }
 
@@ -3814,9 +3814,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                         self.with_constant_rib(
                             IsRepeatExpr::No,
                             if argument.is_potential_trivial_const_param() {
-                                HasGenericParams::Yes
+                                ConstantHasGenerics::Yes
                             } else {
-                                HasGenericParams::No
+                                ConstantHasGenerics::No
                             },
                             None,
                             |this| {
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 9c213da8c2a2c..eb727debc91bb 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1945,6 +1945,16 @@ impl<'a> Resolver<'a> {
         def_id.as_local().map(|def_id| self.source_span[def_id])
     }
 
+    /// Retrieves the name of the given `DefId`.
+    #[inline]
+    pub fn opt_name(&self, def_id: DefId) -> Option<Symbol> {
+        let def_key = match def_id.as_local() {
+            Some(def_id) => self.definitions.def_key(def_id),
+            None => self.cstore().def_key(def_id),
+        };
+        def_key.get_opt_name()
+    }
+
     /// Checks if an expression refers to a function marked with
     /// `#[rustc_legacy_const_generics]` and returns the argument index list
     /// from the attribute.
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index 5f928707ea826..a32cabab4c407 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -982,93 +982,6 @@ impl SourceMap {
         self.files().iter().fold(0, |a, f| a + f.count_lines())
     }
 
-    pub fn generate_fn_name_span(&self, span: Span) -> Option<Span> {
-        let prev_span = self.span_extend_to_prev_str(span, "fn", true, true)?;
-        if let Ok(snippet) = self.span_to_snippet(prev_span) {
-            debug!(
-                "generate_fn_name_span: span={:?}, prev_span={:?}, snippet={:?}",
-                span, prev_span, snippet
-            );
-
-            if snippet.is_empty() {
-                return None;
-            };
-
-            let len = snippet
-                .find(|c: char| !c.is_alphanumeric() && c != '_')
-                .expect("no label after fn");
-            Some(prev_span.with_hi(BytePos(prev_span.lo().0 + len as u32)))
-        } else {
-            None
-        }
-    }
-
-    /// Takes the span of a type parameter in a function signature and try to generate a span for
-    /// the function name (with generics) and a new snippet for this span with the pointed type
-    /// parameter as a new local type parameter.
-    ///
-    /// For instance:
-    /// ```rust,ignore (pseudo-Rust)
-    /// // Given span
-    /// fn my_function(param: T)
-    /// //                    ^ Original span
-    ///
-    /// // Result
-    /// fn my_function(param: T)
-    /// // ^^^^^^^^^^^ Generated span with snippet `my_function<T>`
-    /// ```
-    ///
-    /// Attention: The method used is very fragile since it essentially duplicates the work of the
-    /// parser. If you need to use this function or something similar, please consider updating the
-    /// `SourceMap` functions and this function to something more robust.
-    pub fn generate_local_type_param_snippet(&self, span: Span) -> Option<(Span, String)> {
-        // Try to extend the span to the previous "fn" keyword to retrieve the function
-        // signature.
-        if let Some(sugg_span) = self.span_extend_to_prev_str(span, "fn", false, true) {
-            if let Ok(snippet) = self.span_to_snippet(sugg_span) {
-                // Consume the function name.
-                let mut offset = snippet
-                    .find(|c: char| !c.is_alphanumeric() && c != '_')
-                    .expect("no label after fn");
-
-                // Consume the generics part of the function signature.
-                let mut bracket_counter = 0;
-                let mut last_char = None;
-                for c in snippet[offset..].chars() {
-                    match c {
-                        '<' => bracket_counter += 1,
-                        '>' => bracket_counter -= 1,
-                        '(' => {
-                            if bracket_counter == 0 {
-                                break;
-                            }
-                        }
-                        _ => {}
-                    }
-                    offset += c.len_utf8();
-                    last_char = Some(c);
-                }
-
-                // Adjust the suggestion span to encompass the function name with its generics.
-                let sugg_span = sugg_span.with_hi(BytePos(sugg_span.lo().0 + offset as u32));
-
-                // Prepare the new suggested snippet to append the type parameter that triggered
-                // the error in the generics of the function signature.
-                let mut new_snippet = if last_char == Some('>') {
-                    format!("{}, ", &snippet[..(offset - '>'.len_utf8())])
-                } else {
-                    format!("{}<", &snippet[..offset])
-                };
-                new_snippet
-                    .push_str(&self.span_to_snippet(span).unwrap_or_else(|_| "T".to_string()));
-                new_snippet.push('>');
-
-                return Some((sugg_span, new_snippet));
-            }
-        }
-
-        None
-    }
     pub fn ensure_source_file_source_present(&self, source_file: Lrc<SourceFile>) -> bool {
         source_file.add_external_src(|| {
             match source_file.name {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 156f53ac48626..c8978845ffb0d 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -280,6 +280,7 @@ symbols! {
         StructuralPartialEq,
         SubdiagnosticMessage,
         Sync,
+        T,
         Target,
         ToOwned,
         ToString,
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index dfef924f6993a..df171c2531a7a 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -858,8 +858,7 @@ fn compare_synthetic_generics<'tcx>(
     {
         if impl_synthetic != trait_synthetic {
             let impl_def_id = impl_def_id.expect_local();
-            let impl_hir_id = tcx.hir().local_def_id_to_hir_id(impl_def_id);
-            let impl_span = tcx.hir().span(impl_hir_id);
+            let impl_span = tcx.def_span(impl_def_id);
             let trait_span = tcx.def_span(trait_def_id);
             let mut err = struct_span_err!(
                 tcx.sess,
@@ -878,17 +877,16 @@ fn compare_synthetic_generics<'tcx>(
                         // try taking the name from the trait impl
                         // FIXME: this is obviously suboptimal since the name can already be used
                         // as another generic argument
-                        let new_name = tcx.sess.source_map().span_to_snippet(trait_span).ok()?;
+                        let new_name = tcx.opt_item_name(trait_def_id)?;
                         let trait_m = trait_m.def_id.as_local()?;
-                        let trait_m = tcx.hir().trait_item(hir::TraitItemId { def_id: trait_m });
+                        let trait_m = tcx.hir().expect_trait_item(trait_m);
 
                         let impl_m = impl_m.def_id.as_local()?;
-                        let impl_m = tcx.hir().impl_item(hir::ImplItemId { def_id: impl_m });
+                        let impl_m = tcx.hir().expect_impl_item(impl_m);
 
                         // in case there are no generics, take the spot between the function name
                         // and the opening paren of the argument list
-                        let new_generics_span =
-                            tcx.sess.source_map().generate_fn_name_span(impl_span)?.shrink_to_hi();
+                        let new_generics_span = tcx.def_ident_span(impl_def_id)?.shrink_to_hi();
                         // in case there are generics, just replace them
                         let generics_span =
                             impl_m.generics.span.substitute_dummy(new_generics_span);
@@ -900,7 +898,7 @@ fn compare_synthetic_generics<'tcx>(
                             "try changing the `impl Trait` argument to a generic parameter",
                             vec![
                                 // replace `impl Trait` with `T`
-                                (impl_span, new_name),
+                                (impl_span, new_name.to_string()),
                                 // replace impl method generics with trait method generics
                                 // This isn't quite right, as users might have changed the names
                                 // of the generics, but it works for the common case
@@ -917,7 +915,7 @@ fn compare_synthetic_generics<'tcx>(
                     err.span_label(impl_span, "expected `impl Trait`, found generic parameter");
                     (|| {
                         let impl_m = impl_m.def_id.as_local()?;
-                        let impl_m = tcx.hir().impl_item(hir::ImplItemId { def_id: impl_m });
+                        let impl_m = tcx.hir().expect_impl_item(impl_m);
                         let input_tys = match impl_m.kind {
                             hir::ImplItemKind::Fn(ref sig, _) => sig.decl.inputs,
                             _ => unreachable!(),
diff --git a/src/test/ui/const-generics/early/const-param-from-outer-fn.stderr b/src/test/ui/const-generics/early/const-param-from-outer-fn.stderr
index a9f9787d87595..e3bf38b702e75 100644
--- a/src/test/ui/const-generics/early/const-param-from-outer-fn.stderr
+++ b/src/test/ui/const-generics/early/const-param-from-outer-fn.stderr
@@ -4,7 +4,7 @@ error[E0401]: can't use generic parameters from outer function
 LL | fn foo<const X: u32>() {
    |              - const parameter from outer function
 LL |     fn bar() -> u32 {
-   |        --- try adding a local generic parameter in this method instead
+   |           - help: try using a local generic parameter instead: `<X>`
 LL |         X
    |         ^ use of generic parameter from outer function
 
diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr
index 81715621dd921..b0e2ef5b6f7e3 100644
--- a/src/test/ui/error-codes/E0401.stderr
+++ b/src/test/ui/error-codes/E0401.stderr
@@ -4,9 +4,9 @@ error[E0401]: can't use generic parameters from outer function
 LL | fn foo<T>(x: T) {
    |        - type parameter from outer function
 LL |     fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) {
-   |        ---------------------------    ^ use of generic parameter from outer function
-   |        |
-   |        help: try using a local generic parameter instead: `bfnr<U, V: Baz<U>, W: Fn(), T>`
+   |             -                         ^ use of generic parameter from outer function
+   |             |
+   |             help: try using a local generic parameter instead: `T,`
 
 error[E0401]: can't use generic parameters from outer function
   --> $DIR/E0401.rs:9:16
@@ -15,7 +15,7 @@ LL | fn foo<T>(x: T) {
    |        - type parameter from outer function
 ...
 LL |     fn baz<U,
-   |        --- try adding a local generic parameter in this method instead
+   |            - help: try using a local generic parameter instead: `T,`
 ...
 LL |            (y: T) {
    |                ^ use of generic parameter from outer function
diff --git a/src/test/ui/generics/issue-98432.stderr b/src/test/ui/generics/issue-98432.stderr
index afa67b63bd9a1..c7b5c33618d5f 100644
--- a/src/test/ui/generics/issue-98432.stderr
+++ b/src/test/ui/generics/issue-98432.stderr
@@ -5,9 +5,9 @@ LL | impl<T> Struct<T> {
    |      - type parameter from outer function
 LL |     const CONST: fn() = || {
 LL |         struct _Obligation where T:;
-   |                                  ^ use of generic parameter from outer function
-   |
-   = help: try using a local generic parameter instead
+   |                           -      ^ use of generic parameter from outer function
+   |                           |
+   |                           help: try using a local generic parameter instead: `<T>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-3214.stderr b/src/test/ui/issues/issue-3214.stderr
index 4d8eb6360e640..aa0b5ce64b421 100644
--- a/src/test/ui/issues/issue-3214.stderr
+++ b/src/test/ui/issues/issue-3214.stderr
@@ -2,10 +2,9 @@ error[E0401]: can't use generic parameters from outer function
   --> $DIR/issue-3214.rs:3:12
    |
 LL | fn foo<T>() {
-   |    --- - type parameter from outer function
-   |    |
-   |    try adding a local generic parameter in this method instead
+   |        - type parameter from outer function
 LL |     struct Foo {
+   |               - help: try using a local generic parameter instead: `<T>`
 LL |         x: T,
    |            ^ use of generic parameter from outer function
 
diff --git a/src/test/ui/issues/issue-5997-enum.stderr b/src/test/ui/issues/issue-5997-enum.stderr
index 1c58b9c391104..3a79215d3ae9c 100644
--- a/src/test/ui/issues/issue-5997-enum.stderr
+++ b/src/test/ui/issues/issue-5997-enum.stderr
@@ -2,11 +2,11 @@ error[E0401]: can't use generic parameters from outer function
   --> $DIR/issue-5997-enum.rs:2:16
    |
 LL | fn f<Z>() -> bool {
-   |    - - type parameter from outer function
-   |    |
-   |    try adding a local generic parameter in this method instead
+   |      - type parameter from outer function
 LL |     enum E { V(Z) }
-   |                ^ use of generic parameter from outer function
+   |           -    ^ use of generic parameter from outer function
+   |           |
+   |           help: try using a local generic parameter instead: `<Z>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-5997-struct.stderr b/src/test/ui/issues/issue-5997-struct.stderr
index 5b388d16d7553..d2e97f767719f 100644
--- a/src/test/ui/issues/issue-5997-struct.stderr
+++ b/src/test/ui/issues/issue-5997-struct.stderr
@@ -2,11 +2,11 @@ error[E0401]: can't use generic parameters from outer function
   --> $DIR/issue-5997-struct.rs:2:14
    |
 LL | fn f<T>() -> bool {
-   |    - - type parameter from outer function
-   |    |
-   |    try adding a local generic parameter in this method instead
+   |      - type parameter from outer function
 LL |     struct S(T);
-   |              ^ use of generic parameter from outer function
+   |             -^ use of generic parameter from outer function
+   |             |
+   |             help: try using a local generic parameter instead: `<T>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nested-ty-params.stderr b/src/test/ui/nested-ty-params.stderr
index f6741b5e5e82a..8f4746f5ec3bd 100644
--- a/src/test/ui/nested-ty-params.stderr
+++ b/src/test/ui/nested-ty-params.stderr
@@ -4,9 +4,9 @@ error[E0401]: can't use generic parameters from outer function
 LL | fn hd<U>(v: Vec<U> ) -> U {
    |       - type parameter from outer function
 LL |     fn hd1(w: [U]) -> U { return w[0]; }
-   |        ---     ^ use of generic parameter from outer function
-   |        |
-   |        help: try using a local generic parameter instead: `hd1<U>`
+   |           -    ^ use of generic parameter from outer function
+   |           |
+   |           help: try using a local generic parameter instead: `<U>`
 
 error[E0401]: can't use generic parameters from outer function
   --> $DIR/nested-ty-params.rs:3:23
@@ -14,9 +14,9 @@ error[E0401]: can't use generic parameters from outer function
 LL | fn hd<U>(v: Vec<U> ) -> U {
    |       - type parameter from outer function
 LL |     fn hd1(w: [U]) -> U { return w[0]; }
-   |        ---            ^ use of generic parameter from outer function
-   |        |
-   |        help: try using a local generic parameter instead: `hd1<U>`
+   |           -           ^ use of generic parameter from outer function
+   |           |
+   |           help: try using a local generic parameter instead: `<U>`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/resolve/bad-type-env-capture.stderr b/src/test/ui/resolve/bad-type-env-capture.stderr
index 6f24c0d86997e..b6282c2d0703b 100644
--- a/src/test/ui/resolve/bad-type-env-capture.stderr
+++ b/src/test/ui/resolve/bad-type-env-capture.stderr
@@ -4,9 +4,9 @@ error[E0401]: can't use generic parameters from outer function
 LL | fn foo<T>() {
    |        - type parameter from outer function
 LL |     fn bar(b: T) { }
-   |        ---    ^ use of generic parameter from outer function
-   |        |
-   |        help: try using a local generic parameter instead: `bar<T>`
+   |           -   ^ use of generic parameter from outer function
+   |           |
+   |           help: try using a local generic parameter instead: `<T>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/resolve/issue-3021-c.stderr b/src/test/ui/resolve/issue-3021-c.stderr
index 8764ac8a8563c..5176efc3a6be7 100644
--- a/src/test/ui/resolve/issue-3021-c.stderr
+++ b/src/test/ui/resolve/issue-3021-c.stderr
@@ -3,22 +3,22 @@ error[E0401]: can't use generic parameters from outer function
    |
 LL | fn siphash<T>() {
    |            - type parameter from outer function
-...
+LL |
+LL |     trait U {
+   |            - help: try using a local generic parameter instead: `<T>`
 LL |         fn g(&self, x: T) -> T;
-   |            -           ^ use of generic parameter from outer function
-   |            |
-   |            help: try using a local generic parameter instead: `g<T>`
+   |                        ^ use of generic parameter from outer function
 
 error[E0401]: can't use generic parameters from outer function
   --> $DIR/issue-3021-c.rs:4:30
    |
 LL | fn siphash<T>() {
    |            - type parameter from outer function
-...
+LL |
+LL |     trait U {
+   |            - help: try using a local generic parameter instead: `<T>`
 LL |         fn g(&self, x: T) -> T;
-   |            -                 ^ use of generic parameter from outer function
-   |            |
-   |            help: try using a local generic parameter instead: `g<T>`
+   |                              ^ use of generic parameter from outer function
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr
index 10a703ee09351..0a6d1cc3bcd45 100644
--- a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr
+++ b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr
@@ -4,8 +4,8 @@ error[E0401]: can't use generic parameters from outer function
 LL | trait TraitA<A> {
    |              - type parameter from outer function
 LL |     fn outer(&self) {
-   |        ----- try adding a local generic parameter in this method instead
 LL |         enum Foo<B> {
+   |                  - help: try using a local generic parameter instead: `A,`
 LL |             Variance(A)
    |                      ^ use of generic parameter from outer function
 
@@ -15,9 +15,10 @@ error[E0401]: can't use generic parameters from outer function
 LL | trait TraitB<A> {
    |              - type parameter from outer function
 LL |     fn outer(&self) {
-   |        ----- try adding a local generic parameter in this method instead
 LL |         struct Foo<B>(A);
-   |                       ^ use of generic parameter from outer function
+   |                    -  ^ use of generic parameter from outer function
+   |                    |
+   |                    help: try using a local generic parameter instead: `A,`
 
 error[E0401]: can't use generic parameters from outer function
   --> $DIR/resolve-type-param-in-item-in-trait.rs:23:28
@@ -25,9 +26,10 @@ error[E0401]: can't use generic parameters from outer function
 LL | trait TraitC<A> {
    |              - type parameter from outer function
 LL |     fn outer(&self) {
-   |        ----- try adding a local generic parameter in this method instead
 LL |         struct Foo<B> { a: A }
-   |                            ^ use of generic parameter from outer function
+   |                    -       ^ use of generic parameter from outer function
+   |                    |
+   |                    help: try using a local generic parameter instead: `A,`
 
 error[E0401]: can't use generic parameters from outer function
   --> $DIR/resolve-type-param-in-item-in-trait.rs:30:22
@@ -36,9 +38,9 @@ LL | trait TraitD<A> {
    |              - type parameter from outer function
 LL |     fn outer(&self) {
 LL |         fn foo<B>(a: A) { }
-   |            ------    ^ use of generic parameter from outer function
-   |            |
-   |            help: try using a local generic parameter instead: `foo<B, A>`
+   |                -     ^ use of generic parameter from outer function
+   |                |
+   |                help: try using a local generic parameter instead: `A,`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/type/type-arg-out-of-scope.stderr b/src/test/ui/type/type-arg-out-of-scope.stderr
index 0b6283fbc51e9..7f18b4510f4b2 100644
--- a/src/test/ui/type/type-arg-out-of-scope.stderr
+++ b/src/test/ui/type/type-arg-out-of-scope.stderr
@@ -4,9 +4,9 @@ error[E0401]: can't use generic parameters from outer function
 LL | fn foo<T>(x: T) {
    |        - type parameter from outer function
 LL |     fn bar(f: Box<dyn FnMut(T) -> T>) { }
-   |        ---                  ^ use of generic parameter from outer function
-   |        |
-   |        help: try using a local generic parameter instead: `bar<T>`
+   |           -                 ^ use of generic parameter from outer function
+   |           |
+   |           help: try using a local generic parameter instead: `<T>`
 
 error[E0401]: can't use generic parameters from outer function
   --> $DIR/type-arg-out-of-scope.rs:3:35
@@ -14,9 +14,9 @@ error[E0401]: can't use generic parameters from outer function
 LL | fn foo<T>(x: T) {
    |        - type parameter from outer function
 LL |     fn bar(f: Box<dyn FnMut(T) -> T>) { }
-   |        ---                        ^ use of generic parameter from outer function
-   |        |
-   |        help: try using a local generic parameter instead: `bar<T>`
+   |           -                       ^ use of generic parameter from outer function
+   |           |
+   |           help: try using a local generic parameter instead: `<T>`
 
 error: aborting due to 2 previous errors