]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_resolve/src/late/lifetimes.rs
Rollup merge of #93400 - ChayimFriedman2:dont-suggest-using-const-with-bounds-unused...
[rust.git] / compiler / rustc_resolve / src / late / lifetimes.rs
1 //! Name resolution for lifetimes.
2 //!
3 //! Name resolution for lifetimes follows *much* simpler rules than the
4 //! full resolve. For example, lifetime names are never exported or
5 //! used between functions, and they operate in a purely top-down
6 //! way. Therefore, we break lifetime name resolution into a separate pass.
7
8 use crate::late::diagnostics::{ForLifetimeSpanType, MissingLifetimeSpot};
9 use rustc_ast::walk_list;
10 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
11 use rustc_errors::{struct_span_err, Applicability, Diagnostic};
12 use rustc_hir as hir;
13 use rustc_hir::def::{DefKind, Res};
14 use rustc_hir::def_id::{DefIdMap, LocalDefId};
15 use rustc_hir::hir_id::ItemLocalId;
16 use rustc_hir::intravisit::{self, Visitor};
17 use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node, ParamName, QPath};
18 use rustc_hir::{GenericParamKind, HirIdMap, HirIdSet};
19 use rustc_middle::hir::map::Map;
20 use rustc_middle::hir::nested_filter;
21 use rustc_middle::middle::resolve_lifetime::*;
22 use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
23 use rustc_middle::{bug, span_bug};
24 use rustc_session::lint;
25 use rustc_span::def_id::DefId;
26 use rustc_span::symbol::{kw, sym, Ident, Symbol};
27 use rustc_span::Span;
28 use std::borrow::Cow;
29 use std::cell::Cell;
30 use std::fmt;
31 use std::mem::take;
32
33 use tracing::{debug, span, Level};
34
35 // This counts the no of times a lifetime is used
36 #[derive(Clone, Copy, Debug)]
37 pub enum LifetimeUseSet<'tcx> {
38     One(&'tcx hir::Lifetime),
39     Many,
40 }
41
42 trait RegionExt {
43     fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (ParamName, Region);
44
45     fn late(index: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (ParamName, Region);
46
47     fn late_anon(named_late_bound_vars: u32, index: &Cell<u32>) -> Region;
48
49     fn id(&self) -> Option<DefId>;
50
51     fn shifted(self, amount: u32) -> Region;
52
53     fn shifted_out_to_binder(self, binder: ty::DebruijnIndex) -> Region;
54
55     fn subst<'a, L>(self, params: L, map: &NamedRegionMap) -> Option<Region>
56     where
57         L: Iterator<Item = &'a hir::Lifetime>;
58 }
59
60 impl RegionExt for Region {
61     fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (ParamName, Region) {
62         let i = *index;
63         *index += 1;
64         let def_id = hir_map.local_def_id(param.hir_id);
65         debug!("Region::early: index={} def_id={:?}", i, def_id);
66         (param.name.normalize_to_macros_2_0(), Region::EarlyBound(i, def_id.to_def_id()))
67     }
68
69     fn late(idx: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (ParamName, Region) {
70         let depth = ty::INNERMOST;
71         let def_id = hir_map.local_def_id(param.hir_id);
72         debug!(
73             "Region::late: idx={:?}, param={:?} depth={:?} def_id={:?}",
74             idx, param, depth, def_id,
75         );
76         (param.name.normalize_to_macros_2_0(), Region::LateBound(depth, idx, def_id.to_def_id()))
77     }
78
79     fn late_anon(named_late_bound_vars: u32, index: &Cell<u32>) -> Region {
80         let i = index.get();
81         index.set(i + 1);
82         let depth = ty::INNERMOST;
83         Region::LateBoundAnon(depth, named_late_bound_vars + i, i)
84     }
85
86     fn id(&self) -> Option<DefId> {
87         match *self {
88             Region::Static | Region::LateBoundAnon(..) => None,
89
90             Region::EarlyBound(_, id) | Region::LateBound(_, _, id) | Region::Free(_, id) => {
91                 Some(id)
92             }
93         }
94     }
95
96     fn shifted(self, amount: u32) -> Region {
97         match self {
98             Region::LateBound(debruijn, idx, id) => {
99                 Region::LateBound(debruijn.shifted_in(amount), idx, id)
100             }
101             Region::LateBoundAnon(debruijn, index, anon_index) => {
102                 Region::LateBoundAnon(debruijn.shifted_in(amount), index, anon_index)
103             }
104             _ => self,
105         }
106     }
107
108     fn shifted_out_to_binder(self, binder: ty::DebruijnIndex) -> Region {
109         match self {
110             Region::LateBound(debruijn, index, id) => {
111                 Region::LateBound(debruijn.shifted_out_to_binder(binder), index, id)
112             }
113             Region::LateBoundAnon(debruijn, index, anon_index) => {
114                 Region::LateBoundAnon(debruijn.shifted_out_to_binder(binder), index, anon_index)
115             }
116             _ => self,
117         }
118     }
119
120     fn subst<'a, L>(self, mut params: L, map: &NamedRegionMap) -> Option<Region>
121     where
122         L: Iterator<Item = &'a hir::Lifetime>,
123     {
124         if let Region::EarlyBound(index, _) = self {
125             params.nth(index as usize).and_then(|lifetime| map.defs.get(&lifetime.hir_id).cloned())
126         } else {
127             Some(self)
128         }
129     }
130 }
131
132 /// Maps the id of each lifetime reference to the lifetime decl
133 /// that it corresponds to.
134 ///
135 /// FIXME. This struct gets converted to a `ResolveLifetimes` for
136 /// actual use. It has the same data, but indexed by `LocalDefId`.  This
137 /// is silly.
138 #[derive(Debug, Default)]
139 struct NamedRegionMap {
140     // maps from every use of a named (not anonymous) lifetime to a
141     // `Region` describing how that region is bound
142     defs: HirIdMap<Region>,
143
144     // the set of lifetime def ids that are late-bound; a region can
145     // be late-bound if (a) it does NOT appear in a where-clause and
146     // (b) it DOES appear in the arguments.
147     late_bound: HirIdSet,
148
149     // Maps relevant hir items to the bound vars on them. These include:
150     // - function defs
151     // - function pointers
152     // - closures
153     // - trait refs
154     // - bound types (like `T` in `for<'a> T<'a>: Foo`)
155     late_bound_vars: HirIdMap<Vec<ty::BoundVariableKind>>,
156
157     // maps `PathSegment` `HirId`s to lifetime scopes.
158     scope_for_path: Option<FxHashMap<LocalDefId, FxHashMap<ItemLocalId, LifetimeScopeForPath>>>,
159 }
160
161 crate struct LifetimeContext<'a, 'tcx> {
162     crate tcx: TyCtxt<'tcx>,
163     map: &'a mut NamedRegionMap,
164     scope: ScopeRef<'a>,
165
166     /// Used to disallow the use of in-band lifetimes in `fn` or `Fn` syntax.
167     is_in_fn_syntax: bool,
168
169     is_in_const_generic: bool,
170
171     /// Indicates that we only care about the definition of a trait. This should
172     /// be false if the `Item` we are resolving lifetimes for is not a trait or
173     /// we eventually need lifetimes resolve for trait items.
174     trait_definition_only: bool,
175
176     /// List of labels in the function/method currently under analysis.
177     labels_in_fn: Vec<Ident>,
178
179     /// Cache for cross-crate per-definition object lifetime defaults.
180     xcrate_object_lifetime_defaults: DefIdMap<Vec<ObjectLifetimeDefault>>,
181
182     lifetime_uses: &'a mut DefIdMap<LifetimeUseSet<'tcx>>,
183
184     /// When encountering an undefined named lifetime, we will suggest introducing it in these
185     /// places.
186     crate missing_named_lifetime_spots: Vec<MissingLifetimeSpot<'tcx>>,
187 }
188
189 #[derive(Debug)]
190 enum Scope<'a> {
191     /// Declares lifetimes, and each can be early-bound or late-bound.
192     /// The `DebruijnIndex` of late-bound lifetimes starts at `1` and
193     /// it should be shifted by the number of `Binder`s in between the
194     /// declaration `Binder` and the location it's referenced from.
195     Binder {
196         /// We use an IndexMap here because we want these lifetimes in order
197         /// for diagnostics.
198         lifetimes: FxIndexMap<hir::ParamName, Region>,
199
200         /// if we extend this scope with another scope, what is the next index
201         /// we should use for an early-bound region?
202         next_early_index: u32,
203
204         /// Flag is set to true if, in this binder, `'_` would be
205         /// equivalent to a "single-use region". This is true on
206         /// impls, but not other kinds of items.
207         track_lifetime_uses: bool,
208
209         /// Whether or not this binder would serve as the parent
210         /// binder for opaque types introduced within. For example:
211         ///
212         /// ```text
213         ///     fn foo<'a>() -> impl for<'b> Trait<Item = impl Trait2<'a>>
214         /// ```
215         ///
216         /// Here, the opaque types we create for the `impl Trait`
217         /// and `impl Trait2` references will both have the `foo` item
218         /// as their parent. When we get to `impl Trait2`, we find
219         /// that it is nested within the `for<>` binder -- this flag
220         /// allows us to skip that when looking for the parent binder
221         /// of the resulting opaque type.
222         opaque_type_parent: bool,
223
224         scope_type: BinderScopeType,
225
226         /// The late bound vars for a given item are stored by `HirId` to be
227         /// queried later. However, if we enter an elision scope, we have to
228         /// later append the elided bound vars to the list and need to know what
229         /// to append to.
230         hir_id: hir::HirId,
231
232         s: ScopeRef<'a>,
233     },
234
235     /// Lifetimes introduced by a fn are scoped to the call-site for that fn,
236     /// if this is a fn body, otherwise the original definitions are used.
237     /// Unspecified lifetimes are inferred, unless an elision scope is nested,
238     /// e.g., `(&T, fn(&T) -> &T);` becomes `(&'_ T, for<'a> fn(&'a T) -> &'a T)`.
239     Body {
240         id: hir::BodyId,
241         s: ScopeRef<'a>,
242     },
243
244     /// A scope which either determines unspecified lifetimes or errors
245     /// on them (e.g., due to ambiguity). For more details, see `Elide`.
246     Elision {
247         elide: Elide,
248         s: ScopeRef<'a>,
249     },
250
251     /// Use a specific lifetime (if `Some`) or leave it unset (to be
252     /// inferred in a function body or potentially error outside one),
253     /// for the default choice of lifetime in a trait object type.
254     ObjectLifetimeDefault {
255         lifetime: Option<Region>,
256         s: ScopeRef<'a>,
257     },
258
259     /// When we have nested trait refs, we concanetate late bound vars for inner
260     /// trait refs from outer ones. But we also need to include any HRTB
261     /// lifetimes encountered when identifying the trait that an associated type
262     /// is declared on.
263     Supertrait {
264         lifetimes: Vec<ty::BoundVariableKind>,
265         s: ScopeRef<'a>,
266     },
267
268     TraitRefBoundary {
269         s: ScopeRef<'a>,
270     },
271
272     Root,
273 }
274
275 #[derive(Copy, Clone, Debug)]
276 enum BinderScopeType {
277     /// Any non-concatenating binder scopes.
278     Normal,
279     /// Within a syntactic trait ref, there may be multiple poly trait refs that
280     /// are nested (under the `associcated_type_bounds` feature). The binders of
281     /// the innner poly trait refs are extended from the outer poly trait refs
282     /// and don't increase the late bound depth. If you had
283     /// `T: for<'a>  Foo<Bar: for<'b> Baz<'a, 'b>>`, then the `for<'b>` scope
284     /// would be `Concatenating`. This also used in trait refs in where clauses
285     /// where we have two binders `for<> T: for<> Foo` (I've intentionally left
286     /// out any lifetimes because they aren't needed to show the two scopes).
287     /// The inner `for<>` has a scope of `Concatenating`.
288     Concatenating,
289 }
290
291 // A helper struct for debugging scopes without printing parent scopes
292 struct TruncatedScopeDebug<'a>(&'a Scope<'a>);
293
294 impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
295     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
296         match self.0 {
297             Scope::Binder {
298                 lifetimes,
299                 next_early_index,
300                 track_lifetime_uses,
301                 opaque_type_parent,
302                 scope_type,
303                 hir_id,
304                 s: _,
305             } => f
306                 .debug_struct("Binder")
307                 .field("lifetimes", lifetimes)
308                 .field("next_early_index", next_early_index)
309                 .field("track_lifetime_uses", track_lifetime_uses)
310                 .field("opaque_type_parent", opaque_type_parent)
311                 .field("scope_type", scope_type)
312                 .field("hir_id", hir_id)
313                 .field("s", &"..")
314                 .finish(),
315             Scope::Body { id, s: _ } => {
316                 f.debug_struct("Body").field("id", id).field("s", &"..").finish()
317             }
318             Scope::Elision { elide, s: _ } => {
319                 f.debug_struct("Elision").field("elide", elide).field("s", &"..").finish()
320             }
321             Scope::ObjectLifetimeDefault { lifetime, s: _ } => f
322                 .debug_struct("ObjectLifetimeDefault")
323                 .field("lifetime", lifetime)
324                 .field("s", &"..")
325                 .finish(),
326             Scope::Supertrait { lifetimes, s: _ } => f
327                 .debug_struct("Supertrait")
328                 .field("lifetimes", lifetimes)
329                 .field("s", &"..")
330                 .finish(),
331             Scope::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(),
332             Scope::Root => f.debug_struct("Root").finish(),
333         }
334     }
335 }
336
337 #[derive(Clone, Debug)]
338 enum Elide {
339     /// Use a fresh anonymous late-bound lifetime each time, by
340     /// incrementing the counter to generate sequential indices. All
341     /// anonymous lifetimes must start *after* named bound vars.
342     FreshLateAnon(u32, Cell<u32>),
343     /// Always use this one lifetime.
344     Exact(Region),
345     /// Less or more than one lifetime were found, error on unspecified.
346     Error(Vec<ElisionFailureInfo>),
347     /// Forbid lifetime elision inside of a larger scope where it would be
348     /// permitted. For example, in let position impl trait.
349     Forbid,
350 }
351
352 #[derive(Clone, Debug)]
353 crate struct ElisionFailureInfo {
354     /// Where we can find the argument pattern.
355     crate parent: Option<hir::BodyId>,
356     /// The index of the argument in the original definition.
357     crate index: usize,
358     crate lifetime_count: usize,
359     crate have_bound_regions: bool,
360     crate span: Span,
361 }
362
363 type ScopeRef<'a> = &'a Scope<'a>;
364
365 const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root;
366
367 pub fn provide(providers: &mut ty::query::Providers) {
368     *providers = ty::query::Providers {
369         resolve_lifetimes_trait_definition,
370         resolve_lifetimes,
371
372         named_region_map: |tcx, id| resolve_lifetimes_for(tcx, id).defs.get(&id),
373         is_late_bound_map,
374         object_lifetime_defaults: |tcx, id| match tcx.hir().find_by_def_id(id) {
375             Some(Node::Item(item)) => compute_object_lifetime_defaults(tcx, item),
376             _ => None,
377         },
378         late_bound_vars_map: |tcx, id| resolve_lifetimes_for(tcx, id).late_bound_vars.get(&id),
379         lifetime_scope_map: |tcx, id| {
380             let item_id = item_for(tcx, id);
381             do_resolve(tcx, item_id, false, true).scope_for_path.unwrap().remove(&id)
382         },
383
384         ..*providers
385     };
386 }
387
388 /// Like `resolve_lifetimes`, but does not resolve lifetimes for trait items.
389 /// Also does not generate any diagnostics.
390 ///
391 /// This is ultimately a subset of the `resolve_lifetimes` work. It effectively
392 /// resolves lifetimes only within the trait "header" -- that is, the trait
393 /// and supertrait list. In contrast, `resolve_lifetimes` resolves all the
394 /// lifetimes within the trait and its items. There is room to refactor this,
395 /// for example to resolve lifetimes for each trait item in separate queries,
396 /// but it's convenient to do the entire trait at once because the lifetimes
397 /// from the trait definition are in scope within the trait items as well.
398 ///
399 /// The reason for this separate call is to resolve what would otherwise
400 /// be a cycle. Consider this example:
401 ///
402 /// ```rust
403 /// trait Base<'a> {
404 ///     type BaseItem;
405 /// }
406 /// trait Sub<'b>: for<'a> Base<'a> {
407 ///    type SubItem: Sub<BaseItem = &'b u32>;
408 /// }
409 /// ```
410 ///
411 /// When we resolve `Sub` and all its items, we also have to resolve `Sub<BaseItem = &'b u32>`.
412 /// To figure out the index of `'b`, we have to know about the supertraits
413 /// of `Sub` so that we can determine that the `for<'a>` will be in scope.
414 /// (This is because we -- currently at least -- flatten all the late-bound
415 /// lifetimes into a single binder.) This requires us to resolve the
416 /// *trait definition* of `Sub`; basically just enough lifetime information
417 /// to look at the supertraits.
418 #[tracing::instrument(level = "debug", skip(tcx))]
419 fn resolve_lifetimes_trait_definition(
420     tcx: TyCtxt<'_>,
421     local_def_id: LocalDefId,
422 ) -> ResolveLifetimes {
423     convert_named_region_map(do_resolve(tcx, local_def_id, true, false))
424 }
425
426 /// Computes the `ResolveLifetimes` map that contains data for an entire `Item`.
427 /// You should not read the result of this query directly, but rather use
428 /// `named_region_map`, `is_late_bound_map`, etc.
429 #[tracing::instrument(level = "debug", skip(tcx))]
430 fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> ResolveLifetimes {
431     convert_named_region_map(do_resolve(tcx, local_def_id, false, false))
432 }
433
434 fn do_resolve(
435     tcx: TyCtxt<'_>,
436     local_def_id: LocalDefId,
437     trait_definition_only: bool,
438     with_scope_for_path: bool,
439 ) -> NamedRegionMap {
440     let item = tcx.hir().expect_item(local_def_id);
441     let mut named_region_map = NamedRegionMap {
442         defs: Default::default(),
443         late_bound: Default::default(),
444         late_bound_vars: Default::default(),
445         scope_for_path: with_scope_for_path.then(|| Default::default()),
446     };
447     let mut visitor = LifetimeContext {
448         tcx,
449         map: &mut named_region_map,
450         scope: ROOT_SCOPE,
451         is_in_fn_syntax: false,
452         is_in_const_generic: false,
453         trait_definition_only,
454         labels_in_fn: vec![],
455         xcrate_object_lifetime_defaults: Default::default(),
456         lifetime_uses: &mut Default::default(),
457         missing_named_lifetime_spots: vec![],
458     };
459     visitor.visit_item(item);
460
461     named_region_map
462 }
463
464 fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetimes {
465     let mut rl = ResolveLifetimes::default();
466
467     for (hir_id, v) in named_region_map.defs {
468         let map = rl.defs.entry(hir_id.owner).or_default();
469         map.insert(hir_id.local_id, v);
470     }
471     for hir_id in named_region_map.late_bound {
472         let map = rl.late_bound.entry(hir_id.owner).or_default();
473         map.insert(hir_id.local_id);
474     }
475     for (hir_id, v) in named_region_map.late_bound_vars {
476         let map = rl.late_bound_vars.entry(hir_id.owner).or_default();
477         map.insert(hir_id.local_id, v);
478     }
479
480     debug!(?rl.defs);
481     rl
482 }
483
484 /// Given `any` owner (structs, traits, trait methods, etc.), does lifetime resolution.
485 /// There are two important things this does.
486 /// First, we have to resolve lifetimes for
487 /// the entire *`Item`* that contains this owner, because that's the largest "scope"
488 /// where we can have relevant lifetimes.
489 /// Second, if we are asking for lifetimes in a trait *definition*, we use `resolve_lifetimes_trait_definition`
490 /// instead of `resolve_lifetimes`, which does not descend into the trait items and does not emit diagnostics.
491 /// This allows us to avoid cycles. Importantly, if we ask for lifetimes for lifetimes that have an owner
492 /// other than the trait itself (like the trait methods or associated types), then we just use the regular
493 /// `resolve_lifetimes`.
494 fn resolve_lifetimes_for<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx ResolveLifetimes {
495     let item_id = item_for(tcx, def_id);
496     if item_id == def_id {
497         let item = tcx.hir().item(hir::ItemId { def_id: item_id });
498         match item.kind {
499             hir::ItemKind::Trait(..) => tcx.resolve_lifetimes_trait_definition(item_id),
500             _ => tcx.resolve_lifetimes(item_id),
501         }
502     } else {
503         tcx.resolve_lifetimes(item_id)
504     }
505 }
506
507 /// Finds the `Item` that contains the given `LocalDefId`
508 fn item_for(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> LocalDefId {
509     match tcx.hir().find_by_def_id(local_def_id) {
510         Some(Node::Item(item)) => {
511             return item.def_id;
512         }
513         _ => {}
514     }
515     let item = {
516         let hir_id = tcx.hir().local_def_id_to_hir_id(local_def_id);
517         let mut parent_iter = tcx.hir().parent_iter(hir_id);
518         loop {
519             let node = parent_iter.next().map(|n| n.1);
520             match node {
521                 Some(hir::Node::Item(item)) => break item.def_id,
522                 Some(hir::Node::Crate(_)) | None => bug!("Called `item_for` on an Item."),
523                 _ => {}
524             }
525         }
526     };
527     item
528 }
529
530 fn is_late_bound_map<'tcx>(
531     tcx: TyCtxt<'tcx>,
532     def_id: LocalDefId,
533 ) -> Option<(LocalDefId, &'tcx FxHashSet<ItemLocalId>)> {
534     match tcx.def_kind(def_id) {
535         DefKind::AnonConst | DefKind::InlineConst => {
536             let mut def_id = tcx
537                 .parent(def_id.to_def_id())
538                 .unwrap_or_else(|| bug!("anon const or closure without a parent"));
539             // We search for the next outer anon const or fn here
540             // while skipping closures.
541             //
542             // Note that for `AnonConst` we still just recurse until we
543             // find a function body, but who cares :shrug:
544             while tcx.is_closure(def_id) {
545                 def_id = tcx
546                     .parent(def_id)
547                     .unwrap_or_else(|| bug!("anon const or closure without a parent"));
548             }
549
550             tcx.is_late_bound_map(def_id.expect_local())
551         }
552         _ => resolve_lifetimes_for(tcx, def_id).late_bound.get(&def_id).map(|lt| (def_id, lt)),
553     }
554 }
555
556 /// In traits, there is an implicit `Self` type parameter which comes before the generics.
557 /// We have to account for this when computing the index of the other generic parameters.
558 /// This function returns whether there is such an implicit parameter defined on the given item.
559 fn sub_items_have_self_param(node: &hir::ItemKind<'_>) -> bool {
560     matches!(*node, hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..))
561 }
562
563 fn late_region_as_bound_region<'tcx>(tcx: TyCtxt<'tcx>, region: &Region) -> ty::BoundVariableKind {
564     match region {
565         Region::LateBound(_, _, def_id) => {
566             let name = tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id.expect_local()));
567             ty::BoundVariableKind::Region(ty::BrNamed(*def_id, name))
568         }
569         Region::LateBoundAnon(_, _, anon_idx) => {
570             ty::BoundVariableKind::Region(ty::BrAnon(*anon_idx))
571         }
572         _ => bug!("{:?} is not a late region", region),
573     }
574 }
575
576 #[tracing::instrument(level = "debug")]
577 fn get_lifetime_scopes_for_path(mut scope: &Scope<'_>) -> LifetimeScopeForPath {
578     let mut available_lifetimes = vec![];
579     loop {
580         match scope {
581             Scope::Binder { lifetimes, s, .. } => {
582                 available_lifetimes.extend(lifetimes.keys().filter_map(|p| match p {
583                     hir::ParamName::Plain(ident) => Some(ident.name.to_string()),
584                     _ => None,
585                 }));
586                 scope = s;
587             }
588             Scope::Body { s, .. } => {
589                 scope = s;
590             }
591             Scope::Elision { elide, s } => {
592                 if let Elide::Exact(_) = elide {
593                     return LifetimeScopeForPath::Elided;
594                 } else {
595                     scope = s;
596                 }
597             }
598             Scope::ObjectLifetimeDefault { s, .. } => {
599                 scope = s;
600             }
601             Scope::Root => {
602                 return LifetimeScopeForPath::NonElided(available_lifetimes);
603             }
604             Scope::Supertrait { s, .. } | Scope::TraitRefBoundary { s, .. } => {
605                 scope = s;
606             }
607         }
608     }
609 }
610
611 impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
612     /// Returns the binders in scope and the type of `Binder` that should be created for a poly trait ref.
613     fn poly_trait_ref_binder_info(&mut self) -> (Vec<ty::BoundVariableKind>, BinderScopeType) {
614         let mut scope = self.scope;
615         let mut supertrait_lifetimes = vec![];
616         loop {
617             match scope {
618                 Scope::Body { .. } | Scope::Root => {
619                     break (vec![], BinderScopeType::Normal);
620                 }
621
622                 Scope::Elision { s, .. } | Scope::ObjectLifetimeDefault { s, .. } => {
623                     scope = s;
624                 }
625
626                 Scope::Supertrait { s, lifetimes } => {
627                     supertrait_lifetimes = lifetimes.clone();
628                     scope = s;
629                 }
630
631                 Scope::TraitRefBoundary { .. } => {
632                     // We should only see super trait lifetimes if there is a `Binder` above
633                     assert!(supertrait_lifetimes.is_empty());
634                     break (vec![], BinderScopeType::Normal);
635                 }
636
637                 Scope::Binder { hir_id, .. } => {
638                     // Nested poly trait refs have the binders concatenated
639                     let mut full_binders =
640                         self.map.late_bound_vars.entry(*hir_id).or_default().clone();
641                     full_binders.extend(supertrait_lifetimes.into_iter());
642                     break (full_binders, BinderScopeType::Concatenating);
643                 }
644             }
645         }
646     }
647 }
648 impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
649     type NestedFilter = nested_filter::All;
650
651     fn nested_visit_map(&mut self) -> Self::Map {
652         self.tcx.hir()
653     }
654
655     // We want to nest trait/impl items in their parent, but nothing else.
656     fn visit_nested_item(&mut self, _: hir::ItemId) {}
657
658     fn visit_trait_item_ref(&mut self, ii: &'tcx hir::TraitItemRef) {
659         if !self.trait_definition_only {
660             intravisit::walk_trait_item_ref(self, ii)
661         }
662     }
663
664     fn visit_nested_body(&mut self, body: hir::BodyId) {
665         // Each body has their own set of labels, save labels.
666         let saved = take(&mut self.labels_in_fn);
667         let body = self.tcx.hir().body(body);
668         extract_labels(self, body);
669         self.with(Scope::Body { id: body.id(), s: self.scope }, |_, this| {
670             this.visit_body(body);
671         });
672         self.labels_in_fn = saved;
673     }
674
675     fn visit_fn(
676         &mut self,
677         fk: intravisit::FnKind<'tcx>,
678         fd: &'tcx hir::FnDecl<'tcx>,
679         b: hir::BodyId,
680         s: rustc_span::Span,
681         hir_id: hir::HirId,
682     ) {
683         let name = match fk {
684             intravisit::FnKind::ItemFn(id, _, _, _) => id.name,
685             intravisit::FnKind::Method(id, _, _) => id.name,
686             intravisit::FnKind::Closure => sym::closure,
687         };
688         let name = name.as_str();
689         let span = span!(Level::DEBUG, "visit_fn", name);
690         let _enter = span.enter();
691         match fk {
692             // Any `Binders` are handled elsewhere
693             intravisit::FnKind::ItemFn(..) | intravisit::FnKind::Method(..) => {
694                 intravisit::walk_fn(self, fk, fd, b, s, hir_id)
695             }
696             intravisit::FnKind::Closure => {
697                 self.map.late_bound_vars.insert(hir_id, vec![]);
698                 let scope = Scope::Binder {
699                     hir_id,
700                     lifetimes: FxIndexMap::default(),
701                     next_early_index: self.next_early_index(),
702                     s: self.scope,
703                     track_lifetime_uses: true,
704                     opaque_type_parent: false,
705                     scope_type: BinderScopeType::Normal,
706                 };
707                 self.with(scope, move |_old_scope, this| {
708                     intravisit::walk_fn(this, fk, fd, b, s, hir_id)
709                 });
710             }
711         }
712     }
713
714     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
715         match &item.kind {
716             hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => {
717                 if let Some(of_trait) = of_trait {
718                     self.map.late_bound_vars.insert(of_trait.hir_ref_id, Vec::default());
719                 }
720             }
721             _ => {}
722         }
723         match item.kind {
724             hir::ItemKind::Fn(ref sig, ref generics, _) => {
725                 self.missing_named_lifetime_spots.push(generics.into());
726                 self.visit_early_late(None, item.hir_id(), &sig.decl, generics, |this| {
727                     intravisit::walk_item(this, item);
728                 });
729                 self.missing_named_lifetime_spots.pop();
730             }
731
732             hir::ItemKind::ExternCrate(_)
733             | hir::ItemKind::Use(..)
734             | hir::ItemKind::Macro(..)
735             | hir::ItemKind::Mod(..)
736             | hir::ItemKind::ForeignMod { .. }
737             | hir::ItemKind::GlobalAsm(..) => {
738                 // These sorts of items have no lifetime parameters at all.
739                 intravisit::walk_item(self, item);
740             }
741             hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => {
742                 // No lifetime parameters, but implied 'static.
743                 let scope = Scope::Elision { elide: Elide::Exact(Region::Static), s: ROOT_SCOPE };
744                 self.with(scope, |_, this| intravisit::walk_item(this, item));
745             }
746             hir::ItemKind::OpaqueTy(hir::OpaqueTy { .. }) => {
747                 // Opaque types are visited when we visit the
748                 // `TyKind::OpaqueDef`, so that they have the lifetimes from
749                 // their parent opaque_ty in scope.
750                 //
751                 // The core idea here is that since OpaqueTys are generated with the impl Trait as
752                 // their owner, we can keep going until we find the Item that owns that. We then
753                 // conservatively add all resolved lifetimes. Otherwise we run into problems in
754                 // cases like `type Foo<'a> = impl Bar<As = impl Baz + 'a>`.
755                 for (_hir_id, node) in
756                     self.tcx.hir().parent_iter(self.tcx.hir().local_def_id_to_hir_id(item.def_id))
757                 {
758                     match node {
759                         hir::Node::Item(parent_item) => {
760                             let resolved_lifetimes: &ResolveLifetimes =
761                                 self.tcx.resolve_lifetimes(item_for(self.tcx, parent_item.def_id));
762                             // We need to add *all* deps, since opaque tys may want them from *us*
763                             for (&owner, defs) in resolved_lifetimes.defs.iter() {
764                                 defs.iter().for_each(|(&local_id, region)| {
765                                     self.map.defs.insert(hir::HirId { owner, local_id }, *region);
766                                 });
767                             }
768                             for (&owner, late_bound) in resolved_lifetimes.late_bound.iter() {
769                                 late_bound.iter().for_each(|&local_id| {
770                                     self.map.late_bound.insert(hir::HirId { owner, local_id });
771                                 });
772                             }
773                             for (&owner, late_bound_vars) in
774                                 resolved_lifetimes.late_bound_vars.iter()
775                             {
776                                 late_bound_vars.iter().for_each(|(&local_id, late_bound_vars)| {
777                                     self.map.late_bound_vars.insert(
778                                         hir::HirId { owner, local_id },
779                                         late_bound_vars.clone(),
780                                     );
781                                 });
782                             }
783                             break;
784                         }
785                         hir::Node::Crate(_) => bug!("No Item about an OpaqueTy"),
786                         _ => {}
787                     }
788                 }
789             }
790             hir::ItemKind::TyAlias(_, ref generics)
791             | hir::ItemKind::Enum(_, ref generics)
792             | hir::ItemKind::Struct(_, ref generics)
793             | hir::ItemKind::Union(_, ref generics)
794             | hir::ItemKind::Trait(_, _, ref generics, ..)
795             | hir::ItemKind::TraitAlias(ref generics, ..)
796             | hir::ItemKind::Impl(hir::Impl { ref generics, .. }) => {
797                 self.missing_named_lifetime_spots.push(generics.into());
798
799                 // Impls permit `'_` to be used and it is equivalent to "some fresh lifetime name".
800                 // This is not true for other kinds of items.
801                 let track_lifetime_uses = matches!(item.kind, hir::ItemKind::Impl { .. });
802                 // These kinds of items have only early-bound lifetime parameters.
803                 let mut index = if sub_items_have_self_param(&item.kind) {
804                     1 // Self comes before lifetimes
805                 } else {
806                     0
807                 };
808                 let mut non_lifetime_count = 0;
809                 let lifetimes = generics
810                     .params
811                     .iter()
812                     .filter_map(|param| match param.kind {
813                         GenericParamKind::Lifetime { .. } => {
814                             Some(Region::early(self.tcx.hir(), &mut index, param))
815                         }
816                         GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
817                             non_lifetime_count += 1;
818                             None
819                         }
820                     })
821                     .collect();
822                 self.map.late_bound_vars.insert(item.hir_id(), vec![]);
823                 let scope = Scope::Binder {
824                     hir_id: item.hir_id(),
825                     lifetimes,
826                     next_early_index: index + non_lifetime_count,
827                     opaque_type_parent: true,
828                     track_lifetime_uses,
829                     scope_type: BinderScopeType::Normal,
830                     s: ROOT_SCOPE,
831                 };
832                 self.with(scope, |old_scope, this| {
833                     this.check_lifetime_params(old_scope, &generics.params);
834                     let scope = Scope::TraitRefBoundary { s: this.scope };
835                     this.with(scope, |_, this| {
836                         intravisit::walk_item(this, item);
837                     });
838                 });
839                 self.missing_named_lifetime_spots.pop();
840             }
841         }
842     }
843
844     fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
845         match item.kind {
846             hir::ForeignItemKind::Fn(ref decl, _, ref generics) => {
847                 self.visit_early_late(None, item.hir_id(), decl, generics, |this| {
848                     intravisit::walk_foreign_item(this, item);
849                 })
850             }
851             hir::ForeignItemKind::Static(..) => {
852                 intravisit::walk_foreign_item(self, item);
853             }
854             hir::ForeignItemKind::Type => {
855                 intravisit::walk_foreign_item(self, item);
856             }
857         }
858     }
859
860     #[tracing::instrument(level = "debug", skip(self))]
861     fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
862         match ty.kind {
863             hir::TyKind::BareFn(ref c) => {
864                 let next_early_index = self.next_early_index();
865                 let was_in_fn_syntax = self.is_in_fn_syntax;
866                 self.is_in_fn_syntax = true;
867                 let lifetime_span: Option<Span> =
868                     c.generic_params.iter().rev().find_map(|param| match param.kind {
869                         GenericParamKind::Lifetime { .. } => Some(param.span),
870                         _ => None,
871                     });
872                 let (span, span_type) = if let Some(span) = lifetime_span {
873                     (span.shrink_to_hi(), ForLifetimeSpanType::TypeTail)
874                 } else {
875                     (ty.span.shrink_to_lo(), ForLifetimeSpanType::TypeEmpty)
876                 };
877                 self.missing_named_lifetime_spots
878                     .push(MissingLifetimeSpot::HigherRanked { span, span_type });
879                 let (lifetimes, binders): (FxIndexMap<hir::ParamName, Region>, Vec<_>) = c
880                     .generic_params
881                     .iter()
882                     .filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
883                     .enumerate()
884                     .map(|(late_bound_idx, param)| {
885                         let pair = Region::late(late_bound_idx as u32, self.tcx.hir(), param);
886                         let r = late_region_as_bound_region(self.tcx, &pair.1);
887                         (pair, r)
888                     })
889                     .unzip();
890                 self.map.late_bound_vars.insert(ty.hir_id, binders);
891                 let scope = Scope::Binder {
892                     hir_id: ty.hir_id,
893                     lifetimes,
894                     s: self.scope,
895                     next_early_index,
896                     track_lifetime_uses: true,
897                     opaque_type_parent: false,
898                     scope_type: BinderScopeType::Normal,
899                 };
900                 self.with(scope, |old_scope, this| {
901                     // a bare fn has no bounds, so everything
902                     // contained within is scoped within its binder.
903                     this.check_lifetime_params(old_scope, &c.generic_params);
904                     intravisit::walk_ty(this, ty);
905                 });
906                 self.missing_named_lifetime_spots.pop();
907                 self.is_in_fn_syntax = was_in_fn_syntax;
908             }
909             hir::TyKind::TraitObject(bounds, ref lifetime, _) => {
910                 debug!(?bounds, ?lifetime, "TraitObject");
911                 let scope = Scope::TraitRefBoundary { s: self.scope };
912                 self.with(scope, |_, this| {
913                     for bound in bounds {
914                         this.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None);
915                     }
916                 });
917                 match lifetime.name {
918                     LifetimeName::Implicit(_) => {
919                         // For types like `dyn Foo`, we should
920                         // generate a special form of elided.
921                         span_bug!(ty.span, "object-lifetime-default expected, not implicit",);
922                     }
923                     LifetimeName::ImplicitObjectLifetimeDefault => {
924                         // If the user does not write *anything*, we
925                         // use the object lifetime defaulting
926                         // rules. So e.g., `Box<dyn Debug>` becomes
927                         // `Box<dyn Debug + 'static>`.
928                         self.resolve_object_lifetime_default(lifetime)
929                     }
930                     LifetimeName::Underscore => {
931                         // If the user writes `'_`, we use the *ordinary* elision
932                         // rules. So the `'_` in e.g., `Box<dyn Debug + '_>` will be
933                         // resolved the same as the `'_` in `&'_ Foo`.
934                         //
935                         // cc #48468
936                         self.resolve_elided_lifetimes(&[lifetime])
937                     }
938                     LifetimeName::Param(_) | LifetimeName::Static => {
939                         // If the user wrote an explicit name, use that.
940                         self.visit_lifetime(lifetime);
941                     }
942                     LifetimeName::Error => {}
943                 }
944             }
945             hir::TyKind::Rptr(ref lifetime_ref, ref mt) => {
946                 self.visit_lifetime(lifetime_ref);
947                 let scope = Scope::ObjectLifetimeDefault {
948                     lifetime: self.map.defs.get(&lifetime_ref.hir_id).cloned(),
949                     s: self.scope,
950                 };
951                 self.with(scope, |_, this| this.visit_ty(&mt.ty));
952             }
953             hir::TyKind::OpaqueDef(item_id, lifetimes) => {
954                 // Resolve the lifetimes in the bounds to the lifetime defs in the generics.
955                 // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
956                 // `type MyAnonTy<'b> = impl MyTrait<'b>;`
957                 //                 ^                  ^ this gets resolved in the scope of
958                 //                                      the opaque_ty generics
959                 let opaque_ty = self.tcx.hir().item(item_id);
960                 let (generics, bounds) = match opaque_ty.kind {
961                     // Named opaque `impl Trait` types are reached via `TyKind::Path`.
962                     // This arm is for `impl Trait` in the types of statics, constants and locals.
963                     hir::ItemKind::OpaqueTy(hir::OpaqueTy {
964                         origin: hir::OpaqueTyOrigin::TyAlias,
965                         ..
966                     }) => {
967                         intravisit::walk_ty(self, ty);
968
969                         // Elided lifetimes are not allowed in non-return
970                         // position impl Trait
971                         let scope = Scope::TraitRefBoundary { s: self.scope };
972                         self.with(scope, |_, this| {
973                             let scope = Scope::Elision { elide: Elide::Forbid, s: this.scope };
974                             this.with(scope, |_, this| {
975                                 intravisit::walk_item(this, opaque_ty);
976                             })
977                         });
978
979                         return;
980                     }
981                     // RPIT (return position impl trait)
982                     hir::ItemKind::OpaqueTy(hir::OpaqueTy {
983                         origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..),
984                         ref generics,
985                         bounds,
986                         ..
987                     }) => (generics, bounds),
988                     ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
989                 };
990
991                 // Resolve the lifetimes that are applied to the opaque type.
992                 // These are resolved in the current scope.
993                 // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
994                 // `fn foo<'a>() -> MyAnonTy<'a> { ... }`
995                 //          ^                 ^this gets resolved in the current scope
996                 for lifetime in lifetimes {
997                     let hir::GenericArg::Lifetime(lifetime) = lifetime else {
998                         continue
999                     };
1000                     self.visit_lifetime(lifetime);
1001
1002                     // Check for predicates like `impl for<'a> Trait<impl OtherTrait<'a>>`
1003                     // and ban them. Type variables instantiated inside binders aren't
1004                     // well-supported at the moment, so this doesn't work.
1005                     // In the future, this should be fixed and this error should be removed.
1006                     let def = self.map.defs.get(&lifetime.hir_id).cloned();
1007                     let Some(Region::LateBound(_, _, def_id)) = def else {
1008                         continue
1009                     };
1010                     let Some(def_id) = def_id.as_local() else {
1011                         continue
1012                     };
1013                     let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
1014                     // Ensure that the parent of the def is an item, not HRTB
1015                     let parent_id = self.tcx.hir().get_parent_node(hir_id);
1016                     if !parent_id.is_owner() {
1017                         if !self.trait_definition_only {
1018                             struct_span_err!(
1019                                 self.tcx.sess,
1020                                 lifetime.span,
1021                                 E0657,
1022                                 "`impl Trait` can only capture lifetimes \
1023                                     bound at the fn or impl level"
1024                             )
1025                             .emit();
1026                         }
1027                         self.uninsert_lifetime_on_error(lifetime, def.unwrap());
1028                     }
1029                 }
1030
1031                 // We want to start our early-bound indices at the end of the parent scope,
1032                 // not including any parent `impl Trait`s.
1033                 let mut index = self.next_early_index_for_opaque_type();
1034                 debug!(?index);
1035
1036                 let mut elision = None;
1037                 let mut lifetimes = FxIndexMap::default();
1038                 let mut non_lifetime_count = 0;
1039                 for param in generics.params {
1040                     match param.kind {
1041                         GenericParamKind::Lifetime { .. } => {
1042                             let (name, reg) = Region::early(self.tcx.hir(), &mut index, &param);
1043                             let Region::EarlyBound(_, def_id) = reg else {
1044                                 bug!();
1045                             };
1046                             // We cannot predict what lifetimes are unused in opaque type.
1047                             self.lifetime_uses.insert(def_id, LifetimeUseSet::Many);
1048                             if let hir::ParamName::Plain(Ident {
1049                                 name: kw::UnderscoreLifetime,
1050                                 ..
1051                             }) = name
1052                             {
1053                                 // Pick the elided lifetime "definition" if one exists
1054                                 // and use it to make an elision scope.
1055                                 elision = Some(reg);
1056                             } else {
1057                                 lifetimes.insert(name, reg);
1058                             }
1059                         }
1060                         GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
1061                             non_lifetime_count += 1;
1062                         }
1063                     }
1064                 }
1065                 let next_early_index = index + non_lifetime_count;
1066                 self.map.late_bound_vars.insert(ty.hir_id, vec![]);
1067
1068                 if let Some(elision_region) = elision {
1069                     let scope =
1070                         Scope::Elision { elide: Elide::Exact(elision_region), s: self.scope };
1071                     self.with(scope, |_old_scope, this| {
1072                         let scope = Scope::Binder {
1073                             hir_id: ty.hir_id,
1074                             lifetimes,
1075                             next_early_index,
1076                             s: this.scope,
1077                             track_lifetime_uses: true,
1078                             opaque_type_parent: false,
1079                             scope_type: BinderScopeType::Normal,
1080                         };
1081                         this.with(scope, |_old_scope, this| {
1082                             this.visit_generics(generics);
1083                             let scope = Scope::TraitRefBoundary { s: this.scope };
1084                             this.with(scope, |_, this| {
1085                                 for bound in bounds {
1086                                     this.visit_param_bound(bound);
1087                                 }
1088                             })
1089                         });
1090                     });
1091                 } else {
1092                     let scope = Scope::Binder {
1093                         hir_id: ty.hir_id,
1094                         lifetimes,
1095                         next_early_index,
1096                         s: self.scope,
1097                         track_lifetime_uses: true,
1098                         opaque_type_parent: false,
1099                         scope_type: BinderScopeType::Normal,
1100                     };
1101                     self.with(scope, |_old_scope, this| {
1102                         let scope = Scope::TraitRefBoundary { s: this.scope };
1103                         this.with(scope, |_, this| {
1104                             this.visit_generics(generics);
1105                             for bound in bounds {
1106                                 this.visit_param_bound(bound);
1107                             }
1108                         })
1109                     });
1110                 }
1111             }
1112             _ => intravisit::walk_ty(self, ty),
1113         }
1114     }
1115
1116     fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
1117         use self::hir::TraitItemKind::*;
1118         match trait_item.kind {
1119             Fn(ref sig, _) => {
1120                 self.missing_named_lifetime_spots.push((&trait_item.generics).into());
1121                 let tcx = self.tcx;
1122                 self.visit_early_late(
1123                     Some(tcx.hir().get_parent_item(trait_item.hir_id())),
1124                     trait_item.hir_id(),
1125                     &sig.decl,
1126                     &trait_item.generics,
1127                     |this| intravisit::walk_trait_item(this, trait_item),
1128                 );
1129                 self.missing_named_lifetime_spots.pop();
1130             }
1131             Type(bounds, ref ty) => {
1132                 self.missing_named_lifetime_spots.push((&trait_item.generics).into());
1133                 let generics = &trait_item.generics;
1134                 let mut index = self.next_early_index();
1135                 debug!("visit_ty: index = {}", index);
1136                 let mut non_lifetime_count = 0;
1137                 let lifetimes = generics
1138                     .params
1139                     .iter()
1140                     .filter_map(|param| match param.kind {
1141                         GenericParamKind::Lifetime { .. } => {
1142                             Some(Region::early(self.tcx.hir(), &mut index, param))
1143                         }
1144                         GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
1145                             non_lifetime_count += 1;
1146                             None
1147                         }
1148                     })
1149                     .collect();
1150                 self.map.late_bound_vars.insert(trait_item.hir_id(), vec![]);
1151                 let scope = Scope::Binder {
1152                     hir_id: trait_item.hir_id(),
1153                     lifetimes,
1154                     next_early_index: index + non_lifetime_count,
1155                     s: self.scope,
1156                     track_lifetime_uses: true,
1157                     opaque_type_parent: true,
1158                     scope_type: BinderScopeType::Normal,
1159                 };
1160                 self.with(scope, |old_scope, this| {
1161                     this.check_lifetime_params(old_scope, &generics.params);
1162                     let scope = Scope::TraitRefBoundary { s: this.scope };
1163                     this.with(scope, |_, this| {
1164                         this.visit_generics(generics);
1165                         for bound in bounds {
1166                             this.visit_param_bound(bound);
1167                         }
1168                         if let Some(ty) = ty {
1169                             this.visit_ty(ty);
1170                         }
1171                     })
1172                 });
1173                 self.missing_named_lifetime_spots.pop();
1174             }
1175             Const(_, _) => {
1176                 // Only methods and types support generics.
1177                 assert!(trait_item.generics.params.is_empty());
1178                 self.missing_named_lifetime_spots.push(MissingLifetimeSpot::Static);
1179                 intravisit::walk_trait_item(self, trait_item);
1180                 self.missing_named_lifetime_spots.pop();
1181             }
1182         }
1183     }
1184
1185     fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
1186         use self::hir::ImplItemKind::*;
1187         match impl_item.kind {
1188             Fn(ref sig, _) => {
1189                 self.missing_named_lifetime_spots.push((&impl_item.generics).into());
1190                 let tcx = self.tcx;
1191                 self.visit_early_late(
1192                     Some(tcx.hir().get_parent_item(impl_item.hir_id())),
1193                     impl_item.hir_id(),
1194                     &sig.decl,
1195                     &impl_item.generics,
1196                     |this| intravisit::walk_impl_item(this, impl_item),
1197                 );
1198                 self.missing_named_lifetime_spots.pop();
1199             }
1200             TyAlias(ref ty) => {
1201                 let generics = &impl_item.generics;
1202                 self.missing_named_lifetime_spots.push(generics.into());
1203                 let mut index = self.next_early_index();
1204                 let mut non_lifetime_count = 0;
1205                 debug!("visit_ty: index = {}", index);
1206                 let lifetimes: FxIndexMap<hir::ParamName, Region> = generics
1207                     .params
1208                     .iter()
1209                     .filter_map(|param| match param.kind {
1210                         GenericParamKind::Lifetime { .. } => {
1211                             Some(Region::early(self.tcx.hir(), &mut index, param))
1212                         }
1213                         GenericParamKind::Const { .. } | GenericParamKind::Type { .. } => {
1214                             non_lifetime_count += 1;
1215                             None
1216                         }
1217                     })
1218                     .collect();
1219                 self.map.late_bound_vars.insert(ty.hir_id, vec![]);
1220                 let scope = Scope::Binder {
1221                     hir_id: ty.hir_id,
1222                     lifetimes,
1223                     next_early_index: index + non_lifetime_count,
1224                     s: self.scope,
1225                     track_lifetime_uses: true,
1226                     opaque_type_parent: true,
1227                     scope_type: BinderScopeType::Normal,
1228                 };
1229                 self.with(scope, |old_scope, this| {
1230                     this.check_lifetime_params(old_scope, &generics.params);
1231                     let scope = Scope::TraitRefBoundary { s: this.scope };
1232                     this.with(scope, |_, this| {
1233                         this.visit_generics(generics);
1234                         this.visit_ty(ty);
1235                     })
1236                 });
1237                 self.missing_named_lifetime_spots.pop();
1238             }
1239             Const(_, _) => {
1240                 // Only methods and types support generics.
1241                 assert!(impl_item.generics.params.is_empty());
1242                 self.missing_named_lifetime_spots.push(MissingLifetimeSpot::Static);
1243                 intravisit::walk_impl_item(self, impl_item);
1244                 self.missing_named_lifetime_spots.pop();
1245             }
1246         }
1247     }
1248
1249     #[tracing::instrument(level = "debug", skip(self))]
1250     fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
1251         if lifetime_ref.is_elided() {
1252             self.resolve_elided_lifetimes(&[lifetime_ref]);
1253             return;
1254         }
1255         if lifetime_ref.is_static() {
1256             self.insert_lifetime(lifetime_ref, Region::Static);
1257             return;
1258         }
1259         if self.is_in_const_generic && lifetime_ref.name != LifetimeName::Error {
1260             self.emit_non_static_lt_in_const_generic_error(lifetime_ref);
1261             return;
1262         }
1263         self.resolve_lifetime_ref(lifetime_ref);
1264     }
1265
1266     fn visit_assoc_type_binding(&mut self, type_binding: &'tcx hir::TypeBinding<'_>) {
1267         let scope = self.scope;
1268         if let Some(scope_for_path) = self.map.scope_for_path.as_mut() {
1269             // We add lifetime scope information for `Ident`s in associated type bindings and use
1270             // the `HirId` of the type binding as the key in `LifetimeMap`
1271             let lifetime_scope = get_lifetime_scopes_for_path(scope);
1272             let map = scope_for_path.entry(type_binding.hir_id.owner).or_default();
1273             map.insert(type_binding.hir_id.local_id, lifetime_scope);
1274         }
1275         hir::intravisit::walk_assoc_type_binding(self, type_binding);
1276     }
1277
1278     fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, _: hir::HirId) {
1279         for (i, segment) in path.segments.iter().enumerate() {
1280             let depth = path.segments.len() - i - 1;
1281             if let Some(ref args) = segment.args {
1282                 self.visit_segment_args(path.res, depth, args);
1283             }
1284
1285             let scope = self.scope;
1286             if let Some(scope_for_path) = self.map.scope_for_path.as_mut() {
1287                 // Add lifetime scope information to path segment. Note we cannot call `visit_path_segment`
1288                 // here because that call would yield to resolution problems due to `walk_path_segment`
1289                 // being called, which processes the path segments generic args, which we have already
1290                 // processed using `visit_segment_args`.
1291                 let lifetime_scope = get_lifetime_scopes_for_path(scope);
1292                 if let Some(hir_id) = segment.hir_id {
1293                     let map = scope_for_path.entry(hir_id.owner).or_default();
1294                     map.insert(hir_id.local_id, lifetime_scope);
1295                 }
1296             }
1297         }
1298     }
1299
1300     fn visit_path_segment(&mut self, path_span: Span, path_segment: &'tcx hir::PathSegment<'tcx>) {
1301         let scope = self.scope;
1302         if let Some(scope_for_path) = self.map.scope_for_path.as_mut() {
1303             let lifetime_scope = get_lifetime_scopes_for_path(scope);
1304             if let Some(hir_id) = path_segment.hir_id {
1305                 let map = scope_for_path.entry(hir_id.owner).or_default();
1306                 map.insert(hir_id.local_id, lifetime_scope);
1307             }
1308         }
1309
1310         intravisit::walk_path_segment(self, path_span, path_segment);
1311     }
1312
1313     fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl<'tcx>) {
1314         let output = match fd.output {
1315             hir::FnRetTy::DefaultReturn(_) => None,
1316             hir::FnRetTy::Return(ref ty) => Some(&**ty),
1317         };
1318         self.visit_fn_like_elision(&fd.inputs, output);
1319     }
1320
1321     fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
1322         let scope = Scope::TraitRefBoundary { s: self.scope };
1323         self.with(scope, |_, this| {
1324             for param in generics.params {
1325                 match param.kind {
1326                     GenericParamKind::Lifetime { .. } => {}
1327                     GenericParamKind::Type { ref default, .. } => {
1328                         walk_list!(this, visit_param_bound, param.bounds);
1329                         if let Some(ref ty) = default {
1330                             this.visit_ty(&ty);
1331                         }
1332                     }
1333                     GenericParamKind::Const { ref ty, default } => {
1334                         let was_in_const_generic = this.is_in_const_generic;
1335                         this.is_in_const_generic = true;
1336                         walk_list!(this, visit_param_bound, param.bounds);
1337                         this.visit_ty(&ty);
1338                         if let Some(default) = default {
1339                             this.visit_body(this.tcx.hir().body(default.body));
1340                         }
1341                         this.is_in_const_generic = was_in_const_generic;
1342                     }
1343                 }
1344             }
1345             for predicate in generics.where_clause.predicates {
1346                 match predicate {
1347                     &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
1348                         ref bounded_ty,
1349                         bounds,
1350                         ref bound_generic_params,
1351                         ..
1352                     }) => {
1353                         let (lifetimes, binders): (FxIndexMap<hir::ParamName, Region>, Vec<_>) =
1354                             bound_generic_params
1355                                 .iter()
1356                                 .filter(|param| {
1357                                     matches!(param.kind, GenericParamKind::Lifetime { .. })
1358                                 })
1359                                 .enumerate()
1360                                 .map(|(late_bound_idx, param)| {
1361                                     let pair =
1362                                         Region::late(late_bound_idx as u32, this.tcx.hir(), param);
1363                                     let r = late_region_as_bound_region(this.tcx, &pair.1);
1364                                     (pair, r)
1365                                 })
1366                                 .unzip();
1367                         this.map.late_bound_vars.insert(bounded_ty.hir_id, binders.clone());
1368                         let next_early_index = this.next_early_index();
1369                         // Even if there are no lifetimes defined here, we still wrap it in a binder
1370                         // scope. If there happens to be a nested poly trait ref (an error), that
1371                         // will be `Concatenating` anyways, so we don't have to worry about the depth
1372                         // being wrong.
1373                         let scope = Scope::Binder {
1374                             hir_id: bounded_ty.hir_id,
1375                             lifetimes,
1376                             s: this.scope,
1377                             next_early_index,
1378                             track_lifetime_uses: true,
1379                             opaque_type_parent: false,
1380                             scope_type: BinderScopeType::Normal,
1381                         };
1382                         this.with(scope, |old_scope, this| {
1383                             this.check_lifetime_params(old_scope, &bound_generic_params);
1384                             this.visit_ty(&bounded_ty);
1385                             walk_list!(this, visit_param_bound, bounds);
1386                         })
1387                     }
1388                     &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
1389                         ref lifetime,
1390                         bounds,
1391                         ..
1392                     }) => {
1393                         this.visit_lifetime(lifetime);
1394                         walk_list!(this, visit_param_bound, bounds);
1395                     }
1396                     &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
1397                         ref lhs_ty,
1398                         ref rhs_ty,
1399                         ..
1400                     }) => {
1401                         this.visit_ty(lhs_ty);
1402                         this.visit_ty(rhs_ty);
1403                     }
1404                 }
1405             }
1406         })
1407     }
1408
1409     fn visit_param_bound(&mut self, bound: &'tcx hir::GenericBound<'tcx>) {
1410         match bound {
1411             hir::GenericBound::LangItemTrait(_, _, hir_id, _) => {
1412                 // FIXME(jackh726): This is pretty weird. `LangItemTrait` doesn't go
1413                 // through the regular poly trait ref code, so we don't get another
1414                 // chance to introduce a binder. For now, I'm keeping the existing logic
1415                 // of "if there isn't a Binder scope above us, add one", but I
1416                 // imagine there's a better way to go about this.
1417                 let (binders, scope_type) = self.poly_trait_ref_binder_info();
1418
1419                 self.map.late_bound_vars.insert(*hir_id, binders);
1420                 let scope = Scope::Binder {
1421                     hir_id: *hir_id,
1422                     lifetimes: FxIndexMap::default(),
1423                     s: self.scope,
1424                     next_early_index: self.next_early_index(),
1425                     track_lifetime_uses: true,
1426                     opaque_type_parent: false,
1427                     scope_type,
1428                 };
1429                 self.with(scope, |_, this| {
1430                     intravisit::walk_param_bound(this, bound);
1431                 });
1432             }
1433             _ => intravisit::walk_param_bound(self, bound),
1434         }
1435     }
1436
1437     fn visit_poly_trait_ref(
1438         &mut self,
1439         trait_ref: &'tcx hir::PolyTraitRef<'tcx>,
1440         _modifier: hir::TraitBoundModifier,
1441     ) {
1442         debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref);
1443
1444         let should_pop_missing_lt = self.is_trait_ref_fn_scope(trait_ref);
1445
1446         let next_early_index = self.next_early_index();
1447         let (mut binders, scope_type) = self.poly_trait_ref_binder_info();
1448
1449         let initial_bound_vars = binders.len() as u32;
1450         let mut lifetimes: FxIndexMap<hir::ParamName, Region> = FxIndexMap::default();
1451         let binders_iter = trait_ref
1452             .bound_generic_params
1453             .iter()
1454             .filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
1455             .enumerate()
1456             .map(|(late_bound_idx, param)| {
1457                 let pair =
1458                     Region::late(initial_bound_vars + late_bound_idx as u32, self.tcx.hir(), param);
1459                 let r = late_region_as_bound_region(self.tcx, &pair.1);
1460                 lifetimes.insert(pair.0, pair.1);
1461                 r
1462             });
1463         binders.extend(binders_iter);
1464
1465         debug!(?binders);
1466         self.map.late_bound_vars.insert(trait_ref.trait_ref.hir_ref_id, binders);
1467
1468         // Always introduce a scope here, even if this is in a where clause and
1469         // we introduced the binders around the bounded Ty. In that case, we
1470         // just reuse the concatenation functionality also present in nested trait
1471         // refs.
1472         let scope = Scope::Binder {
1473             hir_id: trait_ref.trait_ref.hir_ref_id,
1474             lifetimes,
1475             s: self.scope,
1476             next_early_index,
1477             track_lifetime_uses: true,
1478             opaque_type_parent: false,
1479             scope_type,
1480         };
1481         self.with(scope, |old_scope, this| {
1482             this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params);
1483             walk_list!(this, visit_generic_param, trait_ref.bound_generic_params);
1484             this.visit_trait_ref(&trait_ref.trait_ref);
1485         });
1486
1487         if should_pop_missing_lt {
1488             self.missing_named_lifetime_spots.pop();
1489         }
1490     }
1491 }
1492
1493 #[derive(Copy, Clone, PartialEq)]
1494 enum ShadowKind {
1495     Label,
1496     Lifetime,
1497 }
1498 struct Original {
1499     kind: ShadowKind,
1500     span: Span,
1501 }
1502 struct Shadower {
1503     kind: ShadowKind,
1504     span: Span,
1505 }
1506
1507 fn original_label(span: Span) -> Original {
1508     Original { kind: ShadowKind::Label, span }
1509 }
1510 fn shadower_label(span: Span) -> Shadower {
1511     Shadower { kind: ShadowKind::Label, span }
1512 }
1513 fn original_lifetime(span: Span) -> Original {
1514     Original { kind: ShadowKind::Lifetime, span }
1515 }
1516 fn shadower_lifetime(param: &hir::GenericParam<'_>) -> Shadower {
1517     Shadower { kind: ShadowKind::Lifetime, span: param.span }
1518 }
1519
1520 impl ShadowKind {
1521     fn desc(&self) -> &'static str {
1522         match *self {
1523             ShadowKind::Label => "label",
1524             ShadowKind::Lifetime => "lifetime",
1525         }
1526     }
1527 }
1528
1529 fn signal_shadowing_problem(tcx: TyCtxt<'_>, name: Symbol, orig: Original, shadower: Shadower) {
1530     let mut err = if let (ShadowKind::Lifetime, ShadowKind::Lifetime) = (orig.kind, shadower.kind) {
1531         // lifetime/lifetime shadowing is an error
1532         struct_span_err!(
1533             tcx.sess,
1534             shadower.span,
1535             E0496,
1536             "{} name `{}` shadows a \
1537              {} name that is already in scope",
1538             shadower.kind.desc(),
1539             name,
1540             orig.kind.desc()
1541         )
1542         .forget_guarantee()
1543     } else {
1544         // shadowing involving a label is only a warning, due to issues with
1545         // labels and lifetimes not being macro-hygienic.
1546         tcx.sess.struct_span_warn(
1547             shadower.span,
1548             &format!(
1549                 "{} name `{}` shadows a \
1550                  {} name that is already in scope",
1551                 shadower.kind.desc(),
1552                 name,
1553                 orig.kind.desc()
1554             ),
1555         )
1556     };
1557     err.span_label(orig.span, "first declared here");
1558     err.span_label(shadower.span, format!("{} `{}` already in scope", orig.kind.desc(), name));
1559     err.emit();
1560 }
1561
1562 // Adds all labels in `b` to `ctxt.labels_in_fn`, signalling a warning
1563 // if one of the label shadows a lifetime or another label.
1564 fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) {
1565     struct GatherLabels<'a, 'tcx> {
1566         tcx: TyCtxt<'tcx>,
1567         scope: ScopeRef<'a>,
1568         labels_in_fn: &'a mut Vec<Ident>,
1569     }
1570
1571     let mut gather =
1572         GatherLabels { tcx: ctxt.tcx, scope: ctxt.scope, labels_in_fn: &mut ctxt.labels_in_fn };
1573     gather.visit_body(body);
1574
1575     impl<'v, 'a, 'tcx> Visitor<'v> for GatherLabels<'a, 'tcx> {
1576         fn visit_expr(&mut self, ex: &hir::Expr<'_>) {
1577             if let Some(label) = expression_label(ex) {
1578                 for prior_label in &self.labels_in_fn[..] {
1579                     // FIXME (#24278): non-hygienic comparison
1580                     if label.name == prior_label.name {
1581                         signal_shadowing_problem(
1582                             self.tcx,
1583                             label.name,
1584                             original_label(prior_label.span),
1585                             shadower_label(label.span),
1586                         );
1587                     }
1588                 }
1589
1590                 check_if_label_shadows_lifetime(self.tcx, self.scope, label);
1591
1592                 self.labels_in_fn.push(label);
1593             }
1594             intravisit::walk_expr(self, ex)
1595         }
1596     }
1597
1598     fn expression_label(ex: &hir::Expr<'_>) -> Option<Ident> {
1599         match ex.kind {
1600             hir::ExprKind::Loop(_, Some(label), ..) => Some(label.ident),
1601             hir::ExprKind::Block(_, Some(label)) => Some(label.ident),
1602             _ => None,
1603         }
1604     }
1605
1606     fn check_if_label_shadows_lifetime(tcx: TyCtxt<'_>, mut scope: ScopeRef<'_>, label: Ident) {
1607         loop {
1608             match *scope {
1609                 Scope::Body { s, .. }
1610                 | Scope::Elision { s, .. }
1611                 | Scope::ObjectLifetimeDefault { s, .. }
1612                 | Scope::Supertrait { s, .. }
1613                 | Scope::TraitRefBoundary { s, .. } => {
1614                     scope = s;
1615                 }
1616
1617                 Scope::Root => {
1618                     return;
1619                 }
1620
1621                 Scope::Binder { ref lifetimes, s, .. } => {
1622                     // FIXME (#24278): non-hygienic comparison
1623                     if let Some(def) =
1624                         lifetimes.get(&hir::ParamName::Plain(label.normalize_to_macros_2_0()))
1625                     {
1626                         signal_shadowing_problem(
1627                             tcx,
1628                             label.name,
1629                             original_lifetime(tcx.def_span(def.id().unwrap().expect_local())),
1630                             shadower_label(label.span),
1631                         );
1632                         return;
1633                     }
1634                     scope = s;
1635                 }
1636             }
1637         }
1638     }
1639 }
1640
1641 fn compute_object_lifetime_defaults<'tcx>(
1642     tcx: TyCtxt<'tcx>,
1643     item: &hir::Item<'_>,
1644 ) -> Option<&'tcx [ObjectLifetimeDefault]> {
1645     match item.kind {
1646         hir::ItemKind::Struct(_, ref generics)
1647         | hir::ItemKind::Union(_, ref generics)
1648         | hir::ItemKind::Enum(_, ref generics)
1649         | hir::ItemKind::OpaqueTy(hir::OpaqueTy {
1650             ref generics,
1651             origin: hir::OpaqueTyOrigin::TyAlias,
1652             ..
1653         })
1654         | hir::ItemKind::TyAlias(_, ref generics)
1655         | hir::ItemKind::Trait(_, _, ref generics, ..) => {
1656             let result = object_lifetime_defaults_for_item(tcx, generics);
1657
1658             // Debugging aid.
1659             let attrs = tcx.hir().attrs(item.hir_id());
1660             if tcx.sess.contains_name(attrs, sym::rustc_object_lifetime_default) {
1661                 let object_lifetime_default_reprs: String = result
1662                     .iter()
1663                     .map(|set| match *set {
1664                         Set1::Empty => "BaseDefault".into(),
1665                         Set1::One(Region::Static) => "'static".into(),
1666                         Set1::One(Region::EarlyBound(mut i, _)) => generics
1667                             .params
1668                             .iter()
1669                             .find_map(|param| match param.kind {
1670                                 GenericParamKind::Lifetime { .. } => {
1671                                     if i == 0 {
1672                                         return Some(param.name.ident().to_string().into());
1673                                     }
1674                                     i -= 1;
1675                                     None
1676                                 }
1677                                 _ => None,
1678                             })
1679                             .unwrap(),
1680                         Set1::One(_) => bug!(),
1681                         Set1::Many => "Ambiguous".into(),
1682                     })
1683                     .collect::<Vec<Cow<'static, str>>>()
1684                     .join(",");
1685                 tcx.sess.span_err(item.span, &object_lifetime_default_reprs);
1686             }
1687
1688             Some(result)
1689         }
1690         _ => None,
1691     }
1692 }
1693
1694 /// Scan the bounds and where-clauses on parameters to extract bounds
1695 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
1696 /// for each type parameter.
1697 fn object_lifetime_defaults_for_item<'tcx>(
1698     tcx: TyCtxt<'tcx>,
1699     generics: &hir::Generics<'_>,
1700 ) -> &'tcx [ObjectLifetimeDefault] {
1701     fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::GenericBound<'_>]) {
1702         for bound in bounds {
1703             if let hir::GenericBound::Outlives(ref lifetime) = *bound {
1704                 set.insert(lifetime.name.normalize_to_macros_2_0());
1705             }
1706         }
1707     }
1708
1709     let process_param = |param: &hir::GenericParam<'_>| match param.kind {
1710         GenericParamKind::Lifetime { .. } => None,
1711         GenericParamKind::Type { .. } => {
1712             let mut set = Set1::Empty;
1713
1714             add_bounds(&mut set, &param.bounds);
1715
1716             let param_def_id = tcx.hir().local_def_id(param.hir_id);
1717             for predicate in generics.where_clause.predicates {
1718                 // Look for `type: ...` where clauses.
1719                 let hir::WherePredicate::BoundPredicate(ref data) = *predicate else { continue };
1720
1721                 // Ignore `for<'a> type: ...` as they can change what
1722                 // lifetimes mean (although we could "just" handle it).
1723                 if !data.bound_generic_params.is_empty() {
1724                     continue;
1725                 }
1726
1727                 let res = match data.bounded_ty.kind {
1728                     hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => path.res,
1729                     _ => continue,
1730                 };
1731
1732                 if res == Res::Def(DefKind::TyParam, param_def_id.to_def_id()) {
1733                     add_bounds(&mut set, &data.bounds);
1734                 }
1735             }
1736
1737             Some(match set {
1738                 Set1::Empty => Set1::Empty,
1739                 Set1::One(name) => {
1740                     if name == hir::LifetimeName::Static {
1741                         Set1::One(Region::Static)
1742                     } else {
1743                         generics
1744                             .params
1745                             .iter()
1746                             .filter_map(|param| match param.kind {
1747                                 GenericParamKind::Lifetime { .. } => {
1748                                     Some((param.hir_id, hir::LifetimeName::Param(param.name)))
1749                                 }
1750                                 _ => None,
1751                             })
1752                             .enumerate()
1753                             .find(|&(_, (_, lt_name))| lt_name == name)
1754                             .map_or(Set1::Many, |(i, (id, _))| {
1755                                 let def_id = tcx.hir().local_def_id(id);
1756                                 Set1::One(Region::EarlyBound(i as u32, def_id.to_def_id()))
1757                             })
1758                     }
1759                 }
1760                 Set1::Many => Set1::Many,
1761             })
1762         }
1763         GenericParamKind::Const { .. } => {
1764             // Generic consts don't impose any constraints.
1765             //
1766             // We still store a dummy value here to allow generic parameters
1767             // in an arbitrary order.
1768             Some(Set1::Empty)
1769         }
1770     };
1771
1772     tcx.arena.alloc_from_iter(generics.params.iter().filter_map(process_param))
1773 }
1774
1775 impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
1776     fn with<F>(&mut self, wrap_scope: Scope<'_>, f: F)
1777     where
1778         F: for<'b> FnOnce(ScopeRef<'_>, &mut LifetimeContext<'b, 'tcx>),
1779     {
1780         let LifetimeContext { tcx, map, lifetime_uses, .. } = self;
1781         let labels_in_fn = take(&mut self.labels_in_fn);
1782         let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults);
1783         let missing_named_lifetime_spots = take(&mut self.missing_named_lifetime_spots);
1784         let mut this = LifetimeContext {
1785             tcx: *tcx,
1786             map,
1787             scope: &wrap_scope,
1788             is_in_fn_syntax: self.is_in_fn_syntax,
1789             is_in_const_generic: self.is_in_const_generic,
1790             trait_definition_only: self.trait_definition_only,
1791             labels_in_fn,
1792             xcrate_object_lifetime_defaults,
1793             lifetime_uses,
1794             missing_named_lifetime_spots,
1795         };
1796         let span = tracing::debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope));
1797         {
1798             let _enter = span.enter();
1799             f(self.scope, &mut this);
1800             if !self.trait_definition_only {
1801                 this.check_uses_for_lifetimes_defined_by_scope();
1802             }
1803         }
1804         self.labels_in_fn = this.labels_in_fn;
1805         self.xcrate_object_lifetime_defaults = this.xcrate_object_lifetime_defaults;
1806         self.missing_named_lifetime_spots = this.missing_named_lifetime_spots;
1807     }
1808
1809     /// helper method to determine the span to remove when suggesting the
1810     /// deletion of a lifetime
1811     fn lifetime_deletion_span(&self, name: Ident, generics: &hir::Generics<'_>) -> Option<Span> {
1812         generics.params.iter().enumerate().find_map(|(i, param)| {
1813             if param.name.ident() == name {
1814                 if generics.params.len() == 1 {
1815                     // if sole lifetime, remove the entire `<>` brackets
1816                     Some(generics.span)
1817                 } else {
1818                     // if removing within `<>` brackets, we also want to
1819                     // delete a leading or trailing comma as appropriate
1820                     if i >= generics.params.len() - 1 {
1821                         Some(generics.params[i - 1].span.shrink_to_hi().to(param.span))
1822                     } else {
1823                         Some(param.span.to(generics.params[i + 1].span.shrink_to_lo()))
1824                     }
1825                 }
1826             } else {
1827                 None
1828             }
1829         })
1830     }
1831
1832     // helper method to issue suggestions from `fn rah<'a>(&'a T)` to `fn rah(&T)`
1833     // or from `fn rah<'a>(T<'a>)` to `fn rah(T<'_>)`
1834     fn suggest_eliding_single_use_lifetime(
1835         &self,
1836         err: &mut Diagnostic,
1837         def_id: DefId,
1838         lifetime: &hir::Lifetime,
1839     ) {
1840         let name = lifetime.name.ident();
1841         let remove_decl = self
1842             .tcx
1843             .parent(def_id)
1844             .and_then(|parent_def_id| parent_def_id.as_local())
1845             .and_then(|parent_def_id| self.tcx.hir().get_generics(parent_def_id))
1846             .and_then(|generics| self.lifetime_deletion_span(name, generics));
1847
1848         let mut remove_use = None;
1849         let mut elide_use = None;
1850         let mut find_arg_use_span = |inputs: &[hir::Ty<'_>]| {
1851             for input in inputs {
1852                 match input.kind {
1853                     hir::TyKind::Rptr(lt, _) => {
1854                         if lt.name.ident() == name {
1855                             // include the trailing whitespace between the lifetime and type names
1856                             let lt_through_ty_span = lifetime.span.to(input.span.shrink_to_hi());
1857                             remove_use = Some(
1858                                 self.tcx
1859                                     .sess
1860                                     .source_map()
1861                                     .span_until_non_whitespace(lt_through_ty_span),
1862                             );
1863                             break;
1864                         }
1865                     }
1866                     hir::TyKind::Path(QPath::Resolved(_, path)) => {
1867                         let last_segment = &path.segments[path.segments.len() - 1];
1868                         let generics = last_segment.args();
1869                         for arg in generics.args.iter() {
1870                             if let GenericArg::Lifetime(lt) = arg {
1871                                 if lt.name.ident() == name {
1872                                     elide_use = Some(lt.span);
1873                                     break;
1874                                 }
1875                             }
1876                         }
1877                         break;
1878                     }
1879                     _ => {}
1880                 }
1881             }
1882         };
1883         if let Node::Lifetime(hir_lifetime) = self.tcx.hir().get(lifetime.hir_id) {
1884             if let Some(parent) =
1885                 self.tcx.hir().find_by_def_id(self.tcx.hir().get_parent_item(hir_lifetime.hir_id))
1886             {
1887                 match parent {
1888                     Node::Item(item) => {
1889                         if let hir::ItemKind::Fn(sig, _, _) = &item.kind {
1890                             find_arg_use_span(sig.decl.inputs);
1891                         }
1892                     }
1893                     Node::ImplItem(impl_item) => {
1894                         if let hir::ImplItemKind::Fn(sig, _) = &impl_item.kind {
1895                             find_arg_use_span(sig.decl.inputs);
1896                         }
1897                     }
1898                     _ => {}
1899                 }
1900             }
1901         }
1902
1903         let msg = "elide the single-use lifetime";
1904         match (remove_decl, remove_use, elide_use) {
1905             (Some(decl_span), Some(use_span), None) => {
1906                 // if both declaration and use deletion spans start at the same
1907                 // place ("start at" because the latter includes trailing
1908                 // whitespace), then this is an in-band lifetime
1909                 if decl_span.shrink_to_lo() == use_span.shrink_to_lo() {
1910                     err.span_suggestion(
1911                         use_span,
1912                         msg,
1913                         String::new(),
1914                         Applicability::MachineApplicable,
1915                     );
1916                 } else {
1917                     err.multipart_suggestion(
1918                         msg,
1919                         vec![(decl_span, String::new()), (use_span, String::new())],
1920                         Applicability::MachineApplicable,
1921                     );
1922                 }
1923             }
1924             (Some(decl_span), None, Some(use_span)) => {
1925                 err.multipart_suggestion(
1926                     msg,
1927                     vec![(decl_span, String::new()), (use_span, "'_".to_owned())],
1928                     Applicability::MachineApplicable,
1929                 );
1930             }
1931             _ => {}
1932         }
1933     }
1934
1935     fn check_uses_for_lifetimes_defined_by_scope(&mut self) {
1936         let Scope::Binder { lifetimes: defined_by, .. } = self.scope else {
1937             debug!("check_uses_for_lifetimes_defined_by_scope: not in a binder scope");
1938             return;
1939         };
1940
1941         let def_ids: Vec<_> = defined_by
1942             .values()
1943             .flat_map(|region| match region {
1944                 Region::EarlyBound(_, def_id)
1945                 | Region::LateBound(_, _, def_id)
1946                 | Region::Free(_, def_id) => Some(*def_id),
1947
1948                 Region::LateBoundAnon(..) | Region::Static => None,
1949             })
1950             .collect();
1951
1952         'lifetimes: for def_id in def_ids {
1953             debug!("check_uses_for_lifetimes_defined_by_scope: def_id = {:?}", def_id);
1954
1955             let lifetimeuseset = self.lifetime_uses.remove(&def_id);
1956
1957             debug!(
1958                 "check_uses_for_lifetimes_defined_by_scope: lifetimeuseset = {:?}",
1959                 lifetimeuseset
1960             );
1961
1962             match lifetimeuseset {
1963                 Some(LifetimeUseSet::One(lifetime)) => {
1964                     debug!(?def_id);
1965                     if let Some((id, span, name)) =
1966                         match self.tcx.hir().get_by_def_id(def_id.expect_local()) {
1967                             Node::Lifetime(hir_lifetime) => Some((
1968                                 hir_lifetime.hir_id,
1969                                 hir_lifetime.span,
1970                                 hir_lifetime.name.ident(),
1971                             )),
1972                             Node::GenericParam(param) => {
1973                                 Some((param.hir_id, param.span, param.name.ident()))
1974                             }
1975                             _ => None,
1976                         }
1977                     {
1978                         debug!("id = {:?} span = {:?} name = {:?}", id, span, name);
1979                         if name.name == kw::UnderscoreLifetime {
1980                             continue;
1981                         }
1982
1983                         if let Some(parent_def_id) = self.tcx.parent(def_id) {
1984                             if let Some(def_id) = parent_def_id.as_local() {
1985                                 // lifetimes in `derive` expansions don't count (Issue #53738)
1986                                 if self
1987                                     .tcx
1988                                     .get_attrs(def_id.to_def_id())
1989                                     .iter()
1990                                     .any(|attr| attr.has_name(sym::automatically_derived))
1991                                 {
1992                                     continue;
1993                                 }
1994
1995                                 // opaque types generated when desugaring an async function can have a single
1996                                 // use lifetime even if it is explicitly denied (Issue #77175)
1997                                 if let hir::Node::Item(hir::Item {
1998                                     kind: hir::ItemKind::OpaqueTy(ref opaque),
1999                                     ..
2000                                 }) = self.tcx.hir().get_by_def_id(def_id)
2001                                 {
2002                                     if !matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn(..)) {
2003                                         continue 'lifetimes;
2004                                     }
2005                                     // We want to do this only if the liftime identifier is already defined
2006                                     // in the async function that generated this. Otherwise it could be
2007                                     // an opaque type defined by the developer and we still want this
2008                                     // lint to fail compilation
2009                                     for p in opaque.generics.params {
2010                                         if defined_by.contains_key(&p.name) {
2011                                             continue 'lifetimes;
2012                                         }
2013                                     }
2014                                 }
2015                             }
2016                         }
2017
2018                         self.tcx.struct_span_lint_hir(
2019                             lint::builtin::SINGLE_USE_LIFETIMES,
2020                             id,
2021                             span,
2022                             |lint| {
2023                                 let mut err = lint.build(&format!(
2024                                     "lifetime parameter `{}` only used once",
2025                                     name
2026                                 ));
2027                                 if span == lifetime.span {
2028                                     // spans are the same for in-band lifetime declarations
2029                                     err.span_label(span, "this lifetime is only used here");
2030                                 } else {
2031                                     err.span_label(span, "this lifetime...");
2032                                     err.span_label(lifetime.span, "...is used only here");
2033                                 }
2034                                 self.suggest_eliding_single_use_lifetime(
2035                                     &mut err, def_id, lifetime,
2036                                 );
2037                                 err.emit();
2038                             },
2039                         );
2040                     }
2041                 }
2042                 Some(LifetimeUseSet::Many) => {
2043                     debug!("not one use lifetime");
2044                 }
2045                 None => {
2046                     if let Some((id, span, name)) =
2047                         match self.tcx.hir().get_by_def_id(def_id.expect_local()) {
2048                             Node::Lifetime(hir_lifetime) => Some((
2049                                 hir_lifetime.hir_id,
2050                                 hir_lifetime.span,
2051                                 hir_lifetime.name.ident(),
2052                             )),
2053                             Node::GenericParam(param) => {
2054                                 Some((param.hir_id, param.span, param.name.ident()))
2055                             }
2056                             _ => None,
2057                         }
2058                     {
2059                         debug!("id ={:?} span = {:?} name = {:?}", id, span, name);
2060                         self.tcx.struct_span_lint_hir(
2061                             lint::builtin::UNUSED_LIFETIMES,
2062                             id,
2063                             span,
2064                             |lint| {
2065                                 let mut err = lint
2066                                     .build(&format!("lifetime parameter `{}` never used", name));
2067                                 if let Some(parent_def_id) = self.tcx.parent(def_id) {
2068                                     if let Some(generics) =
2069                                         self.tcx.hir().get_generics(parent_def_id.expect_local())
2070                                     {
2071                                         let unused_lt_span =
2072                                             self.lifetime_deletion_span(name, generics);
2073                                         if let Some(span) = unused_lt_span {
2074                                             err.span_suggestion(
2075                                                 span,
2076                                                 "elide the unused lifetime",
2077                                                 String::new(),
2078                                                 Applicability::MachineApplicable,
2079                                             );
2080                                         }
2081                                     }
2082                                 }
2083                                 err.emit();
2084                             },
2085                         );
2086                     }
2087                 }
2088             }
2089         }
2090     }
2091
2092     /// Visits self by adding a scope and handling recursive walk over the contents with `walk`.
2093     ///
2094     /// Handles visiting fns and methods. These are a bit complicated because we must distinguish
2095     /// early- vs late-bound lifetime parameters. We do this by checking which lifetimes appear
2096     /// within type bounds; those are early bound lifetimes, and the rest are late bound.
2097     ///
2098     /// For example:
2099     ///
2100     ///    fn foo<'a,'b,'c,T:Trait<'b>>(...)
2101     ///
2102     /// Here `'a` and `'c` are late bound but `'b` is early bound. Note that early- and late-bound
2103     /// lifetimes may be interspersed together.
2104     ///
2105     /// If early bound lifetimes are present, we separate them into their own list (and likewise
2106     /// for late bound). They will be numbered sequentially, starting from the lowest index that is
2107     /// already in scope (for a fn item, that will be 0, but for a method it might not be). Late
2108     /// bound lifetimes are resolved by name and associated with a binder ID (`binder_id`), so the
2109     /// ordering is not important there.
2110     fn visit_early_late<F>(
2111         &mut self,
2112         parent_id: Option<LocalDefId>,
2113         hir_id: hir::HirId,
2114         decl: &'tcx hir::FnDecl<'tcx>,
2115         generics: &'tcx hir::Generics<'tcx>,
2116         walk: F,
2117     ) where
2118         F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>),
2119     {
2120         insert_late_bound_lifetimes(self.map, decl, generics);
2121
2122         // Find the start of nested early scopes, e.g., in methods.
2123         let mut next_early_index = 0;
2124         if let Some(parent_id) = parent_id {
2125             let parent = self.tcx.hir().expect_item(parent_id);
2126             if sub_items_have_self_param(&parent.kind) {
2127                 next_early_index += 1; // Self comes before lifetimes
2128             }
2129             match parent.kind {
2130                 hir::ItemKind::Trait(_, _, ref generics, ..)
2131                 | hir::ItemKind::Impl(hir::Impl { ref generics, .. }) => {
2132                     next_early_index += generics.params.len() as u32;
2133                 }
2134                 _ => {}
2135             }
2136         }
2137
2138         let mut non_lifetime_count = 0;
2139         let mut named_late_bound_vars = 0;
2140         let lifetimes: FxIndexMap<hir::ParamName, Region> = generics
2141             .params
2142             .iter()
2143             .filter_map(|param| match param.kind {
2144                 GenericParamKind::Lifetime { .. } => {
2145                     if self.map.late_bound.contains(&param.hir_id) {
2146                         let late_bound_idx = named_late_bound_vars;
2147                         named_late_bound_vars += 1;
2148                         Some(Region::late(late_bound_idx, self.tcx.hir(), param))
2149                     } else {
2150                         Some(Region::early(self.tcx.hir(), &mut next_early_index, param))
2151                     }
2152                 }
2153                 GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
2154                     non_lifetime_count += 1;
2155                     None
2156                 }
2157             })
2158             .collect();
2159         let next_early_index = next_early_index + non_lifetime_count;
2160
2161         let binders: Vec<_> = generics
2162             .params
2163             .iter()
2164             .filter(|param| {
2165                 matches!(param.kind, GenericParamKind::Lifetime { .. })
2166                     && self.map.late_bound.contains(&param.hir_id)
2167             })
2168             .enumerate()
2169             .map(|(late_bound_idx, param)| {
2170                 let pair = Region::late(late_bound_idx as u32, self.tcx.hir(), param);
2171                 late_region_as_bound_region(self.tcx, &pair.1)
2172             })
2173             .collect();
2174         self.map.late_bound_vars.insert(hir_id, binders);
2175         let scope = Scope::Binder {
2176             hir_id,
2177             lifetimes,
2178             next_early_index,
2179             s: self.scope,
2180             opaque_type_parent: true,
2181             track_lifetime_uses: false,
2182             scope_type: BinderScopeType::Normal,
2183         };
2184         self.with(scope, move |old_scope, this| {
2185             this.check_lifetime_params(old_scope, &generics.params);
2186             walk(this);
2187         });
2188     }
2189
2190     fn next_early_index_helper(&self, only_opaque_type_parent: bool) -> u32 {
2191         let mut scope = self.scope;
2192         loop {
2193             match *scope {
2194                 Scope::Root => return 0,
2195
2196                 Scope::Binder { next_early_index, opaque_type_parent, .. }
2197                     if (!only_opaque_type_parent || opaque_type_parent) =>
2198                 {
2199                     return next_early_index;
2200                 }
2201
2202                 Scope::Binder { s, .. }
2203                 | Scope::Body { s, .. }
2204                 | Scope::Elision { s, .. }
2205                 | Scope::ObjectLifetimeDefault { s, .. }
2206                 | Scope::Supertrait { s, .. }
2207                 | Scope::TraitRefBoundary { s, .. } => scope = s,
2208             }
2209         }
2210     }
2211
2212     /// Returns the next index one would use for an early-bound-region
2213     /// if extending the current scope.
2214     fn next_early_index(&self) -> u32 {
2215         self.next_early_index_helper(true)
2216     }
2217
2218     /// Returns the next index one would use for an `impl Trait` that
2219     /// is being converted into an opaque type alias `impl Trait`. This will be the
2220     /// next early index from the enclosing item, for the most
2221     /// part. See the `opaque_type_parent` field for more info.
2222     fn next_early_index_for_opaque_type(&self) -> u32 {
2223         self.next_early_index_helper(false)
2224     }
2225
2226     fn resolve_lifetime_ref(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
2227         debug!("resolve_lifetime_ref(lifetime_ref={:?})", lifetime_ref);
2228
2229         // If we've already reported an error, just ignore `lifetime_ref`.
2230         if let LifetimeName::Error = lifetime_ref.name {
2231             return;
2232         }
2233
2234         // Walk up the scope chain, tracking the number of fn scopes
2235         // that we pass through, until we find a lifetime with the
2236         // given name or we run out of scopes.
2237         // search.
2238         let mut late_depth = 0;
2239         let mut scope = self.scope;
2240         let mut outermost_body = None;
2241         let result = loop {
2242             match *scope {
2243                 Scope::Body { id, s } => {
2244                     // Non-static lifetimes are prohibited in anonymous constants without
2245                     // `generic_const_exprs`.
2246                     self.maybe_emit_forbidden_non_static_lifetime_error(id, lifetime_ref);
2247
2248                     outermost_body = Some(id);
2249                     scope = s;
2250                 }
2251
2252                 Scope::Root => {
2253                     break None;
2254                 }
2255
2256                 Scope::Binder { ref lifetimes, scope_type, s, .. } => {
2257                     match lifetime_ref.name {
2258                         LifetimeName::Param(param_name) => {
2259                             if let Some(&def) = lifetimes.get(&param_name.normalize_to_macros_2_0())
2260                             {
2261                                 break Some(def.shifted(late_depth));
2262                             }
2263                         }
2264                         _ => bug!("expected LifetimeName::Param"),
2265                     }
2266                     match scope_type {
2267                         BinderScopeType::Normal => late_depth += 1,
2268                         BinderScopeType::Concatenating => {}
2269                     }
2270                     scope = s;
2271                 }
2272
2273                 Scope::Elision { s, .. }
2274                 | Scope::ObjectLifetimeDefault { s, .. }
2275                 | Scope::Supertrait { s, .. }
2276                 | Scope::TraitRefBoundary { s, .. } => {
2277                     scope = s;
2278                 }
2279             }
2280         };
2281
2282         if let Some(mut def) = result {
2283             if let Region::EarlyBound(..) = def {
2284                 // Do not free early-bound regions, only late-bound ones.
2285             } else if let Some(body_id) = outermost_body {
2286                 let fn_id = self.tcx.hir().body_owner(body_id);
2287                 match self.tcx.hir().get(fn_id) {
2288                     Node::Item(&hir::Item { kind: hir::ItemKind::Fn(..), .. })
2289                     | Node::TraitItem(&hir::TraitItem {
2290                         kind: hir::TraitItemKind::Fn(..), ..
2291                     })
2292                     | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => {
2293                         let scope = self.tcx.hir().local_def_id(fn_id);
2294                         def = Region::Free(scope.to_def_id(), def.id().unwrap());
2295                     }
2296                     _ => {}
2297                 }
2298             }
2299
2300             self.insert_lifetime(lifetime_ref, def);
2301         } else {
2302             self.emit_undeclared_lifetime_error(lifetime_ref);
2303         }
2304     }
2305
2306     fn visit_segment_args(
2307         &mut self,
2308         res: Res,
2309         depth: usize,
2310         generic_args: &'tcx hir::GenericArgs<'tcx>,
2311     ) {
2312         debug!(
2313             "visit_segment_args(res={:?}, depth={:?}, generic_args={:?})",
2314             res, depth, generic_args,
2315         );
2316
2317         if generic_args.parenthesized {
2318             let was_in_fn_syntax = self.is_in_fn_syntax;
2319             self.is_in_fn_syntax = true;
2320             self.visit_fn_like_elision(generic_args.inputs(), Some(generic_args.bindings[0].ty()));
2321             self.is_in_fn_syntax = was_in_fn_syntax;
2322             return;
2323         }
2324
2325         let mut elide_lifetimes = true;
2326         let lifetimes: Vec<_> = generic_args
2327             .args
2328             .iter()
2329             .filter_map(|arg| match arg {
2330                 hir::GenericArg::Lifetime(lt) => {
2331                     if !lt.is_elided() {
2332                         elide_lifetimes = false;
2333                     }
2334                     Some(lt)
2335                 }
2336                 _ => None,
2337             })
2338             .collect();
2339         // We short-circuit here if all are elided in order to pluralize
2340         // possible errors
2341         if elide_lifetimes {
2342             self.resolve_elided_lifetimes(&lifetimes);
2343         } else {
2344             lifetimes.iter().for_each(|lt| self.visit_lifetime(lt));
2345         }
2346
2347         // Figure out if this is a type/trait segment,
2348         // which requires object lifetime defaults.
2349         let parent_def_id = |this: &mut Self, def_id: DefId| {
2350             let def_key = this.tcx.def_key(def_id);
2351             DefId { krate: def_id.krate, index: def_key.parent.expect("missing parent") }
2352         };
2353         let type_def_id = match res {
2354             Res::Def(DefKind::AssocTy, def_id) if depth == 1 => Some(parent_def_id(self, def_id)),
2355             Res::Def(DefKind::Variant, def_id) if depth == 0 => Some(parent_def_id(self, def_id)),
2356             Res::Def(
2357                 DefKind::Struct
2358                 | DefKind::Union
2359                 | DefKind::Enum
2360                 | DefKind::TyAlias
2361                 | DefKind::Trait,
2362                 def_id,
2363             ) if depth == 0 => Some(def_id),
2364             _ => None,
2365         };
2366
2367         debug!("visit_segment_args: type_def_id={:?}", type_def_id);
2368
2369         // Compute a vector of defaults, one for each type parameter,
2370         // per the rules given in RFCs 599 and 1156. Example:
2371         //
2372         // ```rust
2373         // struct Foo<'a, T: 'a, U> { }
2374         // ```
2375         //
2376         // If you have `Foo<'x, dyn Bar, dyn Baz>`, we want to default
2377         // `dyn Bar` to `dyn Bar + 'x` (because of the `T: 'a` bound)
2378         // and `dyn Baz` to `dyn Baz + 'static` (because there is no
2379         // such bound).
2380         //
2381         // Therefore, we would compute `object_lifetime_defaults` to a
2382         // vector like `['x, 'static]`. Note that the vector only
2383         // includes type parameters.
2384         let object_lifetime_defaults = type_def_id.map_or_else(Vec::new, |def_id| {
2385             let in_body = {
2386                 let mut scope = self.scope;
2387                 loop {
2388                     match *scope {
2389                         Scope::Root => break false,
2390
2391                         Scope::Body { .. } => break true,
2392
2393                         Scope::Binder { s, .. }
2394                         | Scope::Elision { s, .. }
2395                         | Scope::ObjectLifetimeDefault { s, .. }
2396                         | Scope::Supertrait { s, .. }
2397                         | Scope::TraitRefBoundary { s, .. } => {
2398                             scope = s;
2399                         }
2400                     }
2401                 }
2402             };
2403
2404             let map = &self.map;
2405             let set_to_region = |set: &ObjectLifetimeDefault| match *set {
2406                 Set1::Empty => {
2407                     if in_body {
2408                         None
2409                     } else {
2410                         Some(Region::Static)
2411                     }
2412                 }
2413                 Set1::One(r) => {
2414                     let lifetimes = generic_args.args.iter().filter_map(|arg| match arg {
2415                         GenericArg::Lifetime(lt) => Some(lt),
2416                         _ => None,
2417                     });
2418                     r.subst(lifetimes, map)
2419                 }
2420                 Set1::Many => None,
2421             };
2422             if let Some(def_id) = def_id.as_local() {
2423                 let id = self.tcx.hir().local_def_id_to_hir_id(def_id);
2424                 self.tcx
2425                     .object_lifetime_defaults(id.owner)
2426                     .unwrap()
2427                     .iter()
2428                     .map(set_to_region)
2429                     .collect()
2430             } else {
2431                 let tcx = self.tcx;
2432                 self.xcrate_object_lifetime_defaults
2433                     .entry(def_id)
2434                     .or_insert_with(|| {
2435                         tcx.generics_of(def_id)
2436                             .params
2437                             .iter()
2438                             .filter_map(|param| match param.kind {
2439                                 GenericParamDefKind::Type { object_lifetime_default, .. } => {
2440                                     Some(object_lifetime_default)
2441                                 }
2442                                 GenericParamDefKind::Const { .. } => Some(Set1::Empty),
2443                                 GenericParamDefKind::Lifetime => None,
2444                             })
2445                             .collect()
2446                     })
2447                     .iter()
2448                     .map(set_to_region)
2449                     .collect()
2450             }
2451         });
2452
2453         debug!("visit_segment_args: object_lifetime_defaults={:?}", object_lifetime_defaults);
2454
2455         let mut i = 0;
2456         for arg in generic_args.args {
2457             match arg {
2458                 GenericArg::Lifetime(_) => {}
2459                 GenericArg::Type(ty) => {
2460                     if let Some(&lt) = object_lifetime_defaults.get(i) {
2461                         let scope = Scope::ObjectLifetimeDefault { lifetime: lt, s: self.scope };
2462                         self.with(scope, |_, this| this.visit_ty(ty));
2463                     } else {
2464                         self.visit_ty(ty);
2465                     }
2466                     i += 1;
2467                 }
2468                 GenericArg::Const(ct) => {
2469                     self.visit_anon_const(&ct.value);
2470                     i += 1;
2471                 }
2472                 GenericArg::Infer(inf) => {
2473                     self.visit_id(inf.hir_id);
2474                     i += 1;
2475                 }
2476             }
2477         }
2478
2479         // Hack: when resolving the type `XX` in binding like `dyn
2480         // Foo<'b, Item = XX>`, the current object-lifetime default
2481         // would be to examine the trait `Foo` to check whether it has
2482         // a lifetime bound declared on `Item`. e.g., if `Foo` is
2483         // declared like so, then the default object lifetime bound in
2484         // `XX` should be `'b`:
2485         //
2486         // ```rust
2487         // trait Foo<'a> {
2488         //   type Item: 'a;
2489         // }
2490         // ```
2491         //
2492         // but if we just have `type Item;`, then it would be
2493         // `'static`. However, we don't get all of this logic correct.
2494         //
2495         // Instead, we do something hacky: if there are no lifetime parameters
2496         // to the trait, then we simply use a default object lifetime
2497         // bound of `'static`, because there is no other possibility. On the other hand,
2498         // if there ARE lifetime parameters, then we require the user to give an
2499         // explicit bound for now.
2500         //
2501         // This is intended to leave room for us to implement the
2502         // correct behavior in the future.
2503         let has_lifetime_parameter =
2504             generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)));
2505
2506         // Resolve lifetimes found in the bindings, so either in the type `XX` in `Item = XX` or
2507         // in the trait ref `YY<...>` in `Item: YY<...>`.
2508         for binding in generic_args.bindings {
2509             let scope = Scope::ObjectLifetimeDefault {
2510                 lifetime: if has_lifetime_parameter { None } else { Some(Region::Static) },
2511                 s: self.scope,
2512             };
2513             if let Some(type_def_id) = type_def_id {
2514                 let lifetimes = LifetimeContext::supertrait_hrtb_lifetimes(
2515                     self.tcx,
2516                     type_def_id,
2517                     binding.ident,
2518                 );
2519                 self.with(scope, |_, this| {
2520                     let scope = Scope::Supertrait {
2521                         lifetimes: lifetimes.unwrap_or_default(),
2522                         s: this.scope,
2523                     };
2524                     this.with(scope, |_, this| this.visit_assoc_type_binding(binding));
2525                 });
2526             } else {
2527                 self.with(scope, |_, this| this.visit_assoc_type_binding(binding));
2528             }
2529         }
2530     }
2531
2532     /// Returns all the late-bound vars that come into scope from supertrait HRTBs, based on the
2533     /// associated type name and starting trait.
2534     /// For example, imagine we have
2535     /// ```rust
2536     /// trait Foo<'a, 'b> {
2537     ///   type As;
2538     /// }
2539     /// trait Bar<'b>: for<'a> Foo<'a, 'b> {}
2540     /// trait Bar: for<'b> Bar<'b> {}
2541     /// ```
2542     /// In this case, if we wanted to the supertrait HRTB lifetimes for `As` on
2543     /// the starting trait `Bar`, we would return `Some(['b, 'a])`.
2544     fn supertrait_hrtb_lifetimes(
2545         tcx: TyCtxt<'tcx>,
2546         def_id: DefId,
2547         assoc_name: Ident,
2548     ) -> Option<Vec<ty::BoundVariableKind>> {
2549         let trait_defines_associated_type_named = |trait_def_id: DefId| {
2550             tcx.associated_items(trait_def_id)
2551                 .find_by_name_and_kind(tcx, assoc_name, ty::AssocKind::Type, trait_def_id)
2552                 .is_some()
2553         };
2554
2555         use smallvec::{smallvec, SmallVec};
2556         let mut stack: SmallVec<[(DefId, SmallVec<[ty::BoundVariableKind; 8]>); 8]> =
2557             smallvec![(def_id, smallvec![])];
2558         let mut visited: FxHashSet<DefId> = FxHashSet::default();
2559         loop {
2560             let Some((def_id, bound_vars)) = stack.pop() else {
2561                 break None;
2562             };
2563             // See issue #83753. If someone writes an associated type on a non-trait, just treat it as
2564             // there being no supertrait HRTBs.
2565             match tcx.def_kind(def_id) {
2566                 DefKind::Trait | DefKind::TraitAlias | DefKind::Impl => {}
2567                 _ => break None,
2568             }
2569
2570             if trait_defines_associated_type_named(def_id) {
2571                 break Some(bound_vars.into_iter().collect());
2572             }
2573             let predicates =
2574                 tcx.super_predicates_that_define_assoc_type((def_id, Some(assoc_name)));
2575             let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| {
2576                 let bound_predicate = pred.kind();
2577                 match bound_predicate.skip_binder() {
2578                     ty::PredicateKind::Trait(data) => {
2579                         // The order here needs to match what we would get from `subst_supertrait`
2580                         let pred_bound_vars = bound_predicate.bound_vars();
2581                         let mut all_bound_vars = bound_vars.clone();
2582                         all_bound_vars.extend(pred_bound_vars.iter());
2583                         let super_def_id = data.trait_ref.def_id;
2584                         Some((super_def_id, all_bound_vars))
2585                     }
2586                     _ => None,
2587                 }
2588             });
2589
2590             let obligations = obligations.filter(|o| visited.insert(o.0));
2591             stack.extend(obligations);
2592         }
2593     }
2594
2595     #[tracing::instrument(level = "debug", skip(self))]
2596     fn visit_fn_like_elision(
2597         &mut self,
2598         inputs: &'tcx [hir::Ty<'tcx>],
2599         output: Option<&'tcx hir::Ty<'tcx>>,
2600     ) {
2601         debug!("visit_fn_like_elision: enter");
2602         let mut scope = &*self.scope;
2603         let hir_id = loop {
2604             match scope {
2605                 Scope::Binder { hir_id, .. } => {
2606                     break *hir_id;
2607                 }
2608                 Scope::ObjectLifetimeDefault { ref s, .. }
2609                 | Scope::Elision { ref s, .. }
2610                 | Scope::Supertrait { ref s, .. }
2611                 | Scope::TraitRefBoundary { ref s, .. } => {
2612                     scope = *s;
2613                 }
2614                 Scope::Root | Scope::Body { .. } => {
2615                     // See issues #83907 and #83693. Just bail out from looking inside.
2616                     self.tcx.sess.delay_span_bug(
2617                         rustc_span::DUMMY_SP,
2618                         "In fn_like_elision without appropriate scope above",
2619                     );
2620                     return;
2621                 }
2622             }
2623         };
2624         // While not strictly necessary, we gather anon lifetimes *before* actually
2625         // visiting the argument types.
2626         let mut gather = GatherAnonLifetimes { anon_count: 0 };
2627         for input in inputs {
2628             gather.visit_ty(input);
2629         }
2630         trace!(?gather.anon_count);
2631         let late_bound_vars = self.map.late_bound_vars.entry(hir_id).or_default();
2632         let named_late_bound_vars = late_bound_vars.len() as u32;
2633         late_bound_vars.extend(
2634             (0..gather.anon_count).map(|var| ty::BoundVariableKind::Region(ty::BrAnon(var))),
2635         );
2636         let arg_scope = Scope::Elision {
2637             elide: Elide::FreshLateAnon(named_late_bound_vars, Cell::new(0)),
2638             s: self.scope,
2639         };
2640         self.with(arg_scope, |_, this| {
2641             for input in inputs {
2642                 this.visit_ty(input);
2643             }
2644         });
2645
2646         let Some(output) = output else { return };
2647
2648         debug!("determine output");
2649
2650         // Figure out if there's a body we can get argument names from,
2651         // and whether there's a `self` argument (treated specially).
2652         let mut assoc_item_kind = None;
2653         let mut impl_self = None;
2654         let parent = self.tcx.hir().get_parent_node(output.hir_id);
2655         let body = match self.tcx.hir().get(parent) {
2656             // `fn` definitions and methods.
2657             Node::Item(&hir::Item { kind: hir::ItemKind::Fn(.., body), .. }) => Some(body),
2658
2659             Node::TraitItem(&hir::TraitItem { kind: hir::TraitItemKind::Fn(_, ref m), .. }) => {
2660                 if let hir::ItemKind::Trait(.., ref trait_items) =
2661                     self.tcx.hir().expect_item(self.tcx.hir().get_parent_item(parent)).kind
2662                 {
2663                     assoc_item_kind =
2664                         trait_items.iter().find(|ti| ti.id.hir_id() == parent).map(|ti| ti.kind);
2665                 }
2666                 match *m {
2667                     hir::TraitFn::Required(_) => None,
2668                     hir::TraitFn::Provided(body) => Some(body),
2669                 }
2670             }
2671
2672             Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body), .. }) => {
2673                 if let hir::ItemKind::Impl(hir::Impl { ref self_ty, ref items, .. }) =
2674                     self.tcx.hir().expect_item(self.tcx.hir().get_parent_item(parent)).kind
2675                 {
2676                     impl_self = Some(self_ty);
2677                     assoc_item_kind =
2678                         items.iter().find(|ii| ii.id.hir_id() == parent).map(|ii| ii.kind);
2679                 }
2680                 Some(body)
2681             }
2682
2683             // Foreign functions, `fn(...) -> R` and `Trait(...) -> R` (both types and bounds).
2684             Node::ForeignItem(_) | Node::Ty(_) | Node::TraitRef(_) => None,
2685             // Everything else (only closures?) doesn't
2686             // actually enjoy elision in return types.
2687             _ => {
2688                 self.visit_ty(output);
2689                 return;
2690             }
2691         };
2692
2693         let has_self = match assoc_item_kind {
2694             Some(hir::AssocItemKind::Fn { has_self }) => has_self,
2695             _ => false,
2696         };
2697
2698         // In accordance with the rules for lifetime elision, we can determine
2699         // what region to use for elision in the output type in two ways.
2700         // First (determined here), if `self` is by-reference, then the
2701         // implied output region is the region of the self parameter.
2702         if has_self {
2703             struct SelfVisitor<'a> {
2704                 map: &'a NamedRegionMap,
2705                 impl_self: Option<&'a hir::TyKind<'a>>,
2706                 lifetime: Set1<Region>,
2707             }
2708
2709             impl SelfVisitor<'_> {
2710                 // Look for `self: &'a Self` - also desugared from `&'a self`,
2711                 // and if that matches, use it for elision and return early.
2712                 fn is_self_ty(&self, res: Res) -> bool {
2713                     if let Res::SelfTy { .. } = res {
2714                         return true;
2715                     }
2716
2717                     // Can't always rely on literal (or implied) `Self` due
2718                     // to the way elision rules were originally specified.
2719                     if let Some(&hir::TyKind::Path(hir::QPath::Resolved(None, ref path))) =
2720                         self.impl_self
2721                     {
2722                         match path.res {
2723                             // Permit the types that unambiguously always
2724                             // result in the same type constructor being used
2725                             // (it can't differ between `Self` and `self`).
2726                             Res::Def(DefKind::Struct | DefKind::Union | DefKind::Enum, _)
2727                             | Res::PrimTy(_) => return res == path.res,
2728                             _ => {}
2729                         }
2730                     }
2731
2732                     false
2733                 }
2734             }
2735
2736             impl<'a> Visitor<'a> for SelfVisitor<'a> {
2737                 fn visit_ty(&mut self, ty: &'a hir::Ty<'a>) {
2738                     if let hir::TyKind::Rptr(lifetime_ref, ref mt) = ty.kind {
2739                         if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = mt.ty.kind
2740                         {
2741                             if self.is_self_ty(path.res) {
2742                                 if let Some(lifetime) = self.map.defs.get(&lifetime_ref.hir_id) {
2743                                     self.lifetime.insert(*lifetime);
2744                                 }
2745                             }
2746                         }
2747                     }
2748                     intravisit::walk_ty(self, ty)
2749                 }
2750             }
2751
2752             let mut visitor = SelfVisitor {
2753                 map: self.map,
2754                 impl_self: impl_self.map(|ty| &ty.kind),
2755                 lifetime: Set1::Empty,
2756             };
2757             visitor.visit_ty(&inputs[0]);
2758             if let Set1::One(lifetime) = visitor.lifetime {
2759                 let scope = Scope::Elision { elide: Elide::Exact(lifetime), s: self.scope };
2760                 self.with(scope, |_, this| this.visit_ty(output));
2761                 return;
2762             }
2763         }
2764
2765         // Second, if there was exactly one lifetime (either a substitution or a
2766         // reference) in the arguments, then any anonymous regions in the output
2767         // have that lifetime.
2768         let mut possible_implied_output_region = None;
2769         let mut lifetime_count = 0;
2770         let arg_lifetimes = inputs
2771             .iter()
2772             .enumerate()
2773             .skip(has_self as usize)
2774             .map(|(i, input)| {
2775                 let mut gather = GatherLifetimes {
2776                     map: self.map,
2777                     outer_index: ty::INNERMOST,
2778                     have_bound_regions: false,
2779                     lifetimes: Default::default(),
2780                 };
2781                 gather.visit_ty(input);
2782
2783                 lifetime_count += gather.lifetimes.len();
2784
2785                 if lifetime_count == 1 && gather.lifetimes.len() == 1 {
2786                     // there's a chance that the unique lifetime of this
2787                     // iteration will be the appropriate lifetime for output
2788                     // parameters, so lets store it.
2789                     possible_implied_output_region = gather.lifetimes.iter().cloned().next();
2790                 }
2791
2792                 ElisionFailureInfo {
2793                     parent: body,
2794                     index: i,
2795                     lifetime_count: gather.lifetimes.len(),
2796                     have_bound_regions: gather.have_bound_regions,
2797                     span: input.span,
2798                 }
2799             })
2800             .collect();
2801
2802         let elide = if lifetime_count == 1 {
2803             Elide::Exact(possible_implied_output_region.unwrap())
2804         } else {
2805             Elide::Error(arg_lifetimes)
2806         };
2807
2808         debug!(?elide);
2809
2810         let scope = Scope::Elision { elide, s: self.scope };
2811         self.with(scope, |_, this| this.visit_ty(output));
2812
2813         struct GatherLifetimes<'a> {
2814             map: &'a NamedRegionMap,
2815             outer_index: ty::DebruijnIndex,
2816             have_bound_regions: bool,
2817             lifetimes: FxHashSet<Region>,
2818         }
2819
2820         impl<'v, 'a> Visitor<'v> for GatherLifetimes<'a> {
2821             fn visit_ty(&mut self, ty: &hir::Ty<'_>) {
2822                 if let hir::TyKind::BareFn(_) = ty.kind {
2823                     self.outer_index.shift_in(1);
2824                 }
2825                 match ty.kind {
2826                     hir::TyKind::TraitObject(bounds, ref lifetime, _) => {
2827                         for bound in bounds {
2828                             self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None);
2829                         }
2830
2831                         // Stay on the safe side and don't include the object
2832                         // lifetime default (which may not end up being used).
2833                         if !lifetime.is_elided() {
2834                             self.visit_lifetime(lifetime);
2835                         }
2836                     }
2837                     _ => {
2838                         intravisit::walk_ty(self, ty);
2839                     }
2840                 }
2841                 if let hir::TyKind::BareFn(_) = ty.kind {
2842                     self.outer_index.shift_out(1);
2843                 }
2844             }
2845
2846             fn visit_generic_param(&mut self, param: &hir::GenericParam<'_>) {
2847                 if let hir::GenericParamKind::Lifetime { .. } = param.kind {
2848                     // FIXME(eddyb) Do we want this? It only makes a difference
2849                     // if this `for<'a>` lifetime parameter is never used.
2850                     self.have_bound_regions = true;
2851                 }
2852
2853                 intravisit::walk_generic_param(self, param);
2854             }
2855
2856             fn visit_poly_trait_ref(
2857                 &mut self,
2858                 trait_ref: &hir::PolyTraitRef<'_>,
2859                 modifier: hir::TraitBoundModifier,
2860             ) {
2861                 self.outer_index.shift_in(1);
2862                 intravisit::walk_poly_trait_ref(self, trait_ref, modifier);
2863                 self.outer_index.shift_out(1);
2864             }
2865
2866             fn visit_param_bound(&mut self, bound: &hir::GenericBound<'_>) {
2867                 if let hir::GenericBound::LangItemTrait { .. } = bound {
2868                     self.outer_index.shift_in(1);
2869                     intravisit::walk_param_bound(self, bound);
2870                     self.outer_index.shift_out(1);
2871                 } else {
2872                     intravisit::walk_param_bound(self, bound);
2873                 }
2874             }
2875
2876             fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) {
2877                 if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.hir_id) {
2878                     match lifetime {
2879                         Region::LateBound(debruijn, _, _)
2880                         | Region::LateBoundAnon(debruijn, _, _)
2881                             if debruijn < self.outer_index =>
2882                         {
2883                             self.have_bound_regions = true;
2884                         }
2885                         _ => {
2886                             // FIXME(jackh726): nested trait refs?
2887                             self.lifetimes.insert(lifetime.shifted_out_to_binder(self.outer_index));
2888                         }
2889                     }
2890                 }
2891             }
2892         }
2893
2894         struct GatherAnonLifetimes {
2895             anon_count: u32,
2896         }
2897         impl<'v> Visitor<'v> for GatherAnonLifetimes {
2898             #[instrument(skip(self), level = "trace")]
2899             fn visit_ty(&mut self, ty: &hir::Ty<'_>) {
2900                 // If we enter a `BareFn`, then we enter a *new* binding scope
2901                 if let hir::TyKind::BareFn(_) = ty.kind {
2902                     return;
2903                 }
2904                 intravisit::walk_ty(self, ty);
2905             }
2906
2907             fn visit_generic_args(
2908                 &mut self,
2909                 path_span: Span,
2910                 generic_args: &'v hir::GenericArgs<'v>,
2911             ) {
2912                 // parenthesized args enter a new elison scope
2913                 if generic_args.parenthesized {
2914                     return;
2915                 }
2916                 intravisit::walk_generic_args(self, path_span, generic_args)
2917             }
2918
2919             #[instrument(skip(self), level = "trace")]
2920             fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) {
2921                 if lifetime_ref.is_elided() {
2922                     self.anon_count += 1;
2923                 }
2924             }
2925         }
2926     }
2927
2928     fn resolve_elided_lifetimes(&mut self, lifetime_refs: &[&'tcx hir::Lifetime]) {
2929         debug!("resolve_elided_lifetimes(lifetime_refs={:?})", lifetime_refs);
2930
2931         if lifetime_refs.is_empty() {
2932             return;
2933         }
2934
2935         let mut late_depth = 0;
2936         let mut scope = self.scope;
2937         let mut lifetime_names = FxHashSet::default();
2938         let mut lifetime_spans = vec![];
2939         let error = loop {
2940             match *scope {
2941                 // Do not assign any resolution, it will be inferred.
2942                 Scope::Body { .. } => break Ok(()),
2943
2944                 Scope::Root => break Err(None),
2945
2946                 Scope::Binder { s, ref lifetimes, scope_type, .. } => {
2947                     // collect named lifetimes for suggestions
2948                     for name in lifetimes.keys() {
2949                         if let hir::ParamName::Plain(name) = name {
2950                             lifetime_names.insert(name.name);
2951                             lifetime_spans.push(name.span);
2952                         }
2953                     }
2954                     match scope_type {
2955                         BinderScopeType::Normal => late_depth += 1,
2956                         BinderScopeType::Concatenating => {}
2957                     }
2958                     scope = s;
2959                 }
2960
2961                 Scope::Elision {
2962                     elide: Elide::FreshLateAnon(named_late_bound_vars, ref counter),
2963                     ..
2964                 } => {
2965                     for lifetime_ref in lifetime_refs {
2966                         let lifetime =
2967                             Region::late_anon(named_late_bound_vars, counter).shifted(late_depth);
2968
2969                         self.insert_lifetime(lifetime_ref, lifetime);
2970                     }
2971                     break Ok(());
2972                 }
2973
2974                 Scope::Elision { elide: Elide::Exact(l), .. } => {
2975                     let lifetime = l.shifted(late_depth);
2976                     for lifetime_ref in lifetime_refs {
2977                         self.insert_lifetime(lifetime_ref, lifetime);
2978                     }
2979                     break Ok(());
2980                 }
2981
2982                 Scope::Elision { elide: Elide::Error(ref e), ref s, .. } => {
2983                     let mut scope = s;
2984                     loop {
2985                         match scope {
2986                             Scope::Binder { ref lifetimes, s, .. } => {
2987                                 // Collect named lifetimes for suggestions.
2988                                 for name in lifetimes.keys() {
2989                                     if let hir::ParamName::Plain(name) = name {
2990                                         lifetime_names.insert(name.name);
2991                                         lifetime_spans.push(name.span);
2992                                     }
2993                                 }
2994                                 scope = s;
2995                             }
2996                             Scope::ObjectLifetimeDefault { ref s, .. }
2997                             | Scope::Elision { ref s, .. }
2998                             | Scope::TraitRefBoundary { ref s, .. } => {
2999                                 scope = s;
3000                             }
3001                             _ => break,
3002                         }
3003                     }
3004                     break Err(Some(&e[..]));
3005                 }
3006
3007                 Scope::Elision { elide: Elide::Forbid, .. } => break Err(None),
3008
3009                 Scope::ObjectLifetimeDefault { s, .. }
3010                 | Scope::Supertrait { s, .. }
3011                 | Scope::TraitRefBoundary { s, .. } => {
3012                     scope = s;
3013                 }
3014             }
3015         };
3016
3017         let error = match error {
3018             Ok(()) => {
3019                 self.report_elided_lifetime_in_ty(lifetime_refs);
3020                 return;
3021             }
3022             Err(error) => error,
3023         };
3024
3025         // If we specifically need the `scope_for_path` map, then we're in the
3026         // diagnostic pass and we don't want to emit more errors.
3027         if self.map.scope_for_path.is_some() {
3028             self.tcx.sess.delay_span_bug(
3029                 rustc_span::DUMMY_SP,
3030                 "Encountered unexpected errors during diagnostics related part",
3031             );
3032             return;
3033         }
3034
3035         let mut spans: Vec<_> = lifetime_refs.iter().map(|lt| lt.span).collect();
3036         spans.sort();
3037         let mut spans_dedup = spans.clone();
3038         spans_dedup.dedup();
3039         let spans_with_counts: Vec<_> = spans_dedup
3040             .into_iter()
3041             .map(|sp| (sp, spans.iter().filter(|nsp| *nsp == &sp).count()))
3042             .collect();
3043
3044         let mut err = self.report_missing_lifetime_specifiers(spans.clone(), lifetime_refs.len());
3045
3046         if let Some(params) = error {
3047             // If there's no lifetime available, suggest `'static`.
3048             if self.report_elision_failure(&mut err, params) && lifetime_names.is_empty() {
3049                 lifetime_names.insert(kw::StaticLifetime);
3050             }
3051         }
3052
3053         self.add_missing_lifetime_specifiers_label(
3054             &mut err,
3055             spans_with_counts,
3056             &lifetime_names,
3057             lifetime_spans,
3058             error.unwrap_or(&[]),
3059         );
3060         err.emit();
3061     }
3062
3063     fn resolve_object_lifetime_default(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
3064         debug!("resolve_object_lifetime_default(lifetime_ref={:?})", lifetime_ref);
3065         let mut late_depth = 0;
3066         let mut scope = self.scope;
3067         let lifetime = loop {
3068             match *scope {
3069                 Scope::Binder { s, scope_type, .. } => {
3070                     match scope_type {
3071                         BinderScopeType::Normal => late_depth += 1,
3072                         BinderScopeType::Concatenating => {}
3073                     }
3074                     scope = s;
3075                 }
3076
3077                 Scope::Root | Scope::Elision { .. } => break Region::Static,
3078
3079                 Scope::Body { .. } | Scope::ObjectLifetimeDefault { lifetime: None, .. } => return,
3080
3081                 Scope::ObjectLifetimeDefault { lifetime: Some(l), .. } => break l,
3082
3083                 Scope::Supertrait { s, .. } | Scope::TraitRefBoundary { s, .. } => {
3084                     scope = s;
3085                 }
3086             }
3087         };
3088         self.insert_lifetime(lifetime_ref, lifetime.shifted(late_depth));
3089     }
3090
3091     fn check_lifetime_params(
3092         &mut self,
3093         old_scope: ScopeRef<'_>,
3094         params: &'tcx [hir::GenericParam<'tcx>],
3095     ) {
3096         let lifetimes: Vec<_> = params
3097             .iter()
3098             .filter_map(|param| match param.kind {
3099                 GenericParamKind::Lifetime { .. } => {
3100                     Some((param, param.name.normalize_to_macros_2_0()))
3101                 }
3102                 _ => None,
3103             })
3104             .collect();
3105         for (i, (lifetime_i, lifetime_i_name)) in lifetimes.iter().enumerate() {
3106             if let hir::ParamName::Plain(_) = lifetime_i_name {
3107                 let name = lifetime_i_name.ident().name;
3108                 if name == kw::UnderscoreLifetime || name == kw::StaticLifetime {
3109                     let mut err = struct_span_err!(
3110                         self.tcx.sess,
3111                         lifetime_i.span,
3112                         E0262,
3113                         "invalid lifetime parameter name: `{}`",
3114                         lifetime_i.name.ident(),
3115                     );
3116                     err.span_label(
3117                         lifetime_i.span,
3118                         format!("{} is a reserved lifetime name", name),
3119                     );
3120                     err.emit();
3121                 }
3122             }
3123
3124             // It is a hard error to shadow a lifetime within the same scope.
3125             for (lifetime_j, lifetime_j_name) in lifetimes.iter().skip(i + 1) {
3126                 if lifetime_i_name == lifetime_j_name {
3127                     struct_span_err!(
3128                         self.tcx.sess,
3129                         lifetime_j.span,
3130                         E0263,
3131                         "lifetime name `{}` declared twice in the same scope",
3132                         lifetime_j.name.ident()
3133                     )
3134                     .span_label(lifetime_j.span, "declared twice")
3135                     .span_label(lifetime_i.span, "previous declaration here")
3136                     .emit();
3137                 }
3138             }
3139
3140             // It is a soft error to shadow a lifetime within a parent scope.
3141             self.check_lifetime_param_for_shadowing(old_scope, &lifetime_i);
3142
3143             for bound in lifetime_i.bounds {
3144                 match bound {
3145                     hir::GenericBound::Outlives(ref lt) => match lt.name {
3146                         hir::LifetimeName::Underscore => self.tcx.sess.delay_span_bug(
3147                             lt.span,
3148                             "use of `'_` in illegal place, but not caught by lowering",
3149                         ),
3150                         hir::LifetimeName::Static => {
3151                             self.insert_lifetime(lt, Region::Static);
3152                             self.tcx
3153                                 .sess
3154                                 .struct_span_warn(
3155                                     lifetime_i.span.to(lt.span),
3156                                     &format!(
3157                                         "unnecessary lifetime parameter `{}`",
3158                                         lifetime_i.name.ident(),
3159                                     ),
3160                                 )
3161                                 .help(&format!(
3162                                     "you can use the `'static` lifetime directly, in place of `{}`",
3163                                     lifetime_i.name.ident(),
3164                                 ))
3165                                 .emit();
3166                         }
3167                         hir::LifetimeName::Param(_) | hir::LifetimeName::Implicit(_) => {
3168                             self.resolve_lifetime_ref(lt);
3169                         }
3170                         hir::LifetimeName::ImplicitObjectLifetimeDefault => {
3171                             self.tcx.sess.delay_span_bug(
3172                                 lt.span,
3173                                 "lowering generated `ImplicitObjectLifetimeDefault` \
3174                                  outside of an object type",
3175                             )
3176                         }
3177                         hir::LifetimeName::Error => {
3178                             // No need to do anything, error already reported.
3179                         }
3180                     },
3181                     _ => bug!(),
3182                 }
3183             }
3184         }
3185     }
3186
3187     fn check_lifetime_param_for_shadowing(
3188         &self,
3189         mut old_scope: ScopeRef<'_>,
3190         param: &'tcx hir::GenericParam<'tcx>,
3191     ) {
3192         for label in &self.labels_in_fn {
3193             // FIXME (#24278): non-hygienic comparison
3194             if param.name.ident().name == label.name {
3195                 signal_shadowing_problem(
3196                     self.tcx,
3197                     label.name,
3198                     original_label(label.span),
3199                     shadower_lifetime(&param),
3200                 );
3201                 return;
3202             }
3203         }
3204
3205         loop {
3206             match *old_scope {
3207                 Scope::Body { s, .. }
3208                 | Scope::Elision { s, .. }
3209                 | Scope::ObjectLifetimeDefault { s, .. }
3210                 | Scope::Supertrait { s, .. }
3211                 | Scope::TraitRefBoundary { s, .. } => {
3212                     old_scope = s;
3213                 }
3214
3215                 Scope::Root => {
3216                     return;
3217                 }
3218
3219                 Scope::Binder { ref lifetimes, s, .. } => {
3220                     if let Some(&def) = lifetimes.get(&param.name.normalize_to_macros_2_0()) {
3221                         signal_shadowing_problem(
3222                             self.tcx,
3223                             param.name.ident().name,
3224                             original_lifetime(self.tcx.def_span(def.id().unwrap())),
3225                             shadower_lifetime(&param),
3226                         );
3227                         return;
3228                     }
3229
3230                     old_scope = s;
3231                 }
3232             }
3233         }
3234     }
3235
3236     /// Returns `true` if, in the current scope, replacing `'_` would be
3237     /// equivalent to a single-use lifetime.
3238     fn track_lifetime_uses(&self) -> bool {
3239         let mut scope = self.scope;
3240         loop {
3241             match *scope {
3242                 Scope::Root => break false,
3243
3244                 // Inside of items, it depends on the kind of item.
3245                 Scope::Binder { track_lifetime_uses, .. } => break track_lifetime_uses,
3246
3247                 // Inside a body, `'_` will use an inference variable,
3248                 // should be fine.
3249                 Scope::Body { .. } => break true,
3250
3251                 // A lifetime only used in a fn argument could as well
3252                 // be replaced with `'_`, as that would generate a
3253                 // fresh name, too.
3254                 Scope::Elision { elide: Elide::FreshLateAnon(..), .. } => break true,
3255
3256                 // In the return type or other such place, `'_` is not
3257                 // going to make a fresh name, so we cannot
3258                 // necessarily replace a single-use lifetime with
3259                 // `'_`.
3260                 Scope::Elision {
3261                     elide: Elide::Exact(_) | Elide::Error(_) | Elide::Forbid, ..
3262                 } => break false,
3263
3264                 Scope::ObjectLifetimeDefault { s, .. }
3265                 | Scope::Supertrait { s, .. }
3266                 | Scope::TraitRefBoundary { s, .. } => scope = s,
3267             }
3268         }
3269     }
3270
3271     #[tracing::instrument(level = "debug", skip(self))]
3272     fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
3273         debug!(
3274             node = ?self.tcx.hir().node_to_string(lifetime_ref.hir_id),
3275             span = ?self.tcx.sess.source_map().span_to_diagnostic_string(lifetime_ref.span)
3276         );
3277         self.map.defs.insert(lifetime_ref.hir_id, def);
3278
3279         match def {
3280             Region::LateBoundAnon(..) | Region::Static => {
3281                 // These are anonymous lifetimes or lifetimes that are not declared.
3282             }
3283
3284             Region::Free(_, def_id)
3285             | Region::LateBound(_, _, def_id)
3286             | Region::EarlyBound(_, def_id) => {
3287                 // A lifetime declared by the user.
3288                 let track_lifetime_uses = self.track_lifetime_uses();
3289                 debug!(?track_lifetime_uses);
3290                 if track_lifetime_uses && !self.lifetime_uses.contains_key(&def_id) {
3291                     debug!("first use of {:?}", def_id);
3292                     self.lifetime_uses.insert(def_id, LifetimeUseSet::One(lifetime_ref));
3293                 } else {
3294                     debug!("many uses of {:?}", def_id);
3295                     self.lifetime_uses.insert(def_id, LifetimeUseSet::Many);
3296                 }
3297             }
3298         }
3299     }
3300
3301     /// Sometimes we resolve a lifetime, but later find that it is an
3302     /// error (esp. around impl trait). In that case, we remove the
3303     /// entry into `map.defs` so as not to confuse later code.
3304     fn uninsert_lifetime_on_error(&mut self, lifetime_ref: &'tcx hir::Lifetime, bad_def: Region) {
3305         let old_value = self.map.defs.remove(&lifetime_ref.hir_id);
3306         assert_eq!(old_value, Some(bad_def));
3307     }
3308 }
3309
3310 /// Detects late-bound lifetimes and inserts them into
3311 /// `map.late_bound`.
3312 ///
3313 /// A region declared on a fn is **late-bound** if:
3314 /// - it is constrained by an argument type;
3315 /// - it does not appear in a where-clause.
3316 ///
3317 /// "Constrained" basically means that it appears in any type but
3318 /// not amongst the inputs to a projection. In other words, `<&'a
3319 /// T as Trait<''b>>::Foo` does not constrain `'a` or `'b`.
3320 #[tracing::instrument(level = "debug", skip(map))]
3321 fn insert_late_bound_lifetimes(
3322     map: &mut NamedRegionMap,
3323     decl: &hir::FnDecl<'_>,
3324     generics: &hir::Generics<'_>,
3325 ) {
3326     let mut constrained_by_input = ConstrainedCollector::default();
3327     for arg_ty in decl.inputs {
3328         constrained_by_input.visit_ty(arg_ty);
3329     }
3330
3331     let mut appears_in_output = AllCollector::default();
3332     intravisit::walk_fn_ret_ty(&mut appears_in_output, &decl.output);
3333
3334     debug!(?constrained_by_input.regions);
3335
3336     // Walk the lifetimes that appear in where clauses.
3337     //
3338     // Subtle point: because we disallow nested bindings, we can just
3339     // ignore binders here and scrape up all names we see.
3340     let mut appears_in_where_clause = AllCollector::default();
3341     appears_in_where_clause.visit_generics(generics);
3342
3343     for param in generics.params {
3344         if let hir::GenericParamKind::Lifetime { .. } = param.kind {
3345             if !param.bounds.is_empty() {
3346                 // `'a: 'b` means both `'a` and `'b` are referenced
3347                 appears_in_where_clause
3348                     .regions
3349                     .insert(hir::LifetimeName::Param(param.name.normalize_to_macros_2_0()));
3350             }
3351         }
3352     }
3353
3354     debug!(?appears_in_where_clause.regions);
3355
3356     // Late bound regions are those that:
3357     // - appear in the inputs
3358     // - do not appear in the where-clauses
3359     // - are not implicitly captured by `impl Trait`
3360     for param in generics.params {
3361         match param.kind {
3362             hir::GenericParamKind::Lifetime { .. } => { /* fall through */ }
3363
3364             // Neither types nor consts are late-bound.
3365             hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => continue,
3366         }
3367
3368         let lt_name = hir::LifetimeName::Param(param.name.normalize_to_macros_2_0());
3369         // appears in the where clauses? early-bound.
3370         if appears_in_where_clause.regions.contains(&lt_name) {
3371             continue;
3372         }
3373
3374         // does not appear in the inputs, but appears in the return type? early-bound.
3375         if !constrained_by_input.regions.contains(&lt_name)
3376             && appears_in_output.regions.contains(&lt_name)
3377         {
3378             continue;
3379         }
3380
3381         debug!("lifetime {:?} with id {:?} is late-bound", param.name.ident(), param.hir_id);
3382
3383         let inserted = map.late_bound.insert(param.hir_id);
3384         assert!(inserted, "visited lifetime {:?} twice", param.hir_id);
3385     }
3386
3387     return;
3388
3389     #[derive(Default)]
3390     struct ConstrainedCollector {
3391         regions: FxHashSet<hir::LifetimeName>,
3392     }
3393
3394     impl<'v> Visitor<'v> for ConstrainedCollector {
3395         fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
3396             match ty.kind {
3397                 hir::TyKind::Path(
3398                     hir::QPath::Resolved(Some(_), _) | hir::QPath::TypeRelative(..),
3399                 ) => {
3400                     // ignore lifetimes appearing in associated type
3401                     // projections, as they are not *constrained*
3402                     // (defined above)
3403                 }
3404
3405                 hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => {
3406                     // consider only the lifetimes on the final
3407                     // segment; I am not sure it's even currently
3408                     // valid to have them elsewhere, but even if it
3409                     // is, those would be potentially inputs to
3410                     // projections
3411                     if let Some(last_segment) = path.segments.last() {
3412                         self.visit_path_segment(path.span, last_segment);
3413                     }
3414                 }
3415
3416                 _ => {
3417                     intravisit::walk_ty(self, ty);
3418                 }
3419             }
3420         }
3421
3422         fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
3423             self.regions.insert(lifetime_ref.name.normalize_to_macros_2_0());
3424         }
3425     }
3426
3427     #[derive(Default)]
3428     struct AllCollector {
3429         regions: FxHashSet<hir::LifetimeName>,
3430     }
3431
3432     impl<'v> Visitor<'v> for AllCollector {
3433         fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
3434             self.regions.insert(lifetime_ref.name.normalize_to_macros_2_0());
3435         }
3436     }
3437 }