diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index c506360aa8a..4da09c4ef48 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -313,6 +313,13 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         });
     }
 
+    fn visit_assoc_type_binding(&mut self, type_binding: &'hir TypeBinding<'hir>) {
+        self.insert(type_binding.span, type_binding.hir_id, Node::TypeBinding(type_binding));
+        self.with_parent(type_binding.hir_id, |this| {
+            intravisit::walk_assoc_type_binding(this, type_binding)
+        })
+    }
+
     fn visit_trait_item_ref(&mut self, ii: &'hir TraitItemRef) {
         // Do not visit the duplicate information in TraitItemRef. We want to
         // map the actual nodes, not the duplicate ones in the *Ref.
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 83821b5b536..9c314f67651 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3302,6 +3302,7 @@ pub enum Node<'hir> {
     Stmt(&'hir Stmt<'hir>),
     PathSegment(&'hir PathSegment<'hir>),
     Ty(&'hir Ty<'hir>),
+    TypeBinding(&'hir TypeBinding<'hir>),
     TraitRef(&'hir TraitRef<'hir>),
     Binding(&'hir Pat<'hir>),
     Pat(&'hir Pat<'hir>),
@@ -3347,6 +3348,7 @@ impl<'hir> Node<'hir> {
             | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
             Node::Lifetime(lt) => Some(lt.name.ident()),
             Node::GenericParam(p) => Some(p.name.ident()),
+            Node::TypeBinding(b) => Some(b.ident),
             Node::Param(..)
             | Node::AnonConst(..)
             | Node::Expr(..)
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 4558a3d10c4..fb40008d60b 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -85,6 +85,7 @@ impl<'a> State<'a> {
             Node::Stmt(a) => self.print_stmt(&a),
             Node::PathSegment(a) => self.print_path_segment(&a),
             Node::Ty(a) => self.print_type(&a),
+            Node::TypeBinding(a) => self.print_type_binding(&a),
             Node::TraitRef(a) => self.print_trait_ref(&a),
             Node::Binding(a) | Node::Pat(a) => self.print_pat(&a),
             Node::Arm(a) => self.print_arm(&a),
@@ -1703,21 +1704,7 @@ impl<'a> State<'a> {
 
             for binding in generic_args.bindings.iter() {
                 start_or_comma(self);
-                self.print_ident(binding.ident);
-                self.print_generic_args(binding.gen_args, false, false);
-                self.space();
-                match generic_args.bindings[0].kind {
-                    hir::TypeBindingKind::Equality { ref term } => {
-                        self.word_space("=");
-                        match term {
-                            Term::Ty(ref ty) => self.print_type(ty),
-                            Term::Const(ref c) => self.print_anon_const(c),
-                        }
-                    }
-                    hir::TypeBindingKind::Constraint { bounds } => {
-                        self.print_bounds(":", bounds);
-                    }
-                }
+                self.print_type_binding(binding);
             }
 
             if !empty.get() {
@@ -1726,6 +1713,24 @@ impl<'a> State<'a> {
         }
     }
 
+    pub fn print_type_binding(&mut self, binding: &hir::TypeBinding<'_>) {
+        self.print_ident(binding.ident);
+        self.print_generic_args(binding.gen_args, false, false);
+        self.space();
+        match binding.kind {
+            hir::TypeBindingKind::Equality { ref term } => {
+                self.word_space("=");
+                match term {
+                    Term::Ty(ref ty) => self.print_type(ty),
+                    Term::Const(ref c) => self.print_anon_const(c),
+                }
+            }
+            hir::TypeBindingKind::Constraint { bounds } => {
+                self.print_bounds(":", bounds);
+            }
+        }
+    }
+
     pub fn print_pat(&mut self, pat: &hir::Pat<'_>) {
         self.maybe_print_comment(pat.span.lo());
         self.ann.pre(self, AnnNode::Pat(pat));
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 779af7a3827..ebda9f7588d 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -298,6 +298,7 @@ impl<'hir> Map<'hir> {
             Node::Stmt(_)
             | Node::PathSegment(_)
             | Node::Ty(_)
+            | Node::TypeBinding(_)
             | Node::Infer(_)
             | Node::TraitRef(_)
             | Node::Pat(_)
@@ -323,7 +324,8 @@ impl<'hir> Map<'hir> {
     }
 
     pub fn get_parent_node(self, hir_id: HirId) -> HirId {
-        self.find_parent_node(hir_id).unwrap()
+        self.find_parent_node(hir_id)
+            .unwrap_or_else(|| bug!("No parent for node {:?}", self.node_to_string(hir_id)))
     }
 
     /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
@@ -973,6 +975,7 @@ impl<'hir> Map<'hir> {
                     .with_hi(seg.args.map_or_else(|| ident_span.hi(), |args| args.span_ext.hi()))
             }
             Node::Ty(ty) => ty.span,
+            Node::TypeBinding(tb) => tb.span,
             Node::TraitRef(tr) => tr.path.span,
             Node::Binding(pat) => pat.span,
             Node::Pat(pat) => pat.span,
@@ -1205,6 +1208,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
         Some(Node::Stmt(_)) => node_str("stmt"),
         Some(Node::PathSegment(_)) => node_str("path segment"),
         Some(Node::Ty(_)) => node_str("type"),
+        Some(Node::TypeBinding(_)) => node_str("type binding"),
         Some(Node::TraitRef(_)) => node_str("trait ref"),
         Some(Node::Binding(_)) => node_str("local"),
         Some(Node::Pat(_)) => node_str("pat"),
diff --git a/compiler/rustc_middle/src/middle/resolve_lifetime.rs b/compiler/rustc_middle/src/middle/resolve_lifetime.rs
index cdc0d076801..c71ba7b1753 100644
--- a/compiler/rustc_middle/src/middle/resolve_lifetime.rs
+++ b/compiler/rustc_middle/src/middle/resolve_lifetime.rs
@@ -16,20 +16,6 @@ pub enum Region {
     Free(DefId, /* lifetime decl */ DefId),
 }
 
-/// This is used in diagnostics to improve suggestions for missing generic arguments.
-/// It gives information on the type of lifetimes that are in scope for a particular `PathSegment`,
-/// so that we can e.g. suggest elided-lifetimes-in-paths of the form <'_, '_> e.g.
-#[derive(Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)]
-pub enum LifetimeScopeForPath {
-    /// Contains all lifetime names that are in scope and could possibly be used in generics
-    /// arguments of path.
-    NonElided(Vec<LocalDefId>),
-
-    /// Information that allows us to suggest args of the form `<'_>` in case
-    /// no generic arguments were provided for a path.
-    Elided,
-}
-
 /// A set containing, at most, one known element.
 /// If two distinct values are inserted into a set, then it
 /// becomes `Many`, which can be used to detect ambiguities.
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 24531e46189..5b48f164016 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1599,11 +1599,6 @@ rustc_queries! {
         desc { "looking up late bound vars" }
     }
 
-    query lifetime_scope_map(_: LocalDefId) -> Option<FxHashMap<ItemLocalId, LifetimeScopeForPath>> {
-        storage(ArenaCacheSelector<'tcx>)
-        desc { "finds the lifetime scope for an HirId of a PathSegment" }
-    }
-
     query visibility(def_id: DefId) -> ty::Visibility {
         desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) }
         separate_provide_extern
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index ac71146303a..041e5fb4bc6 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -6,7 +6,7 @@ use crate::hir::place::Place as HirPlace;
 use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
 use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource};
 use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
-use crate::middle::resolve_lifetime::{self, LifetimeScopeForPath};
+use crate::middle::resolve_lifetime;
 use crate::middle::stability;
 use crate::mir::interpret::{self, Allocation, ConstAllocation, ConstValue, Scalar};
 use crate::mir::{
@@ -2821,10 +2821,6 @@ impl<'tcx> TyCtxt<'tcx> {
         )
     }
 
-    pub fn lifetime_scope(self, id: HirId) -> Option<&'tcx LifetimeScopeForPath> {
-        self.lifetime_scope_map(id.owner).as_ref().and_then(|map| map.get(&id.local_id))
-    }
-
     /// Whether the `def_id` counts as const fn in the current crate, considering all active
     /// feature gates
     pub fn is_const_fn(self, def_id: DefId) -> bool {
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index 59794c4d3f0..3d662ed5de4 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/ty/query.rs
@@ -6,9 +6,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
 use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
 use crate::middle::lib_features::LibFeatures;
 use crate::middle::privacy::AccessLevels;
-use crate::middle::resolve_lifetime::{
-    LifetimeScopeForPath, ObjectLifetimeDefault, Region, ResolveLifetimes,
-};
+use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes};
 use crate::middle::stability::{self, DeprecationEntry};
 use crate::mir;
 use crate::mir::interpret::GlobalId;
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index bfc42902be4..447f4174c10 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -8,12 +8,11 @@
 
 use crate::late::diagnostics::{ForLifetimeSpanType, MissingLifetimeSpot};
 use rustc_ast::walk_list;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefIdMap, LocalDefId};
-use rustc_hir::hir_id::ItemLocalId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node};
 use rustc_hir::{GenericParamKind, HirIdMap};
@@ -141,9 +140,6 @@ struct NamedRegionMap {
     // - trait refs
     // - bound types (like `T` in `for<'a> T<'a>: Foo`)
     late_bound_vars: HirIdMap<Vec<ty::BoundVariableKind>>,
-
-    // maps `PathSegment` `HirId`s to lifetime scopes.
-    scope_for_path: Option<FxHashMap<LocalDefId, FxHashMap<ItemLocalId, LifetimeScopeForPath>>>,
 }
 
 pub(crate) struct LifetimeContext<'a, 'tcx> {
@@ -362,10 +358,6 @@ pub fn provide(providers: &mut ty::query::Providers) {
             _ => None,
         },
         late_bound_vars_map: |tcx, id| resolve_lifetimes_for(tcx, id).late_bound_vars.get(&id),
-        lifetime_scope_map: |tcx, id| {
-            let item_id = item_for(tcx, id);
-            do_resolve(tcx, item_id, false, true).scope_for_path.unwrap().remove(&id)
-        },
 
         ..*providers
     };
@@ -406,7 +398,7 @@ fn resolve_lifetimes_trait_definition(
     tcx: TyCtxt<'_>,
     local_def_id: LocalDefId,
 ) -> ResolveLifetimes {
-    convert_named_region_map(do_resolve(tcx, local_def_id, true, false))
+    convert_named_region_map(do_resolve(tcx, local_def_id, true))
 }
 
 /// Computes the `ResolveLifetimes` map that contains data for an entire `Item`.
@@ -414,21 +406,17 @@ fn resolve_lifetimes_trait_definition(
 /// `named_region_map`, `is_late_bound_map`, etc.
 #[tracing::instrument(level = "debug", skip(tcx))]
 fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> ResolveLifetimes {
-    convert_named_region_map(do_resolve(tcx, local_def_id, false, false))
+    convert_named_region_map(do_resolve(tcx, local_def_id, false))
 }
 
 fn do_resolve(
     tcx: TyCtxt<'_>,
     local_def_id: LocalDefId,
     trait_definition_only: bool,
-    with_scope_for_path: bool,
 ) -> NamedRegionMap {
     let item = tcx.hir().expect_item(local_def_id);
-    let mut named_region_map = NamedRegionMap {
-        defs: Default::default(),
-        late_bound_vars: Default::default(),
-        scope_for_path: with_scope_for_path.then(|| Default::default()),
-    };
+    let mut named_region_map =
+        NamedRegionMap { defs: Default::default(), late_bound_vars: Default::default() };
     let mut visitor = LifetimeContext {
         tcx,
         map: &mut named_region_map,
@@ -524,38 +512,6 @@ fn late_region_as_bound_region<'tcx>(tcx: TyCtxt<'tcx>, region: &Region) -> ty::
     }
 }
 
-#[tracing::instrument(level = "debug")]
-fn get_lifetime_scopes_for_path(mut scope: &Scope<'_>) -> LifetimeScopeForPath {
-    let mut available_lifetimes = vec![];
-    loop {
-        match scope {
-            Scope::Binder { lifetimes, s, .. } => {
-                available_lifetimes.extend(lifetimes.keys());
-                scope = s;
-            }
-            Scope::Body { s, .. } => {
-                scope = s;
-            }
-            Scope::Elision { elide, s } => {
-                if let Elide::Exact(_) = elide {
-                    return LifetimeScopeForPath::Elided;
-                } else {
-                    scope = s;
-                }
-            }
-            Scope::ObjectLifetimeDefault { s, .. } => {
-                scope = s;
-            }
-            Scope::Root => {
-                return LifetimeScopeForPath::NonElided(available_lifetimes);
-            }
-            Scope::Supertrait { s, .. } | Scope::TraitRefBoundary { s, .. } => {
-                scope = s;
-            }
-        }
-    }
-}
-
 impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
     /// Returns the binders in scope and the type of `Binder` that should be created for a poly trait ref.
     fn poly_trait_ref_binder_info(&mut self) -> (Vec<ty::BoundVariableKind>, BinderScopeType) {
@@ -1202,53 +1158,15 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
         }
     }
 
-    fn visit_assoc_type_binding(&mut self, type_binding: &'tcx hir::TypeBinding<'_>) {
-        let scope = self.scope;
-        if let Some(scope_for_path) = self.map.scope_for_path.as_mut() {
-            // We add lifetime scope information for `Ident`s in associated type bindings and use
-            // the `HirId` of the type binding as the key in `LifetimeMap`
-            let lifetime_scope = get_lifetime_scopes_for_path(scope);
-            let map = scope_for_path.entry(type_binding.hir_id.owner).or_default();
-            map.insert(type_binding.hir_id.local_id, lifetime_scope);
-        }
-        hir::intravisit::walk_assoc_type_binding(self, type_binding);
-    }
-
     fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, _: hir::HirId) {
         for (i, segment) in path.segments.iter().enumerate() {
             let depth = path.segments.len() - i - 1;
             if let Some(ref args) = segment.args {
                 self.visit_segment_args(path.res, depth, args);
             }
-
-            let scope = self.scope;
-            if let Some(scope_for_path) = self.map.scope_for_path.as_mut() {
-                // Add lifetime scope information to path segment. Note we cannot call `visit_path_segment`
-                // here because that call would yield to resolution problems due to `walk_path_segment`
-                // being called, which processes the path segments generic args, which we have already
-                // processed using `visit_segment_args`.
-                let lifetime_scope = get_lifetime_scopes_for_path(scope);
-                if let Some(hir_id) = segment.hir_id {
-                    let map = scope_for_path.entry(hir_id.owner).or_default();
-                    map.insert(hir_id.local_id, lifetime_scope);
-                }
-            }
         }
     }
 
