]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_resolve/src/late/lifetimes.rs
Auto merge of #98588 - b-naber:valtrees-cleanup, r=lcnr
[rust.git] / compiler / rustc_resolve / src / late / lifetimes.rs
1 //! Resolution of early vs late bound lifetimes.
2 //!
3 //! Name resolution for lifetimes is performed on the AST and embedded into HIR.  From this
4 //! information, typechecking needs to transform the lifetime parameters into bound lifetimes.
5 //! Lifetimes can be early-bound or late-bound.  Construction of typechecking terms needs to visit
6 //! the types in HIR to identify late-bound lifetimes and assign their Debruijn indices.  This file
7 //! is also responsible for assigning their semantics to implicit lifetimes in trait objects.
8
9 use rustc_ast::walk_list;
10 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
11 use rustc_errors::struct_span_err;
12 use rustc_hir as hir;
13 use rustc_hir::def::{DefKind, Res};
14 use rustc_hir::def_id::LocalDefId;
15 use rustc_hir::intravisit::{self, Visitor};
16 use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeName, Node};
17 use rustc_middle::bug;
18 use rustc_middle::hir::map::Map;
19 use rustc_middle::hir::nested_filter;
20 use rustc_middle::middle::resolve_lifetime::*;
21 use rustc_middle::ty::{self, DefIdTree, TyCtxt};
22 use rustc_span::def_id::DefId;
23 use rustc_span::symbol::{sym, Ident};
24 use rustc_span::Span;
25 use std::fmt;
26
27 trait RegionExt {
28     fn early(hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region);
29
30     fn late(index: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region);
31
32     fn id(&self) -> Option<DefId>;
33
34     fn shifted(self, amount: u32) -> Region;
35
36     fn shifted_out_to_binder(self, binder: ty::DebruijnIndex) -> Region;
37 }
38
39 impl RegionExt for Region {
40     fn early(hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region) {
41         let def_id = hir_map.local_def_id(param.hir_id);
42         debug!("Region::early: def_id={:?}", def_id);
43         (def_id, Region::EarlyBound(def_id.to_def_id()))
44     }
45
46     fn late(idx: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region) {
47         let depth = ty::INNERMOST;
48         let def_id = hir_map.local_def_id(param.hir_id);
49         debug!(
50             "Region::late: idx={:?}, param={:?} depth={:?} def_id={:?}",
51             idx, param, depth, def_id,
52         );
53         (def_id, Region::LateBound(depth, idx, def_id.to_def_id()))
54     }
55
56     fn id(&self) -> Option<DefId> {
57         match *self {
58             Region::Static => None,
59
60             Region::EarlyBound(id) | Region::LateBound(_, _, id) | Region::Free(_, id) => Some(id),
61         }
62     }
63
64     fn shifted(self, amount: u32) -> Region {
65         match self {
66             Region::LateBound(debruijn, idx, id) => {
67                 Region::LateBound(debruijn.shifted_in(amount), idx, id)
68             }
69             _ => self,
70         }
71     }
72
73     fn shifted_out_to_binder(self, binder: ty::DebruijnIndex) -> Region {
74         match self {
75             Region::LateBound(debruijn, index, id) => {
76                 Region::LateBound(debruijn.shifted_out_to_binder(binder), index, id)
77             }
78             _ => self,
79         }
80     }
81 }
82
83 /// Maps the id of each lifetime reference to the lifetime decl
84 /// that it corresponds to.
85 ///
86 /// FIXME. This struct gets converted to a `ResolveLifetimes` for
87 /// actual use. It has the same data, but indexed by `LocalDefId`.  This
88 /// is silly.
89 #[derive(Debug, Default)]
90 struct NamedRegionMap {
91     // maps from every use of a named (not anonymous) lifetime to a
92     // `Region` describing how that region is bound
93     defs: HirIdMap<Region>,
94
95     // Maps relevant hir items to the bound vars on them. These include:
96     // - function defs
97     // - function pointers
98     // - closures
99     // - trait refs
100     // - bound types (like `T` in `for<'a> T<'a>: Foo`)
101     late_bound_vars: HirIdMap<Vec<ty::BoundVariableKind>>,
102 }
103
104 pub(crate) struct LifetimeContext<'a, 'tcx> {
105     pub(crate) tcx: TyCtxt<'tcx>,
106     map: &'a mut NamedRegionMap,
107     scope: ScopeRef<'a>,
108
109     /// Indicates that we only care about the definition of a trait. This should
110     /// be false if the `Item` we are resolving lifetimes for is not a trait or
111     /// we eventually need lifetimes resolve for trait items.
112     trait_definition_only: bool,
113 }
114
115 #[derive(Debug)]
116 enum Scope<'a> {
117     /// Declares lifetimes, and each can be early-bound or late-bound.
118     /// The `DebruijnIndex` of late-bound lifetimes starts at `1` and
119     /// it should be shifted by the number of `Binder`s in between the
120     /// declaration `Binder` and the location it's referenced from.
121     Binder {
122         /// We use an IndexMap here because we want these lifetimes in order
123         /// for diagnostics.
124         lifetimes: FxIndexMap<LocalDefId, Region>,
125
126         scope_type: BinderScopeType,
127
128         /// The late bound vars for a given item are stored by `HirId` to be
129         /// queried later. However, if we enter an elision scope, we have to
130         /// later append the elided bound vars to the list and need to know what
131         /// to append to.
132         hir_id: hir::HirId,
133
134         s: ScopeRef<'a>,
135
136         /// If this binder comes from a where clause, specify how it was created.
137         /// This is used to diagnose inaccessible lifetimes in APIT:
138         /// ```ignore (illustrative)
139         /// fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
140         /// ```
141         where_bound_origin: Option<hir::PredicateOrigin>,
142     },
143
144     /// Lifetimes introduced by a fn are scoped to the call-site for that fn,
145     /// if this is a fn body, otherwise the original definitions are used.
146     /// Unspecified lifetimes are inferred, unless an elision scope is nested,
147     /// e.g., `(&T, fn(&T) -> &T);` becomes `(&'_ T, for<'a> fn(&'a T) -> &'a T)`.
148     Body {
149         id: hir::BodyId,
150         s: ScopeRef<'a>,
151     },
152
153     /// A scope which either determines unspecified lifetimes or errors
154     /// on them (e.g., due to ambiguity).
155     Elision {
156         s: ScopeRef<'a>,
157     },
158
159     /// Use a specific lifetime (if `Some`) or leave it unset (to be
160     /// inferred in a function body or potentially error outside one),
161     /// for the default choice of lifetime in a trait object type.
162     ObjectLifetimeDefault {
163         lifetime: Option<Region>,
164         s: ScopeRef<'a>,
165     },
166
167     /// When we have nested trait refs, we concatenate late bound vars for inner
168     /// trait refs from outer ones. But we also need to include any HRTB
169     /// lifetimes encountered when identifying the trait that an associated type
170     /// is declared on.
171     Supertrait {
172         lifetimes: Vec<ty::BoundVariableKind>,
173         s: ScopeRef<'a>,
174     },
175
176     TraitRefBoundary {
177         s: ScopeRef<'a>,
178     },
179
180     Root,
181 }
182
183 #[derive(Copy, Clone, Debug)]
184 enum BinderScopeType {
185     /// Any non-concatenating binder scopes.
186     Normal,
187     /// Within a syntactic trait ref, there may be multiple poly trait refs that
188     /// are nested (under the `associated_type_bounds` feature). The binders of
189     /// the inner poly trait refs are extended from the outer poly trait refs
190     /// and don't increase the late bound depth. If you had
191     /// `T: for<'a>  Foo<Bar: for<'b> Baz<'a, 'b>>`, then the `for<'b>` scope
192     /// would be `Concatenating`. This also used in trait refs in where clauses
193     /// where we have two binders `for<> T: for<> Foo` (I've intentionally left
194     /// out any lifetimes because they aren't needed to show the two scopes).
195     /// The inner `for<>` has a scope of `Concatenating`.
196     Concatenating,
197 }
198
199 // A helper struct for debugging scopes without printing parent scopes
200 struct TruncatedScopeDebug<'a>(&'a Scope<'a>);
201
202 impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
203     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204         match self.0 {
205             Scope::Binder { lifetimes, scope_type, hir_id, where_bound_origin, s: _ } => f
206                 .debug_struct("Binder")
207                 .field("lifetimes", lifetimes)
208                 .field("scope_type", scope_type)
209                 .field("hir_id", hir_id)
210                 .field("where_bound_origin", where_bound_origin)
211                 .field("s", &"..")
212                 .finish(),
213             Scope::Body { id, s: _ } => {
214                 f.debug_struct("Body").field("id", id).field("s", &"..").finish()
215             }
216             Scope::Elision { s: _ } => f.debug_struct("Elision").field("s", &"..").finish(),
217             Scope::ObjectLifetimeDefault { lifetime, s: _ } => f
218                 .debug_struct("ObjectLifetimeDefault")
219                 .field("lifetime", lifetime)
220                 .field("s", &"..")
221                 .finish(),
222             Scope::Supertrait { lifetimes, s: _ } => f
223                 .debug_struct("Supertrait")
224                 .field("lifetimes", lifetimes)
225                 .field("s", &"..")
226                 .finish(),
227             Scope::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(),
228             Scope::Root => f.debug_struct("Root").finish(),
229         }
230     }
231 }
232
233 type ScopeRef<'a> = &'a Scope<'a>;
234
235 const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root;
236
237 pub fn provide(providers: &mut ty::query::Providers) {
238     *providers = ty::query::Providers {
239         resolve_lifetimes_trait_definition,
240         resolve_lifetimes,
241
242         named_region_map: |tcx, id| resolve_lifetimes_for(tcx, id).defs.get(&id),
243         is_late_bound_map,
244         object_lifetime_default,
245         late_bound_vars_map: |tcx, id| resolve_lifetimes_for(tcx, id).late_bound_vars.get(&id),
246
247         ..*providers
248     };
249 }
250
251 /// Like `resolve_lifetimes`, but does not resolve lifetimes for trait items.
252 /// Also does not generate any diagnostics.
253 ///
254 /// This is ultimately a subset of the `resolve_lifetimes` work. It effectively
255 /// resolves lifetimes only within the trait "header" -- that is, the trait
256 /// and supertrait list. In contrast, `resolve_lifetimes` resolves all the
257 /// lifetimes within the trait and its items. There is room to refactor this,
258 /// for example to resolve lifetimes for each trait item in separate queries,
259 /// but it's convenient to do the entire trait at once because the lifetimes
260 /// from the trait definition are in scope within the trait items as well.
261 ///
262 /// The reason for this separate call is to resolve what would otherwise
263 /// be a cycle. Consider this example:
264 ///
265 /// ```ignore UNSOLVED (maybe @jackh726 knows what lifetime parameter to give Sub)
266 /// trait Base<'a> {
267 ///     type BaseItem;
268 /// }
269 /// trait Sub<'b>: for<'a> Base<'a> {
270 ///    type SubItem: Sub<BaseItem = &'b u32>;
271 /// }
272 /// ```
273 ///
274 /// When we resolve `Sub` and all its items, we also have to resolve `Sub<BaseItem = &'b u32>`.
275 /// To figure out the index of `'b`, we have to know about the supertraits
276 /// of `Sub` so that we can determine that the `for<'a>` will be in scope.
277 /// (This is because we -- currently at least -- flatten all the late-bound
278 /// lifetimes into a single binder.) This requires us to resolve the
279 /// *trait definition* of `Sub`; basically just enough lifetime information
280 /// to look at the supertraits.
281 #[instrument(level = "debug", skip(tcx))]
282 fn resolve_lifetimes_trait_definition(
283     tcx: TyCtxt<'_>,
284     local_def_id: LocalDefId,
285 ) -> ResolveLifetimes {
286     convert_named_region_map(do_resolve(tcx, local_def_id, true))
287 }
288
289 /// Computes the `ResolveLifetimes` map that contains data for an entire `Item`.
290 /// You should not read the result of this query directly, but rather use
291 /// `named_region_map`, `is_late_bound_map`, etc.
292 #[instrument(level = "debug", skip(tcx))]
293 fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> ResolveLifetimes {
294     convert_named_region_map(do_resolve(tcx, local_def_id, false))
295 }
296
297 fn do_resolve(
298     tcx: TyCtxt<'_>,
299     local_def_id: LocalDefId,
300     trait_definition_only: bool,
301 ) -> NamedRegionMap {
302     let item = tcx.hir().expect_item(local_def_id);
303     let mut named_region_map =
304         NamedRegionMap { defs: Default::default(), late_bound_vars: Default::default() };
305     let mut visitor = LifetimeContext {
306         tcx,
307         map: &mut named_region_map,
308         scope: ROOT_SCOPE,
309         trait_definition_only,
310     };
311     visitor.visit_item(item);
312
313     named_region_map
314 }
315
316 fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetimes {
317     let mut rl = ResolveLifetimes::default();
318
319     for (hir_id, v) in named_region_map.defs {
320         let map = rl.defs.entry(hir_id.owner).or_default();
321         map.insert(hir_id.local_id, v);
322     }
323     for (hir_id, v) in named_region_map.late_bound_vars {
324         let map = rl.late_bound_vars.entry(hir_id.owner).or_default();
325         map.insert(hir_id.local_id, v);
326     }
327
328     debug!(?rl.defs);
329     rl
330 }
331
332 /// Given `any` owner (structs, traits, trait methods, etc.), does lifetime resolution.
333 /// There are two important things this does.
334 /// First, we have to resolve lifetimes for
335 /// the entire *`Item`* that contains this owner, because that's the largest "scope"
336 /// where we can have relevant lifetimes.
337 /// Second, if we are asking for lifetimes in a trait *definition*, we use `resolve_lifetimes_trait_definition`
338 /// instead of `resolve_lifetimes`, which does not descend into the trait items and does not emit diagnostics.
339 /// This allows us to avoid cycles. Importantly, if we ask for lifetimes for lifetimes that have an owner
340 /// other than the trait itself (like the trait methods or associated types), then we just use the regular
341 /// `resolve_lifetimes`.
342 fn resolve_lifetimes_for<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx ResolveLifetimes {
343     let item_id = item_for(tcx, def_id);
344     if item_id == def_id {
345         let item = tcx.hir().item(hir::ItemId { def_id: item_id });
346         match item.kind {
347             hir::ItemKind::Trait(..) => tcx.resolve_lifetimes_trait_definition(item_id),
348             _ => tcx.resolve_lifetimes(item_id),
349         }
350     } else {
351         tcx.resolve_lifetimes(item_id)
352     }
353 }
354
355 /// Finds the `Item` that contains the given `LocalDefId`
356 fn item_for(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> LocalDefId {
357     match tcx.hir().find_by_def_id(local_def_id) {
358         Some(Node::Item(item)) => {
359             return item.def_id;
360         }
361         _ => {}
362     }
363     let item = {
364         let hir_id = tcx.hir().local_def_id_to_hir_id(local_def_id);
365         let mut parent_iter = tcx.hir().parent_iter(hir_id);
366         loop {
367             let node = parent_iter.next().map(|n| n.1);
368             match node {
369                 Some(hir::Node::Item(item)) => break item.def_id,
370                 Some(hir::Node::Crate(_)) | None => bug!("Called `item_for` on an Item."),
371                 _ => {}
372             }
373         }
374     };
375     item
376 }
377
378 fn late_region_as_bound_region<'tcx>(tcx: TyCtxt<'tcx>, region: &Region) -> ty::BoundVariableKind {
379     match region {
380         Region::LateBound(_, _, def_id) => {
381             let name = tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id.expect_local()));
382             ty::BoundVariableKind::Region(ty::BrNamed(*def_id, name))
383         }
384         _ => bug!("{:?} is not a late region", region),
385     }
386 }
387
388 impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
389     /// Returns the binders in scope and the type of `Binder` that should be created for a poly trait ref.
390     fn poly_trait_ref_binder_info(&mut self) -> (Vec<ty::BoundVariableKind>, BinderScopeType) {
391         let mut scope = self.scope;
392         let mut supertrait_lifetimes = vec![];
393         loop {
394             match scope {
395                 Scope::Body { .. } | Scope::Root => {
396                     break (vec![], BinderScopeType::Normal);
397                 }
398
399                 Scope::Elision { s, .. } | Scope::ObjectLifetimeDefault { s, .. } => {
400                     scope = s;
401                 }
402
403                 Scope::Supertrait { s, lifetimes } => {
404                     supertrait_lifetimes = lifetimes.clone();
405                     scope = s;
406                 }
407
408                 Scope::TraitRefBoundary { .. } => {
409                     // We should only see super trait lifetimes if there is a `Binder` above
410                     assert!(supertrait_lifetimes.is_empty());
411                     break (vec![], BinderScopeType::Normal);
412                 }
413
414                 Scope::Binder { hir_id, .. } => {
415                     // Nested poly trait refs have the binders concatenated
416                     let mut full_binders =
417                         self.map.late_bound_vars.entry(*hir_id).or_default().clone();
418                     full_binders.extend(supertrait_lifetimes.into_iter());
419                     break (full_binders, BinderScopeType::Concatenating);
420                 }
421             }
422         }
423     }
424 }
425 impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
426     type NestedFilter = nested_filter::All;
427
428     fn nested_visit_map(&mut self) -> Self::Map {
429         self.tcx.hir()
430     }
431
432     // We want to nest trait/impl items in their parent, but nothing else.
433     fn visit_nested_item(&mut self, _: hir::ItemId) {}
434
435     fn visit_trait_item_ref(&mut self, ii: &'tcx hir::TraitItemRef) {
436         if !self.trait_definition_only {
437             intravisit::walk_trait_item_ref(self, ii)
438         }
439     }
440
441     fn visit_nested_body(&mut self, body: hir::BodyId) {
442         let body = self.tcx.hir().body(body);
443         self.with(Scope::Body { id: body.id(), s: self.scope }, |this| {
444             this.visit_body(body);
445         });
446     }
447
448     fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
449         if let hir::ExprKind::Closure(hir::Closure {
450             binder, bound_generic_params, fn_decl, ..
451         }) = e.kind
452         {
453             if let &hir::ClosureBinder::For { span: for_sp, .. } = binder {
454                 fn span_of_infer(ty: &hir::Ty<'_>) -> Option<Span> {
455                     struct V(Option<Span>);
456
457                     impl<'v> Visitor<'v> for V {
458                         fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
459                             match t.kind {
460                                 _ if self.0.is_some() => (),
461                                 hir::TyKind::Infer => {
462                                     self.0 = Some(t.span);
463                                 }
464                                 _ => intravisit::walk_ty(self, t),
465                             }
466                         }
467                     }
468
469                     let mut v = V(None);
470                     v.visit_ty(ty);
471                     v.0
472                 }
473
474                 let infer_in_rt_sp = match fn_decl.output {
475                     hir::FnRetTy::DefaultReturn(sp) => Some(sp),
476                     hir::FnRetTy::Return(ty) => span_of_infer(ty),
477                 };
478
479                 let infer_spans = fn_decl
480                     .inputs
481                     .into_iter()
482                     .filter_map(span_of_infer)
483                     .chain(infer_in_rt_sp)
484                     .collect::<Vec<_>>();
485
486                 if !infer_spans.is_empty() {
487                     self.tcx.sess
488                         .struct_span_err(
489                             infer_spans,
490                             "implicit types in closure signatures are forbidden when `for<...>` is present",
491                         )
492                         .span_label(for_sp, "`for<...>` is here")
493                         .emit();
494                 }
495             }
496
497             let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) =
498                 bound_generic_params
499                     .iter()
500                     .filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
501                     .enumerate()
502                     .map(|(late_bound_idx, param)| {
503                         let pair = Region::late(late_bound_idx as u32, self.tcx.hir(), param);
504                         let r = late_region_as_bound_region(self.tcx, &pair.1);
505                         (pair, r)
506                     })
507                     .unzip();
508
509             self.map.late_bound_vars.insert(e.hir_id, binders);
510             let scope = Scope::Binder {
511                 hir_id: e.hir_id,
512                 lifetimes,
513                 s: self.scope,
514                 scope_type: BinderScopeType::Normal,
515                 where_bound_origin: None,
516             };
517
518             self.with(scope, |this| {
519                 // a closure has no bounds, so everything
520                 // contained within is scoped within its binder.
521                 intravisit::walk_expr(this, e)
522             });
523         } else {
524             intravisit::walk_expr(self, e)
525         }
526     }
527
528     #[instrument(level = "debug", skip(self))]
529     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
530         match &item.kind {
531             hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => {
532                 if let Some(of_trait) = of_trait {
533                     self.map.late_bound_vars.insert(of_trait.hir_ref_id, Vec::default());
534                 }
535             }
536             _ => {}
537         }
538         match item.kind {
539             hir::ItemKind::Fn(_, ref generics, _) => {
540                 self.visit_early_late(item.hir_id(), generics, |this| {
541                     intravisit::walk_item(this, item);
542                 });
543             }
544
545             hir::ItemKind::ExternCrate(_)
546             | hir::ItemKind::Use(..)
547             | hir::ItemKind::Macro(..)
548             | hir::ItemKind::Mod(..)
549             | hir::ItemKind::ForeignMod { .. }
550             | hir::ItemKind::GlobalAsm(..) => {
551                 // These sorts of items have no lifetime parameters at all.
552                 intravisit::walk_item(self, item);
553             }
554             hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => {
555                 // No lifetime parameters, but implied 'static.
556                 self.with(Scope::Elision { s: self.scope }, |this| {
557                     intravisit::walk_item(this, item)
558                 });
559             }
560             hir::ItemKind::OpaqueTy(hir::OpaqueTy { .. }) => {
561                 // Opaque types are visited when we visit the
562                 // `TyKind::OpaqueDef`, so that they have the lifetimes from
563                 // their parent opaque_ty in scope.
564                 //
565                 // The core idea here is that since OpaqueTys are generated with the impl Trait as
566                 // their owner, we can keep going until we find the Item that owns that. We then
567                 // conservatively add all resolved lifetimes. Otherwise we run into problems in
568                 // cases like `type Foo<'a> = impl Bar<As = impl Baz + 'a>`.
569                 for (_hir_id, node) in
570                     self.tcx.hir().parent_iter(self.tcx.hir().local_def_id_to_hir_id(item.def_id))
571                 {
572                     match node {
573                         hir::Node::Item(parent_item) => {
574                             let resolved_lifetimes: &ResolveLifetimes =
575                                 self.tcx.resolve_lifetimes(item_for(self.tcx, parent_item.def_id));
576                             // We need to add *all* deps, since opaque tys may want them from *us*
577                             for (&owner, defs) in resolved_lifetimes.defs.iter() {
578                                 defs.iter().for_each(|(&local_id, region)| {
579                                     self.map.defs.insert(hir::HirId { owner, local_id }, *region);
580                                 });
581                             }
582                             for (&owner, late_bound_vars) in
583                                 resolved_lifetimes.late_bound_vars.iter()
584                             {
585                                 late_bound_vars.iter().for_each(|(&local_id, late_bound_vars)| {
586                                     self.map.late_bound_vars.insert(
587                                         hir::HirId { owner, local_id },
588                                         late_bound_vars.clone(),
589                                     );
590                                 });
591                             }
592                             break;
593                         }
594                         hir::Node::Crate(_) => bug!("No Item about an OpaqueTy"),
595                         _ => {}
596                     }
597                 }
598             }
599             hir::ItemKind::TyAlias(_, ref generics)
600             | hir::ItemKind::Enum(_, ref generics)
601             | hir::ItemKind::Struct(_, ref generics)
602             | hir::ItemKind::Union(_, ref generics)
603             | hir::ItemKind::Trait(_, _, ref generics, ..)
604             | hir::ItemKind::TraitAlias(ref generics, ..)
605             | hir::ItemKind::Impl(hir::Impl { ref generics, .. }) => {
606                 // These kinds of items have only early-bound lifetime parameters.
607                 let lifetimes = generics
608                     .params
609                     .iter()
610                     .filter_map(|param| match param.kind {
611                         GenericParamKind::Lifetime { .. } => {
612                             Some(Region::early(self.tcx.hir(), param))
613                         }
614                         GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None,
615                     })
616                     .collect();
617                 self.map.late_bound_vars.insert(item.hir_id(), vec![]);
618                 let scope = Scope::Binder {
619                     hir_id: item.hir_id(),
620                     lifetimes,
621                     scope_type: BinderScopeType::Normal,
622                     s: ROOT_SCOPE,
623                     where_bound_origin: None,
624                 };
625                 self.with(scope, |this| {
626                     let scope = Scope::TraitRefBoundary { s: this.scope };
627                     this.with(scope, |this| {
628                         intravisit::walk_item(this, item);
629                     });
630                 });
631             }
632         }
633     }
634
635     fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
636         match item.kind {
637             hir::ForeignItemKind::Fn(_, _, ref generics) => {
638                 self.visit_early_late(item.hir_id(), generics, |this| {
639                     intravisit::walk_foreign_item(this, item);
640                 })
641             }
642             hir::ForeignItemKind::Static(..) => {
643                 intravisit::walk_foreign_item(self, item);
644             }
645             hir::ForeignItemKind::Type => {
646                 intravisit::walk_foreign_item(self, item);
647             }
648         }
649     }
650
651     #[instrument(level = "debug", skip(self))]
652     fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
653         match ty.kind {
654             hir::TyKind::BareFn(ref c) => {
655                 let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) = c
656                     .generic_params
657                     .iter()
658                     .filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
659                     .enumerate()
660                     .map(|(late_bound_idx, param)| {
661                         let pair = Region::late(late_bound_idx as u32, self.tcx.hir(), param);
662                         let r = late_region_as_bound_region(self.tcx, &pair.1);
663                         (pair, r)
664                     })
665                     .unzip();
666                 self.map.late_bound_vars.insert(ty.hir_id, binders);
667                 let scope = Scope::Binder {
668                     hir_id: ty.hir_id,
669                     lifetimes,
670                     s: self.scope,
671                     scope_type: BinderScopeType::Normal,
672                     where_bound_origin: None,
673                 };
674                 self.with(scope, |this| {
675                     // a bare fn has no bounds, so everything
676                     // contained within is scoped within its binder.
677                     intravisit::walk_ty(this, ty);
678                 });
679             }
680             hir::TyKind::TraitObject(bounds, ref lifetime, _) => {
681                 debug!(?bounds, ?lifetime, "TraitObject");
682                 let scope = Scope::TraitRefBoundary { s: self.scope };
683                 self.with(scope, |this| {
684                     for bound in bounds {
685                         this.visit_poly_trait_ref(bound);
686                     }
687                 });
688                 match lifetime.name {
689                     LifetimeName::ImplicitObjectLifetimeDefault => {
690                         // If the user does not write *anything*, we
691                         // use the object lifetime defaulting
692                         // rules. So e.g., `Box<dyn Debug>` becomes
693                         // `Box<dyn Debug + 'static>`.
694                         self.resolve_object_lifetime_default(lifetime)
695                     }
696                     LifetimeName::Infer => {
697                         // If the user writes `'_`, we use the *ordinary* elision
698                         // rules. So the `'_` in e.g., `Box<dyn Debug + '_>` will be
699                         // resolved the same as the `'_` in `&'_ Foo`.
700                         //
701                         // cc #48468
702                     }
703                     LifetimeName::Param(..) | LifetimeName::Static => {
704                         // If the user wrote an explicit name, use that.
705                         self.visit_lifetime(lifetime);
706                     }
707                     LifetimeName::Error => {}
708                 }
709             }
710             hir::TyKind::Rptr(ref lifetime_ref, ref mt) => {
711                 self.visit_lifetime(lifetime_ref);
712                 let scope = Scope::ObjectLifetimeDefault {
713                     lifetime: self.map.defs.get(&lifetime_ref.hir_id).cloned(),
714                     s: self.scope,
715                 };
716                 self.with(scope, |this| this.visit_ty(&mt.ty));
717             }
718             hir::TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => {
719                 // Resolve the lifetimes in the bounds to the lifetime defs in the generics.
720                 // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
721                 // `type MyAnonTy<'b> = impl MyTrait<'b>;`
722                 //                 ^                  ^ this gets resolved in the scope of
723                 //                                      the opaque_ty generics
724                 let opaque_ty = self.tcx.hir().item(item_id);
725                 let (generics, bounds) = match opaque_ty.kind {
726                     hir::ItemKind::OpaqueTy(hir::OpaqueTy {
727                         origin: hir::OpaqueTyOrigin::TyAlias,
728                         ..
729                     }) => {
730                         intravisit::walk_ty(self, ty);
731
732                         // Elided lifetimes are not allowed in non-return
733                         // position impl Trait
734                         let scope = Scope::TraitRefBoundary { s: self.scope };
735                         self.with(scope, |this| {
736                             let scope = Scope::Elision { s: this.scope };
737                             this.with(scope, |this| {
738                                 intravisit::walk_item(this, opaque_ty);
739                             })
740                         });
741
742                         return;
743                     }
744                     hir::ItemKind::OpaqueTy(hir::OpaqueTy {
745                         origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..),
746                         ref generics,
747                         bounds,
748                         ..
749                     }) => (generics, bounds),
750                     ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
751                 };
752
753                 // Resolve the lifetimes that are applied to the opaque type.
754                 // These are resolved in the current scope.
755                 // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
756                 // `fn foo<'a>() -> MyAnonTy<'a> { ... }`
757                 //          ^                 ^this gets resolved in the current scope
758                 for lifetime in lifetimes {
759                     let hir::GenericArg::Lifetime(lifetime) = lifetime else {
760                         continue
761                     };
762                     self.visit_lifetime(lifetime);
763
764                     // Check for predicates like `impl for<'a> Trait<impl OtherTrait<'a>>`
765                     // and ban them. Type variables instantiated inside binders aren't
766                     // well-supported at the moment, so this doesn't work.
767                     // In the future, this should be fixed and this error should be removed.
768                     let def = self.map.defs.get(&lifetime.hir_id).cloned();
769                     let Some(Region::LateBound(_, _, def_id)) = def else {
770                         continue
771                     };
772                     let Some(def_id) = def_id.as_local() else {
773                         continue
774                     };
775                     let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
776                     // Ensure that the parent of the def is an item, not HRTB
777                     let parent_id = self.tcx.hir().get_parent_node(hir_id);
778                     if !parent_id.is_owner() {
779                         if !self.trait_definition_only {
780                             struct_span_err!(
781                                 self.tcx.sess,
782                                 lifetime.span,
783                                 E0657,
784                                 "`impl Trait` can only capture lifetimes \
785                                     bound at the fn or impl level"
786                             )
787                             .emit();
788                         }
789                         self.uninsert_lifetime_on_error(lifetime, def.unwrap());
790                     }
791                     if let hir::Node::Item(hir::Item {
792                         kind: hir::ItemKind::OpaqueTy { .. }, ..
793                     }) = self.tcx.hir().get(parent_id)
794                     {
795                         if !self.trait_definition_only {
796                             let mut err = self.tcx.sess.struct_span_err(
797                                 lifetime.span,
798                                 "higher kinded lifetime bounds on nested opaque types are not supported yet",
799                             );
800                             err.span_note(self.tcx.def_span(def_id), "lifetime declared here");
801                             err.emit();
802                         }
803                         self.uninsert_lifetime_on_error(lifetime, def.unwrap());
804                     }
805                 }
806
807                 // We want to start our early-bound indices at the end of the parent scope,
808                 // not including any parent `impl Trait`s.
809                 let mut lifetimes = FxIndexMap::default();
810                 debug!(?generics.params);
811                 for param in generics.params {
812                     match param.kind {
813                         GenericParamKind::Lifetime { .. } => {
814                             let (def_id, reg) = Region::early(self.tcx.hir(), &param);
815                             lifetimes.insert(def_id, reg);
816                         }
817                         GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {}
818                     }
819                 }
820                 self.map.late_bound_vars.insert(ty.hir_id, vec![]);
821
822                 let scope = Scope::Binder {
823                     hir_id: ty.hir_id,
824                     lifetimes,
825                     s: self.scope,
826                     scope_type: BinderScopeType::Normal,
827                     where_bound_origin: None,
828                 };
829                 self.with(scope, |this| {
830                     let scope = Scope::TraitRefBoundary { s: this.scope };
831                     this.with(scope, |this| {
832                         this.visit_generics(generics);
833                         for bound in bounds {
834                             this.visit_param_bound(bound);
835                         }
836                     })
837                 });
838             }
839             _ => intravisit::walk_ty(self, ty),
840         }
841     }
842
843     #[instrument(level = "debug", skip(self))]
844     fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
845         use self::hir::TraitItemKind::*;
846         match trait_item.kind {
847             Fn(_, _) => {
848                 self.visit_early_late(trait_item.hir_id(), &trait_item.generics, |this| {
849                     intravisit::walk_trait_item(this, trait_item)
850                 });
851             }
852             Type(bounds, ref ty) => {
853                 let generics = &trait_item.generics;
854                 let lifetimes = generics
855                     .params
856                     .iter()
857                     .filter_map(|param| match param.kind {
858                         GenericParamKind::Lifetime { .. } => {
859                             Some(Region::early(self.tcx.hir(), param))
860                         }
861                         GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None,
862                     })
863                     .collect();
864                 self.map.late_bound_vars.insert(trait_item.hir_id(), vec![]);
865                 let scope = Scope::Binder {
866                     hir_id: trait_item.hir_id(),
867                     lifetimes,
868                     s: self.scope,
869                     scope_type: BinderScopeType::Normal,
870                     where_bound_origin: None,
871                 };
872                 self.with(scope, |this| {
873                     let scope = Scope::TraitRefBoundary { s: this.scope };
874                     this.with(scope, |this| {
875                         this.visit_generics(generics);
876                         for bound in bounds {
877                             this.visit_param_bound(bound);
878                         }
879                         if let Some(ty) = ty {
880                             this.visit_ty(ty);
881                         }
882                     })
883                 });
884             }
885             Const(_, _) => {
886                 // Only methods and types support generics.
887                 assert!(trait_item.generics.params.is_empty());
888                 intravisit::walk_trait_item(self, trait_item);
889             }
890         }
891     }
892
893     #[instrument(level = "debug", skip(self))]
894     fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
895         use self::hir::ImplItemKind::*;
896         match impl_item.kind {
897             Fn(..) => self.visit_early_late(impl_item.hir_id(), &impl_item.generics, |this| {
898                 intravisit::walk_impl_item(this, impl_item)
899             }),
900             TyAlias(ref ty) => {
901                 let generics = &impl_item.generics;
902                 let lifetimes: FxIndexMap<LocalDefId, Region> = generics
903                     .params
904                     .iter()
905                     .filter_map(|param| match param.kind {
906                         GenericParamKind::Lifetime { .. } => {
907                             Some(Region::early(self.tcx.hir(), param))
908                         }
909                         GenericParamKind::Const { .. } | GenericParamKind::Type { .. } => None,
910                     })
911                     .collect();
912                 self.map.late_bound_vars.insert(ty.hir_id, vec![]);
913                 let scope = Scope::Binder {
914                     hir_id: ty.hir_id,
915                     lifetimes,
916                     s: self.scope,
917                     scope_type: BinderScopeType::Normal,
918                     where_bound_origin: None,
919                 };
920                 self.with(scope, |this| {
921                     let scope = Scope::TraitRefBoundary { s: this.scope };
922                     this.with(scope, |this| {
923                         this.visit_generics(generics);
924                         this.visit_ty(ty);
925                     })
926                 });
927             }
928             Const(_, _) => {
929                 // Only methods and types support generics.
930                 assert!(impl_item.generics.params.is_empty());
931                 intravisit::walk_impl_item(self, impl_item);
932             }
933         }
934     }
935
936     #[instrument(level = "debug", skip(self))]
937     fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
938         match lifetime_ref.name {
939             hir::LifetimeName::Static => self.insert_lifetime(lifetime_ref, Region::Static),
940             hir::LifetimeName::Param(param_def_id, _) => {
941                 self.resolve_lifetime_ref(param_def_id, lifetime_ref)
942             }
943             // If we've already reported an error, just ignore `lifetime_ref`.
944             hir::LifetimeName::Error => {}
945             // Those will be resolved by typechecking.
946             hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Infer => {}
947         }
948     }
949
950     fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, _: hir::HirId) {
951         for (i, segment) in path.segments.iter().enumerate() {
952             let depth = path.segments.len() - i - 1;
953             if let Some(ref args) = segment.args {
954                 self.visit_segment_args(path.res, depth, args);
955             }
956         }
957     }
958
959     fn visit_fn(
960         &mut self,
961         fk: intravisit::FnKind<'tcx>,
962         fd: &'tcx hir::FnDecl<'tcx>,
963         body_id: hir::BodyId,
964         _: Span,
965         _: hir::HirId,
966     ) {
967         let output = match fd.output {
968             hir::FnRetTy::DefaultReturn(_) => None,
969             hir::FnRetTy::Return(ref ty) => Some(&**ty),
970         };
971         self.visit_fn_like_elision(&fd.inputs, output, matches!(fk, intravisit::FnKind::Closure));
972         intravisit::walk_fn_kind(self, fk);
973         self.visit_nested_body(body_id)
974     }
975
976     fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
977         let scope = Scope::TraitRefBoundary { s: self.scope };
978         self.with(scope, |this| {
979             for param in generics.params {
980                 match param.kind {
981                     GenericParamKind::Lifetime { .. } => {}
982                     GenericParamKind::Type { ref default, .. } => {
983                         if let Some(ref ty) = default {
984                             this.visit_ty(&ty);
985                         }
986                     }
987                     GenericParamKind::Const { ref ty, default } => {
988                         this.visit_ty(&ty);
989                         if let Some(default) = default {
990                             this.visit_body(this.tcx.hir().body(default.body));
991                         }
992                     }
993                 }
994             }
995             for predicate in generics.predicates {
996                 match predicate {
997                     &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
998                         ref bounded_ty,
999                         bounds,
1000                         ref bound_generic_params,
1001                         origin,
1002                         ..
1003                     }) => {
1004                         let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) =
1005                             bound_generic_params
1006                                 .iter()
1007                                 .filter(|param| {
1008                                     matches!(param.kind, GenericParamKind::Lifetime { .. })
1009                                 })
1010                                 .enumerate()
1011                                 .map(|(late_bound_idx, param)| {
1012                                     let pair =
1013                                         Region::late(late_bound_idx as u32, this.tcx.hir(), param);
1014                                     let r = late_region_as_bound_region(this.tcx, &pair.1);
1015                                     (pair, r)
1016                                 })
1017                                 .unzip();
1018                         this.map.late_bound_vars.insert(bounded_ty.hir_id, binders.clone());
1019                         // Even if there are no lifetimes defined here, we still wrap it in a binder
1020                         // scope. If there happens to be a nested poly trait ref (an error), that
1021                         // will be `Concatenating` anyways, so we don't have to worry about the depth
1022                         // being wrong.
1023                         let scope = Scope::Binder {
1024                             hir_id: bounded_ty.hir_id,
1025                             lifetimes,
1026                             s: this.scope,
1027                             scope_type: BinderScopeType::Normal,
1028                             where_bound_origin: Some(origin),
1029                         };
1030                         this.with(scope, |this| {
1031                             this.visit_ty(&bounded_ty);
1032                             walk_list!(this, visit_param_bound, bounds);
1033                         })
1034                     }
1035                     &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
1036                         ref lifetime,
1037                         bounds,
1038                         ..
1039                     }) => {
1040                         this.visit_lifetime(lifetime);
1041                         walk_list!(this, visit_param_bound, bounds);
1042
1043                         if lifetime.name != hir::LifetimeName::Static {
1044                             for bound in bounds {
1045                                 let hir::GenericBound::Outlives(ref lt) = bound else {
1046                                     continue;
1047                                 };
1048                                 if lt.name != hir::LifetimeName::Static {
1049                                     continue;
1050                                 }
1051                                 this.insert_lifetime(lt, Region::Static);
1052                                 this.tcx
1053                                     .sess
1054                                     .struct_span_warn(
1055                                         lifetime.span,
1056                                         &format!(
1057                                             "unnecessary lifetime parameter `{}`",
1058                                             lifetime.name.ident(),
1059                                         ),
1060                                     )
1061                                     .help(&format!(
1062                                         "you can use the `'static` lifetime directly, in place of `{}`",
1063                                         lifetime.name.ident(),
1064                                     ))
1065                                     .emit();
1066                             }
1067                         }
1068                     }
1069                     &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
1070                         ref lhs_ty,
1071                         ref rhs_ty,
1072                         ..
1073                     }) => {
1074                         this.visit_ty(lhs_ty);
1075                         this.visit_ty(rhs_ty);
1076                     }
1077                 }
1078             }
1079         })
1080     }
1081
1082     fn visit_param_bound(&mut self, bound: &'tcx hir::GenericBound<'tcx>) {
1083         match bound {
1084             hir::GenericBound::LangItemTrait(_, _, hir_id, _) => {
1085                 // FIXME(jackh726): This is pretty weird. `LangItemTrait` doesn't go
1086                 // through the regular poly trait ref code, so we don't get another
1087                 // chance to introduce a binder. For now, I'm keeping the existing logic
1088                 // of "if there isn't a Binder scope above us, add one", but I
1089                 // imagine there's a better way to go about this.
1090                 let (binders, scope_type) = self.poly_trait_ref_binder_info();
1091
1092                 self.map.late_bound_vars.insert(*hir_id, binders);
1093                 let scope = Scope::Binder {
1094                     hir_id: *hir_id,
1095                     lifetimes: FxIndexMap::default(),
1096                     s: self.scope,
1097                     scope_type,
1098                     where_bound_origin: None,
1099                 };
1100                 self.with(scope, |this| {
1101                     intravisit::walk_param_bound(this, bound);
1102                 });
1103             }
1104             _ => intravisit::walk_param_bound(self, bound),
1105         }
1106     }
1107
1108     fn visit_poly_trait_ref(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) {
1109         debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref);
1110
1111         let (mut binders, scope_type) = self.poly_trait_ref_binder_info();
1112
1113         let initial_bound_vars = binders.len() as u32;
1114         let mut lifetimes: FxIndexMap<LocalDefId, Region> = FxIndexMap::default();
1115         let binders_iter = trait_ref
1116             .bound_generic_params
1117             .iter()
1118             .filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
1119             .enumerate()
1120             .map(|(late_bound_idx, param)| {
1121                 let pair =
1122                     Region::late(initial_bound_vars + late_bound_idx as u32, self.tcx.hir(), param);
1123                 let r = late_region_as_bound_region(self.tcx, &pair.1);
1124                 lifetimes.insert(pair.0, pair.1);
1125                 r
1126             });
1127         binders.extend(binders_iter);
1128
1129         debug!(?binders);
1130         self.map.late_bound_vars.insert(trait_ref.trait_ref.hir_ref_id, binders);
1131
1132         // Always introduce a scope here, even if this is in a where clause and
1133         // we introduced the binders around the bounded Ty. In that case, we
1134         // just reuse the concatenation functionality also present in nested trait
1135         // refs.
1136         let scope = Scope::Binder {
1137             hir_id: trait_ref.trait_ref.hir_ref_id,
1138             lifetimes,
1139             s: self.scope,
1140             scope_type,
1141             where_bound_origin: None,
1142         };
1143         self.with(scope, |this| {
1144             walk_list!(this, visit_generic_param, trait_ref.bound_generic_params);
1145             this.visit_trait_ref(&trait_ref.trait_ref);
1146         });
1147     }
1148 }
1149
1150 fn object_lifetime_default<'tcx>(tcx: TyCtxt<'tcx>, param_def_id: DefId) -> ObjectLifetimeDefault {
1151     debug_assert_eq!(tcx.def_kind(param_def_id), DefKind::TyParam);
1152     let param_def_id = param_def_id.expect_local();
1153     let parent_def_id = tcx.local_parent(param_def_id);
1154     let generics = tcx.hir().get_generics(parent_def_id).unwrap();
1155     let param_hir_id = tcx.local_def_id_to_hir_id(param_def_id);
1156     let param = generics.params.iter().find(|p| p.hir_id == param_hir_id).unwrap();
1157
1158     // Scan the bounds and where-clauses on parameters to extract bounds
1159     // of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
1160     // for each type parameter.
1161     match param.kind {
1162         GenericParamKind::Type { .. } => {
1163             let mut set = Set1::Empty;
1164
1165             // Look for `type: ...` where clauses.
1166             for bound in generics.bounds_for_param(param_def_id) {
1167                 // Ignore `for<'a> type: ...` as they can change what
1168                 // lifetimes mean (although we could "just" handle it).
1169                 if !bound.bound_generic_params.is_empty() {
1170                     continue;
1171                 }
1172
1173                 for bound in bound.bounds {
1174                     if let hir::GenericBound::Outlives(ref lifetime) = *bound {
1175                         set.insert(lifetime.name.normalize_to_macros_2_0());
1176                     }
1177                 }
1178             }
1179
1180             match set {
1181                 Set1::Empty => ObjectLifetimeDefault::Empty,
1182                 Set1::One(hir::LifetimeName::Static) => ObjectLifetimeDefault::Static,
1183                 Set1::One(hir::LifetimeName::Param(param_def_id, _)) => {
1184                     ObjectLifetimeDefault::Param(param_def_id.to_def_id())
1185                 }
1186                 _ => ObjectLifetimeDefault::Ambiguous,
1187             }
1188         }
1189         _ => {
1190             bug!("object_lifetime_default_raw must only be called on a type parameter")
1191         }
1192     }
1193 }
1194
1195 impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
1196     fn with<F>(&mut self, wrap_scope: Scope<'_>, f: F)
1197     where
1198         F: for<'b> FnOnce(&mut LifetimeContext<'b, 'tcx>),
1199     {
1200         let LifetimeContext { tcx, map, .. } = self;
1201         let mut this = LifetimeContext {
1202             tcx: *tcx,
1203             map,
1204             scope: &wrap_scope,
1205             trait_definition_only: self.trait_definition_only,
1206         };
1207         let span = debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope));
1208         {
1209             let _enter = span.enter();
1210             f(&mut this);
1211         }
1212     }
1213
1214     /// Visits self by adding a scope and handling recursive walk over the contents with `walk`.
1215     ///
1216     /// Handles visiting fns and methods. These are a bit complicated because we must distinguish
1217     /// early- vs late-bound lifetime parameters. We do this by checking which lifetimes appear
1218     /// within type bounds; those are early bound lifetimes, and the rest are late bound.
1219     ///
1220     /// For example:
1221     ///
1222     ///    fn foo<'a,'b,'c,T:Trait<'b>>(...)
1223     ///
1224     /// Here `'a` and `'c` are late bound but `'b` is early bound. Note that early- and late-bound
1225     /// lifetimes may be interspersed together.
1226     ///
1227     /// If early bound lifetimes are present, we separate them into their own list (and likewise
1228     /// for late bound). They will be numbered sequentially, starting from the lowest index that is
1229     /// already in scope (for a fn item, that will be 0, but for a method it might not be). Late
1230     /// bound lifetimes are resolved by name and associated with a binder ID (`binder_id`), so the
1231     /// ordering is not important there.
1232     fn visit_early_late<F>(
1233         &mut self,
1234         hir_id: hir::HirId,
1235         generics: &'tcx hir::Generics<'tcx>,
1236         walk: F,
1237     ) where
1238         F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>),
1239     {
1240         let mut named_late_bound_vars = 0;
1241         let lifetimes: FxIndexMap<LocalDefId, Region> = generics
1242             .params
1243             .iter()
1244             .filter_map(|param| match param.kind {
1245                 GenericParamKind::Lifetime { .. } => {
1246                     if self.tcx.is_late_bound(param.hir_id) {
1247                         let late_bound_idx = named_late_bound_vars;
1248                         named_late_bound_vars += 1;
1249                         Some(Region::late(late_bound_idx, self.tcx.hir(), param))
1250                     } else {
1251                         Some(Region::early(self.tcx.hir(), param))
1252                     }
1253                 }
1254                 GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None,
1255             })
1256             .collect();
1257
1258         let binders: Vec<_> = generics
1259             .params
1260             .iter()
1261             .filter(|param| {
1262                 matches!(param.kind, GenericParamKind::Lifetime { .. })
1263                     && self.tcx.is_late_bound(param.hir_id)
1264             })
1265             .enumerate()
1266             .map(|(late_bound_idx, param)| {
1267                 let pair = Region::late(late_bound_idx as u32, self.tcx.hir(), param);
1268                 late_region_as_bound_region(self.tcx, &pair.1)
1269             })
1270             .collect();
1271         self.map.late_bound_vars.insert(hir_id, binders);
1272         let scope = Scope::Binder {
1273             hir_id,
1274             lifetimes,
1275             s: self.scope,
1276             scope_type: BinderScopeType::Normal,
1277             where_bound_origin: None,
1278         };
1279         self.with(scope, walk);
1280     }
1281
1282     #[instrument(level = "debug", skip(self))]
1283     fn resolve_lifetime_ref(
1284         &mut self,
1285         region_def_id: LocalDefId,
1286         lifetime_ref: &'tcx hir::Lifetime,
1287     ) {
1288         // Walk up the scope chain, tracking the number of fn scopes
1289         // that we pass through, until we find a lifetime with the
1290         // given name or we run out of scopes.
1291         // search.
1292         let mut late_depth = 0;
1293         let mut scope = self.scope;
1294         let mut outermost_body = None;
1295         let result = loop {
1296             match *scope {
1297                 Scope::Body { id, s } => {
1298                     outermost_body = Some(id);
1299                     scope = s;
1300                 }
1301
1302                 Scope::Root => {
1303                     break None;
1304                 }
1305
1306                 Scope::Binder { ref lifetimes, scope_type, s, where_bound_origin, .. } => {
1307                     if let Some(&def) = lifetimes.get(&region_def_id) {
1308                         break Some(def.shifted(late_depth));
1309                     }
1310                     match scope_type {
1311                         BinderScopeType::Normal => late_depth += 1,
1312                         BinderScopeType::Concatenating => {}
1313                     }
1314                     // Fresh lifetimes in APIT used to be allowed in async fns and forbidden in
1315                     // regular fns.
1316                     if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin
1317                         && let hir::LifetimeName::Param(_, hir::ParamName::Fresh) = lifetime_ref.name
1318                         && let hir::IsAsync::NotAsync = self.tcx.asyncness(lifetime_ref.hir_id.owner)
1319                         && !self.tcx.features().anonymous_lifetime_in_impl_trait
1320                     {
1321                         rustc_session::parse::feature_err(
1322                             &self.tcx.sess.parse_sess,
1323                             sym::anonymous_lifetime_in_impl_trait,
1324                             lifetime_ref.span,
1325                             "anonymous lifetimes in `impl Trait` are unstable",
1326                         ).emit();
1327                         return;
1328                     }
1329                     scope = s;
1330                 }
1331
1332                 Scope::Elision { s, .. }
1333                 | Scope::ObjectLifetimeDefault { s, .. }
1334                 | Scope::Supertrait { s, .. }
1335                 | Scope::TraitRefBoundary { s, .. } => {
1336                     scope = s;
1337                 }
1338             }
1339         };
1340
1341         if let Some(mut def) = result {
1342             if let Region::EarlyBound(..) = def {
1343                 // Do not free early-bound regions, only late-bound ones.
1344             } else if let Some(body_id) = outermost_body {
1345                 let fn_id = self.tcx.hir().body_owner(body_id);
1346                 match self.tcx.hir().get(fn_id) {
1347                     Node::Item(&hir::Item { kind: hir::ItemKind::Fn(..), .. })
1348                     | Node::TraitItem(&hir::TraitItem {
1349                         kind: hir::TraitItemKind::Fn(..), ..
1350                     })
1351                     | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => {
1352                         let scope = self.tcx.hir().local_def_id(fn_id);
1353                         def = Region::Free(scope.to_def_id(), def.id().unwrap());
1354                     }
1355                     _ => {}
1356                 }
1357             }
1358
1359             self.insert_lifetime(lifetime_ref, def);
1360             return;
1361         }
1362
1363         // We may fail to resolve higher-ranked lifetimes that are mentioned by APIT.
1364         // AST-based resolution does not care for impl-trait desugaring, which are the
1365         // responibility of lowering.  This may create a mismatch between the resolution
1366         // AST found (`region_def_id`) which points to HRTB, and what HIR allows.
1367         // ```
1368         // fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
1369         // ```
1370         //
1371         // In such case, walk back the binders to diagnose it properly.
1372         let mut scope = self.scope;
1373         loop {
1374             match *scope {
1375                 Scope::Binder {
1376                     where_bound_origin: Some(hir::PredicateOrigin::ImplTrait), ..
1377                 } => {
1378                     let mut err = self.tcx.sess.struct_span_err(
1379                         lifetime_ref.span,
1380                         "`impl Trait` can only mention lifetimes bound at the fn or impl level",
1381                     );
1382                     err.span_note(self.tcx.def_span(region_def_id), "lifetime declared here");
1383                     err.emit();
1384                     return;
1385                 }
1386                 Scope::Root => break,
1387                 Scope::Binder { s, .. }
1388                 | Scope::Body { s, .. }
1389                 | Scope::Elision { s, .. }
1390                 | Scope::ObjectLifetimeDefault { s, .. }
1391                 | Scope::Supertrait { s, .. }
1392                 | Scope::TraitRefBoundary { s, .. } => {
1393                     scope = s;
1394                 }
1395             }
1396         }
1397
1398         self.tcx.sess.delay_span_bug(
1399             lifetime_ref.span,
1400             &format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
1401         );
1402     }
1403
1404     #[instrument(level = "debug", skip(self))]
1405     fn visit_segment_args(
1406         &mut self,
1407         res: Res,
1408         depth: usize,
1409         generic_args: &'tcx hir::GenericArgs<'tcx>,
1410     ) {
1411         if generic_args.parenthesized {
1412             self.visit_fn_like_elision(
1413                 generic_args.inputs(),
1414                 Some(generic_args.bindings[0].ty()),
1415                 false,
1416             );
1417             return;
1418         }
1419
1420         for arg in generic_args.args {
1421             if let hir::GenericArg::Lifetime(lt) = arg {
1422                 self.visit_lifetime(lt);
1423             }
1424         }
1425
1426         // Figure out if this is a type/trait segment,
1427         // which requires object lifetime defaults.
1428         let type_def_id = match res {
1429             Res::Def(DefKind::AssocTy, def_id) if depth == 1 => Some(self.tcx.parent(def_id)),
1430             Res::Def(DefKind::Variant, def_id) if depth == 0 => Some(self.tcx.parent(def_id)),
1431             Res::Def(
1432                 DefKind::Struct
1433                 | DefKind::Union
1434                 | DefKind::Enum
1435                 | DefKind::TyAlias
1436                 | DefKind::Trait,
1437                 def_id,
1438             ) if depth == 0 => Some(def_id),
1439             _ => None,
1440         };
1441
1442         debug!(?type_def_id);
1443
1444         // Compute a vector of defaults, one for each type parameter,
1445         // per the rules given in RFCs 599 and 1156. Example:
1446         //
1447         // ```rust
1448         // struct Foo<'a, T: 'a, U> { }
1449         // ```
1450         //
1451         // If you have `Foo<'x, dyn Bar, dyn Baz>`, we want to default
1452         // `dyn Bar` to `dyn Bar + 'x` (because of the `T: 'a` bound)
1453         // and `dyn Baz` to `dyn Baz + 'static` (because there is no
1454         // such bound).
1455         //
1456         // Therefore, we would compute `object_lifetime_defaults` to a
1457         // vector like `['x, 'static]`. Note that the vector only
1458         // includes type parameters.
1459         let object_lifetime_defaults = type_def_id.map_or_else(Vec::new, |def_id| {
1460             let in_body = {
1461                 let mut scope = self.scope;
1462                 loop {
1463                     match *scope {
1464                         Scope::Root => break false,
1465
1466                         Scope::Body { .. } => break true,
1467
1468                         Scope::Binder { s, .. }
1469                         | Scope::Elision { s, .. }
1470                         | Scope::ObjectLifetimeDefault { s, .. }
1471                         | Scope::Supertrait { s, .. }
1472                         | Scope::TraitRefBoundary { s, .. } => {
1473                             scope = s;
1474                         }
1475                     }
1476                 }
1477             };
1478
1479             let map = &self.map;
1480             let generics = self.tcx.generics_of(def_id);
1481
1482             // `type_def_id` points to an item, so there is nothing to inherit generics from.
1483             debug_assert_eq!(generics.parent_count, 0);
1484
1485             let set_to_region = |set: ObjectLifetimeDefault| match set {
1486                 ObjectLifetimeDefault::Empty => {
1487                     if in_body {
1488                         None
1489                     } else {
1490                         Some(Region::Static)
1491                     }
1492                 }
1493                 ObjectLifetimeDefault::Static => Some(Region::Static),
1494                 ObjectLifetimeDefault::Param(param_def_id) => {
1495                     // This index can be used with `generic_args` since `parent_count == 0`.
1496                     let index = generics.param_def_id_to_index[&param_def_id] as usize;
1497                     generic_args.args.get(index).and_then(|arg| match arg {
1498                         GenericArg::Lifetime(lt) => map.defs.get(&lt.hir_id).copied(),
1499                         _ => None,
1500                     })
1501                 }
1502                 ObjectLifetimeDefault::Ambiguous => None,
1503             };
1504             generics
1505                 .params
1506                 .iter()
1507                 .filter_map(|param| {
1508                     match self.tcx.def_kind(param.def_id) {
1509                         // Generic consts don't impose any constraints.
1510                         //
1511                         // We still store a dummy value here to allow generic parameters
1512                         // in an arbitrary order.
1513                         DefKind::ConstParam => Some(ObjectLifetimeDefault::Empty),
1514                         DefKind::TyParam => Some(self.tcx.object_lifetime_default(param.def_id)),
1515                         // We may also get a `Trait` or `TraitAlias` because of how generics `Self` parameter
1516                         // works.  Ignore it because it can't have a meaningful lifetime default.
1517                         DefKind::LifetimeParam | DefKind::Trait | DefKind::TraitAlias => None,
1518                         dk => bug!("unexpected def_kind {:?}", dk),
1519                     }
1520                 })
1521                 .map(set_to_region)
1522                 .collect()
1523         });
1524
1525         debug!(?object_lifetime_defaults);
1526
1527         let mut i = 0;
1528         for arg in generic_args.args {
1529             match arg {
1530                 GenericArg::Lifetime(_) => {}
1531                 GenericArg::Type(ty) => {
1532                     if let Some(&lt) = object_lifetime_defaults.get(i) {
1533                         let scope = Scope::ObjectLifetimeDefault { lifetime: lt, s: self.scope };
1534                         self.with(scope, |this| this.visit_ty(ty));
1535                     } else {
1536                         self.visit_ty(ty);
1537                     }
1538                     i += 1;
1539                 }
1540                 GenericArg::Const(ct) => {
1541                     self.visit_anon_const(&ct.value);
1542                     i += 1;
1543                 }
1544                 GenericArg::Infer(inf) => {
1545                     self.visit_id(inf.hir_id);
1546                     i += 1;
1547                 }
1548             }
1549         }
1550
1551         // Hack: when resolving the type `XX` in binding like `dyn
1552         // Foo<'b, Item = XX>`, the current object-lifetime default
1553         // would be to examine the trait `Foo` to check whether it has
1554         // a lifetime bound declared on `Item`. e.g., if `Foo` is
1555         // declared like so, then the default object lifetime bound in
1556         // `XX` should be `'b`:
1557         //
1558         // ```rust
1559         // trait Foo<'a> {
1560         //   type Item: 'a;
1561         // }
1562         // ```
1563         //
1564         // but if we just have `type Item;`, then it would be
1565         // `'static`. However, we don't get all of this logic correct.
1566         //
1567         // Instead, we do something hacky: if there are no lifetime parameters
1568         // to the trait, then we simply use a default object lifetime
1569         // bound of `'static`, because there is no other possibility. On the other hand,
1570         // if there ARE lifetime parameters, then we require the user to give an
1571         // explicit bound for now.
1572         //
1573         // This is intended to leave room for us to implement the
1574         // correct behavior in the future.
1575         let has_lifetime_parameter =
1576             generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)));
1577
1578         // Resolve lifetimes found in the bindings, so either in the type `XX` in `Item = XX` or
1579         // in the trait ref `YY<...>` in `Item: YY<...>`.
1580         for binding in generic_args.bindings {
1581             let scope = Scope::ObjectLifetimeDefault {
1582                 lifetime: if has_lifetime_parameter { None } else { Some(Region::Static) },
1583                 s: self.scope,
1584             };
1585             if let Some(type_def_id) = type_def_id {
1586                 let lifetimes = LifetimeContext::supertrait_hrtb_lifetimes(
1587                     self.tcx,
1588                     type_def_id,
1589                     binding.ident,
1590                 );
1591                 self.with(scope, |this| {
1592                     let scope = Scope::Supertrait {
1593                         lifetimes: lifetimes.unwrap_or_default(),
1594                         s: this.scope,
1595                     };
1596                     this.with(scope, |this| this.visit_assoc_type_binding(binding));
1597                 });
1598             } else {
1599                 self.with(scope, |this| this.visit_assoc_type_binding(binding));
1600             }
1601         }
1602     }
1603
1604     /// Returns all the late-bound vars that come into scope from supertrait HRTBs, based on the
1605     /// associated type name and starting trait.
1606     /// For example, imagine we have
1607     /// ```ignore (illustrative)
1608     /// trait Foo<'a, 'b> {
1609     ///   type As;
1610     /// }
1611     /// trait Bar<'b>: for<'a> Foo<'a, 'b> {}
1612     /// trait Bar: for<'b> Bar<'b> {}
1613     /// ```
1614     /// In this case, if we wanted to the supertrait HRTB lifetimes for `As` on
1615     /// the starting trait `Bar`, we would return `Some(['b, 'a])`.
1616     fn supertrait_hrtb_lifetimes(
1617         tcx: TyCtxt<'tcx>,
1618         def_id: DefId,
1619         assoc_name: Ident,
1620     ) -> Option<Vec<ty::BoundVariableKind>> {
1621         let trait_defines_associated_type_named = |trait_def_id: DefId| {
1622             tcx.associated_items(trait_def_id)
1623                 .find_by_name_and_kind(tcx, assoc_name, ty::AssocKind::Type, trait_def_id)
1624                 .is_some()
1625         };
1626
1627         use smallvec::{smallvec, SmallVec};
1628         let mut stack: SmallVec<[(DefId, SmallVec<[ty::BoundVariableKind; 8]>); 8]> =
1629             smallvec![(def_id, smallvec![])];
1630         let mut visited: FxHashSet<DefId> = FxHashSet::default();
1631         loop {
1632             let Some((def_id, bound_vars)) = stack.pop() else {
1633                 break None;
1634             };
1635             // See issue #83753. If someone writes an associated type on a non-trait, just treat it as
1636             // there being no supertrait HRTBs.
1637             match tcx.def_kind(def_id) {
1638                 DefKind::Trait | DefKind::TraitAlias | DefKind::Impl => {}
1639                 _ => break None,
1640             }
1641
1642             if trait_defines_associated_type_named(def_id) {
1643                 break Some(bound_vars.into_iter().collect());
1644             }
1645             let predicates =
1646                 tcx.super_predicates_that_define_assoc_type((def_id, Some(assoc_name)));
1647             let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| {
1648                 let bound_predicate = pred.kind();
1649                 match bound_predicate.skip_binder() {
1650                     ty::PredicateKind::Trait(data) => {
1651                         // The order here needs to match what we would get from `subst_supertrait`
1652                         let pred_bound_vars = bound_predicate.bound_vars();
1653                         let mut all_bound_vars = bound_vars.clone();
1654                         all_bound_vars.extend(pred_bound_vars.iter());
1655                         let super_def_id = data.trait_ref.def_id;
1656                         Some((super_def_id, all_bound_vars))
1657                     }
1658                     _ => None,
1659                 }
1660             });
1661
1662             let obligations = obligations.filter(|o| visited.insert(o.0));
1663             stack.extend(obligations);
1664         }
1665     }
1666
1667     #[instrument(level = "debug", skip(self))]
1668     fn visit_fn_like_elision(
1669         &mut self,
1670         inputs: &'tcx [hir::Ty<'tcx>],
1671         output: Option<&'tcx hir::Ty<'tcx>>,
1672         in_closure: bool,
1673     ) {
1674         self.with(Scope::Elision { s: self.scope }, |this| {
1675             for input in inputs {
1676                 this.visit_ty(input);
1677             }
1678             if !in_closure && let Some(output) = output {
1679                 this.visit_ty(output);
1680             }
1681         });
1682         if in_closure && let Some(output) = output {
1683             self.visit_ty(output);
1684         }
1685     }
1686
1687     fn resolve_object_lifetime_default(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
1688         debug!("resolve_object_lifetime_default(lifetime_ref={:?})", lifetime_ref);
1689         let mut late_depth = 0;
1690         let mut scope = self.scope;
1691         let lifetime = loop {
1692             match *scope {
1693                 Scope::Binder { s, scope_type, .. } => {
1694                     match scope_type {
1695                         BinderScopeType::Normal => late_depth += 1,
1696                         BinderScopeType::Concatenating => {}
1697                     }
1698                     scope = s;
1699                 }
1700
1701                 Scope::Root | Scope::Elision { .. } => break Region::Static,
1702
1703                 Scope::Body { .. } | Scope::ObjectLifetimeDefault { lifetime: None, .. } => return,
1704
1705                 Scope::ObjectLifetimeDefault { lifetime: Some(l), .. } => break l,
1706
1707                 Scope::Supertrait { s, .. } | Scope::TraitRefBoundary { s, .. } => {
1708                     scope = s;
1709                 }
1710             }
1711         };
1712         self.insert_lifetime(lifetime_ref, lifetime.shifted(late_depth));
1713     }
1714
1715     #[instrument(level = "debug", skip(self))]
1716     fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
1717         debug!(
1718             node = ?self.tcx.hir().node_to_string(lifetime_ref.hir_id),
1719             span = ?self.tcx.sess.source_map().span_to_diagnostic_string(lifetime_ref.span)
1720         );
1721         self.map.defs.insert(lifetime_ref.hir_id, def);
1722     }
1723
1724     /// Sometimes we resolve a lifetime, but later find that it is an
1725     /// error (esp. around impl trait). In that case, we remove the
1726     /// entry into `map.defs` so as not to confuse later code.
1727     fn uninsert_lifetime_on_error(&mut self, lifetime_ref: &'tcx hir::Lifetime, bad_def: Region) {
1728         let old_value = self.map.defs.remove(&lifetime_ref.hir_id);
1729         assert_eq!(old_value, Some(bad_def));
1730     }
1731 }
1732
1733 /// Detects late-bound lifetimes and inserts them into
1734 /// `late_bound`.
1735 ///
1736 /// A region declared on a fn is **late-bound** if:
1737 /// - it is constrained by an argument type;
1738 /// - it does not appear in a where-clause.
1739 ///
1740 /// "Constrained" basically means that it appears in any type but
1741 /// not amongst the inputs to a projection. In other words, `<&'a
1742 /// T as Trait<''b>>::Foo` does not constrain `'a` or `'b`.
1743 fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<LocalDefId>> {
1744     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
1745     let decl = tcx.hir().fn_decl_by_hir_id(hir_id)?;
1746     let generics = tcx.hir().get_generics(def_id)?;
1747
1748     let mut late_bound = FxIndexSet::default();
1749
1750     let mut constrained_by_input = ConstrainedCollector::default();
1751     for arg_ty in decl.inputs {
1752         constrained_by_input.visit_ty(arg_ty);
1753     }
1754
1755     let mut appears_in_output = AllCollector::default();
1756     intravisit::walk_fn_ret_ty(&mut appears_in_output, &decl.output);
1757
1758     debug!(?constrained_by_input.regions);
1759
1760     // Walk the lifetimes that appear in where clauses.
1761     //
1762     // Subtle point: because we disallow nested bindings, we can just
1763     // ignore binders here and scrape up all names we see.
1764     let mut appears_in_where_clause = AllCollector::default();
1765     appears_in_where_clause.visit_generics(generics);
1766     debug!(?appears_in_where_clause.regions);
1767
1768     // Late bound regions are those that:
1769     // - appear in the inputs
1770     // - do not appear in the where-clauses
1771     // - are not implicitly captured by `impl Trait`
1772     for param in generics.params {
1773         match param.kind {
1774             hir::GenericParamKind::Lifetime { .. } => { /* fall through */ }
1775
1776             // Neither types nor consts are late-bound.
1777             hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => continue,
1778         }
1779
1780         let param_def_id = tcx.hir().local_def_id(param.hir_id);
1781
1782         // appears in the where clauses? early-bound.
1783         if appears_in_where_clause.regions.contains(&param_def_id) {
1784             continue;
1785         }
1786
1787         // does not appear in the inputs, but appears in the return type? early-bound.
1788         if !constrained_by_input.regions.contains(&param_def_id)
1789             && appears_in_output.regions.contains(&param_def_id)
1790         {
1791             continue;
1792         }
1793
1794         debug!("lifetime {:?} with id {:?} is late-bound", param.name.ident(), param.hir_id);
1795
1796         let inserted = late_bound.insert(param_def_id);
1797         assert!(inserted, "visited lifetime {:?} twice", param.hir_id);
1798     }
1799
1800     debug!(?late_bound);
1801     return Some(tcx.arena.alloc(late_bound));
1802
1803     #[derive(Default)]
1804     struct ConstrainedCollector {
1805         regions: FxHashSet<LocalDefId>,
1806     }
1807
1808     impl<'v> Visitor<'v> for ConstrainedCollector {
1809         fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
1810             match ty.kind {
1811                 hir::TyKind::Path(
1812                     hir::QPath::Resolved(Some(_), _) | hir::QPath::TypeRelative(..),
1813                 ) => {
1814                     // ignore lifetimes appearing in associated type
1815                     // projections, as they are not *constrained*
1816                     // (defined above)
1817                 }
1818
1819                 hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => {
1820                     // consider only the lifetimes on the final
1821                     // segment; I am not sure it's even currently
1822                     // valid to have them elsewhere, but even if it
1823                     // is, those would be potentially inputs to
1824                     // projections
1825                     if let Some(last_segment) = path.segments.last() {
1826                         self.visit_path_segment(last_segment);
1827                     }
1828                 }
1829
1830                 _ => {
1831                     intravisit::walk_ty(self, ty);
1832                 }
1833             }
1834         }
1835
1836         fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
1837             if let hir::LifetimeName::Param(def_id, _) = lifetime_ref.name {
1838                 self.regions.insert(def_id);
1839             }
1840         }
1841     }
1842
1843     #[derive(Default)]
1844     struct AllCollector {
1845         regions: FxHashSet<LocalDefId>,
1846     }
1847
1848     impl<'v> Visitor<'v> for AllCollector {
1849         fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
1850             if let hir::LifetimeName::Param(def_id, _) = lifetime_ref.name {
1851                 self.regions.insert(def_id);
1852             }
1853         }
1854     }
1855 }