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