-    fn visit_path_segment(&mut self, path_span: Span, path_segment: &'tcx hir::PathSegment<'tcx>) {
-        let scope = self.scope;
-        if let Some(scope_for_path) = self.map.scope_for_path.as_mut() {
-            let lifetime_scope = get_lifetime_scopes_for_path(scope);
-            if let Some(hir_id) = path_segment.hir_id {
-                let map = scope_for_path.entry(hir_id.owner).or_default();
-                map.insert(hir_id.local_id, lifetime_scope);
-            }
-        }
-
-        intravisit::walk_path_segment(self, path_span, path_segment);
-    }
-
     fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl<'tcx>) {
         let output = match fd.output {
             hir::FnRetTy::DefaultReturn(_) => None,
@@ -2227,6 +2145,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
 
             // Foreign functions, `fn(...) -> R` and `Trait(...) -> R` (both types and bounds).
             Node::ForeignItem(_) | Node::Ty(_) | Node::TraitRef(_) => None,
+
+            Node::TypeBinding(_) if let Node::TraitRef(_) = self.tcx.hir().get(self.tcx.hir().get_parent_node(parent)) => None,
+
             // Everything else (only closures?) doesn't
             // actually enjoy elision in return types.
             _ => {
@@ -2548,16 +2469,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
         };
 
-        // If we specifically need the `scope_for_path` map, then we're in the
-        // diagnostic pass and we don't want to emit more errors.
-        if self.map.scope_for_path.is_some() {
-            self.tcx.sess.delay_span_bug(
-                rustc_span::DUMMY_SP,
-                "Encountered unexpected errors during diagnostics related part",
-            );
-            return;
-        }
-
         let mut spans: Vec<_> = lifetime_refs.iter().map(|lt| lt.span).collect();
         spans.sort();
         let mut spans_dedup = spans.clone();
diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
index 417778cc57d..58b63804b4a 100644
--- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
@@ -249,6 +249,7 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
                 | hir::Node::Stmt(..)
                 | hir::Node::PathSegment(..)
                 | hir::Node::Ty(..)
+                | hir::Node::TypeBinding(..)
                 | hir::Node::TraitRef(..)
                 | hir::Node::Binding(..)
                 | hir::Node::Pat(..)
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 7e3fefe4502..2433401b7f0 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -450,21 +450,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                     .discr_type()
                     .to_ty(tcx),
 
-                Node::TraitRef(trait_ref @ &TraitRef {
-                  path, ..
-                }) if let Some((binding, seg)) =
-                  path
-                      .segments
-                      .iter()
-                      .find_map(|seg| {
-                          seg.args?.bindings
-                              .iter()
-                              .find_map(|binding| if binding.opt_const()?.hir_id == hir_id {
-                                Some((binding, seg))
-                              } else {
-                                None
-                              })
-                      }) =>
+                Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, ..  })
+                    if let Node::TraitRef(trait_ref) = tcx.hir().get(
+                        tcx.hir().get_parent_node(binding_id)
+                    ) =>
                 {
                   let Some(trait_def_id) = trait_ref.trait_def_id() else {
                     return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
diff --git a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
index bc3a3db9fda..c440e93fe0a 100644
--- a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
@@ -5,7 +5,6 @@ use rustc_errors::{
 };
 use rustc_hir as hir;
 use rustc_middle::hir::map::fn_sig;
-use rustc_middle::middle::resolve_lifetime::LifetimeScopeForPath;
 use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt};
 use rustc_session::Session;
 use rustc_span::def_id::DefId;
@@ -291,7 +290,69 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
     }
 
     // Creates lifetime name suggestions from the lifetime parameter names
-    fn get_lifetime_args_suggestions_from_param_names(&self, num_params_to_take: usize) -> String {
+    fn get_lifetime_args_suggestions_from_param_names(
+        &self,
+        path_hir_id: Option<hir::HirId>,
+        num_params_to_take: usize,
+    ) -> String {
+        debug!(?path_hir_id);
+
+        if let Some(path_hir_id) = path_hir_id {
+            let mut ret = Vec::new();
+            for (id, node) in self.tcx.hir().parent_iter(path_hir_id) {
+                debug!(?id);
+                let params = if let Some(generics) = node.generics() {
+                    generics.params
+                } else if let hir::Node::Ty(ty) = node
+                    && let hir::TyKind::BareFn(bare_fn) = ty.kind
+                {
+                    bare_fn.generic_params
+                } else {
+                    &[]
+                };
+                ret.extend(params.iter().filter_map(|p| {
+                    let hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }
+                        = p.kind
+                    else { return None };
+                    let hir::ParamName::Plain(name) = p.name else { return None };
+                    Some(name.to_string())
+                }));
+                // Suggest `'static` when in const/static item-like.
+                if let hir::Node::Item(hir::Item {
+                    kind: hir::ItemKind::Static { .. } | hir::ItemKind::Const { .. },
+                    ..
+                })
+                | hir::Node::TraitItem(hir::TraitItem {
+                    kind: hir::TraitItemKind::Const { .. },
+                    ..
+                })
+                | hir::Node::ImplItem(hir::ImplItem {
+                    kind: hir::ImplItemKind::Const { .. },
+                    ..
+                })
+                | hir::Node::ForeignItem(hir::ForeignItem {
+                    kind: hir::ForeignItemKind::Static { .. },
+                    ..
+                })
+                | hir::Node::AnonConst(..) = node
+                {
+                    ret.extend(
+                        std::iter::repeat("'static".to_owned())
+                            .take(num_params_to_take.saturating_sub(ret.len())),
+                    );
+                }
+                if ret.len() >= num_params_to_take {
+                    return ret[..num_params_to_take].join(", ");
+                }
+                // We cannot refer to lifetimes defined in an outer function.
+                if let hir::Node::Item(_) = node {
+                    break;
+                }
+            }
+        }
+
+        // We could not gather enough lifetime parameters in the scope.
+        // We use the parameter names from the target type's definition instead.
         self.gen_params
             .params
             .iter()
@@ -501,44 +562,10 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
         let num_params_to_take = num_missing_args;
         let msg = format!("add missing {} argument{}", self.kind(), pluralize!(num_missing_args));
 
-        // we first try to get lifetime name suggestions from scope or elision information. If none is
-        // available we use the parameter definitions
-        let suggested_args = if let Some(hir_id) = self.path_segment.hir_id {
-            if let Some(lifetimes_in_scope) = self.tcx.lifetime_scope(hir_id) {
-                match lifetimes_in_scope {
-                    LifetimeScopeForPath::NonElided(param_names) => {
-                        debug!("NonElided(param_names: {:?})", param_names);
-
-                        if param_names.len() >= num_params_to_take {
-                            // use lifetime parameters in scope for suggestions
-                            param_names
-                                .iter()
-                                .take(num_params_to_take)
-                                .map(|def_id| {
-                                    self.tcx.item_name(def_id.to_def_id()).to_ident_string()
-                                })
-                                .collect::<Vec<_>>()
-                                .join(", ")
-                        } else {
-                            // Not enough lifetime arguments in scope -> create suggestions from
-                            // lifetime parameter names in definition. An error for the incorrect
-                            // lifetime scope will be output later.
-                            self.get_lifetime_args_suggestions_from_param_names(num_params_to_take)
-                        }
-                    }
-                    LifetimeScopeForPath::Elided => {
-                        debug!("Elided");
-                        // use suggestions of the form `<'_, '_>` in case lifetime can be elided
-                        ["'_"].repeat(num_params_to_take).join(",")
-                    }
-                }
-            } else {
-                self.get_lifetime_args_suggestions_from_param_names(num_params_to_take)
-            }
-        } else {
-            self.get_lifetime_args_suggestions_from_param_names(num_params_to_take)
-        };
-
+        let suggested_args = self.get_lifetime_args_suggestions_from_param_names(
+            self.path_segment.hir_id,
+            num_params_to_take,
+        );
         debug!("suggested_args: {:?}", &suggested_args);
 
         match self.angle_brackets {
diff --git a/src/test/ui/generic-associated-types/elided-in-expr-position.stderr b/src/test/ui/generic-associated-types/elided-in-expr-position.stderr
index 9263f3d67e3..b395a1cfd8a 100644
--- a/src/test/ui/generic-associated-types/elided-in-expr-position.stderr
+++ b/src/test/ui/generic-associated-types/elided-in-expr-position.stderr
@@ -11,7 +11,7 @@ LL |     type Assoc<'a> where Self: 'a;
    |          ^^^^^ --
 help: add missing lifetime argument
    |
-LL |     fn g(&self) -> Self::Assoc<'_>;
+LL |     fn g(&self) -> Self::Assoc<'a>;
    |                          ~~~~~~~~~
 
 error[E0107]: missing generics for associated type `Trait::Assoc`
@@ -27,7 +27,7 @@ LL |     type Assoc<'a> where Self: 'a;
    |          ^^^^^ --
 help: add missing lifetime argument
    |
-LL |     fn g(&self) -> Self::Assoc<'_> {
+LL |     fn g(&self) -> Self::Assoc<'a> {
    |                          ~~~~~~~~~
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/generic-associated-types/issue-81862.stderr b/src/test/ui/generic-associated-types/issue-81862.stderr
index 024f8ad89f7..c664b3ee668 100644
--- a/src/test/ui/generic-associated-types/issue-81862.stderr
+++ b/src/test/ui/generic-associated-types/issue-81862.stderr
@@ -11,7 +11,7 @@ LL |     type Item<'a>;
    |          ^^^^ --
 help: add missing lifetime argument
    |
-LL |     fn next(&mut self) -> Option<Self::Item<'_>>;
+LL |     fn next(&mut self) -> Option<Self::Item<'a>>;
    |                                        ~~~~~~~~
 
 error: aborting due to previous error
diff --git a/src/test/ui/suggestions/missing-lifetime-specifier.stderr b/src/test/ui/suggestions/missing-lifetime-specifier.stderr
index b04ea1c9158..1498337549d 100644
--- a/src/test/ui/suggestions/missing-lifetime-specifier.stderr
+++ b/src/test/ui/suggestions/missing-lifetime-specifier.stderr
@@ -171,8 +171,8 @@ LL | pub union Qux<'t, 'k, I> {
    |           ^^^ --  --
 help: add missing lifetime argument
    |
-LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, '_, i32>>>>> = RefCell::new(HashMap::new());
-   |                                                       ++++
+LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                                       +++++++++
 
 error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:43:44
@@ -243,8 +243,8 @@ LL | pub union Qux<'t, 'k, I> {
    |           ^^^ --  --
 help: add missing lifetime argument
    |
-LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, '_, i32>>>>> = RefCell::new(HashMap::new());
-   |                                                       ++++
+LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                                       +++++++++
 
 error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:51:45
@@ -261,8 +261,8 @@ LL | trait Tar<'t, 'k, I> {}
    |       ^^^ --  --
 help: add missing lifetime argument
    |
-LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, '_, i32>>>>> = RefCell::new(HashMap::new());
-   |                                                        ++++
+LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                                        +++++++++
 
 error[E0106]: missing lifetime specifier
   --> $DIR/missing-lifetime-specifier.rs:51:44
@@ -360,8 +360,8 @@ LL | trait Tar<'t, 'k, I> {}
    |       ^^^ --  --
 help: add missing lifetime argument
    |
-LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, '_, i32>>>>> = RefCell::new(HashMap::new());
-   |                                                        ++++
+LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                                        +++++++++
 
 error: aborting due to 24 previous errors