]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_resolve/src/late/lifetimes.rs
Rollup merge of #101700 - compiler-errors:deletion-span, r=davidtwco
[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, hir::TraitBoundModifier::None);
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(
1109         &mut self,
1110         trait_ref: &'tcx hir::PolyTraitRef<'tcx>,
1111         _modifier: hir::TraitBoundModifier,
1112     ) {
1113         debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref);
1114
1115         let (mut binders, scope_type) = self.poly_trait_ref_binder_info();
1116
1117         let initial_bound_vars = binders.len() as u32;
1118         let mut lifetimes: FxIndexMap<LocalDefId, Region> = FxIndexMap::default();
1119         let binders_iter = trait_ref
1120             .bound_generic_params
1121             .iter()
1122             .filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
1123             .enumerate()
1124             .map(|(late_bound_idx, param)| {
1125                 let pair =
1126                     Region::late(initial_bound_vars + late_bound_idx as u32, self.tcx.hir(), param);
1127                 let r = late_region_as_bound_region(self.tcx, &pair.1);
1128                 lifetimes.insert(pair.0, pair.1);
1129                 r
1130             });
1131         binders.extend(binders_iter);
1132
1133         debug!(?binders);
1134         self.map.late_bound_vars.insert(trait_ref.trait_ref.hir_ref_id, binders);
1135
1136         // Always introduce a scope here, even if this is in a where clause and
1137         // we introduced the binders around the bounded Ty. In that case, we
1138         // just reuse the concatenation functionality also present in nested trait
1139         // refs.
1140         let scope = Scope::Binder {
1141             hir_id: trait_ref.trait_ref.hir_ref_id,
1142             lifetimes,
1143             s: self.scope,
1144             scope_type,
1145             where_bound_origin: None,
1146         };
1147         self.with(scope, |this| {
1148             walk_list!(this, visit_generic_param, trait_ref.bound_generic_params);
1149             this.visit_trait_ref(&trait_ref.trait_ref);
1150         });
1151     }
1152 }
1153
1154 fn object_lifetime_default<'tcx>(tcx: TyCtxt<'tcx>, param_def_id: DefId) -> ObjectLifetimeDefault {
1155     debug_assert_eq!(tcx.def_kind(param_def_id), DefKind::TyParam);
1156     let param_def_id = param_def_id.expect_local();
1157     let parent_def_id = tcx.local_parent(param_def_id);
1158     let generics = tcx.hir().get_generics(parent_def_id).unwrap();
1159     let param_hir_id = tcx.local_def_id_to_hir_id(param_def_id);
1160     let param = generics.params.iter().find(|p| p.hir_id == param_hir_id).unwrap();
1161
1162     // Scan the bounds and where-clauses on parameters to extract bounds
1163     // of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
1164     // for each type parameter.
1165     match param.kind {
1166         GenericParamKind::Type { .. } => {
1167             let mut set = Set1::Empty;
1168
1169             // Look for `type: ...` where clauses.
1170             for bound in generics.bounds_for_param(param_def_id) {
1171                 // Ignore `for<'a> type: ...` as they can change what
1172                 // lifetimes mean (although we could "just" handle it).
1173                 if !bound.bound_generic_params.is_empty() {
1174                     continue;
1175                 }
1176
1177                 for bound in bound.bounds {
1178                     if let hir::GenericBound::Outlives(ref lifetime) = *bound {
1179                         set.insert(lifetime.name.normalize_to_macros_2_0());
1180                     }
1181                 }
1182             }
1183
1184             match set {
1185                 Set1::Empty => ObjectLifetimeDefault::Empty,
1186                 Set1::One(hir::LifetimeName::Static) => ObjectLifetimeDefault::Static,
1187                 Set1::One(hir::LifetimeName::Param(param_def_id, _)) => {
1188                     ObjectLifetimeDefault::Param(param_def_id.to_def_id())
1189                 }
1190                 _ => ObjectLifetimeDefault::Ambiguous,
1191             }
1192         }
1193         _ => {
1194             bug!("object_lifetime_default_raw must only be called on a type parameter")
1195         }
1196     }
1197 }
1198
1199 impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
1200     fn with<F>(&mut self, wrap_scope: Scope<'_>, f: F)
1201     where
1202         F: for<'b> FnOnce(&mut LifetimeContext<'b, 'tcx>),
1203     {
1204         let LifetimeContext { tcx, map, .. } = self;
1205         let mut this = LifetimeContext {
1206             tcx: *tcx,
1207             map,
1208             scope: &wrap_scope,
1209             trait_definition_only: self.trait_definition_only,
1210         };
1211         let span = debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope));
1212         {
1213             let _enter = span.enter();
1214             f(&mut this);
1215         }
1216     }
1217
1218     /// Visits self by adding a scope and handling recursive walk over the contents with `walk`.
1219     ///
1220     /// Handles visiting fns and methods. These are a bit complicated because we must distinguish
1221     /// early- vs late-bound lifetime parameters. We do this by checking which lifetimes appear
1222     /// within type bounds; those are early bound lifetimes, and the rest are late bound.
1223     ///
1224     /// For example:
1225     ///
1226     ///    fn foo<'a,'b,'c,T:Trait<'b>>(...)
1227     ///
1228     /// Here `'a` and `'c` are late bound but `'b` is early bound. Note that early- and late-bound
1229     /// lifetimes may be interspersed together.
1230     ///
1231     /// If early bound lifetimes are present, we separate them into their own list (and likewise
1232     /// for late bound). They will be numbered sequentially, starting from the lowest index that is
1233     /// already in scope (for a fn item, that will be 0, but for a method it might not be). Late
1234     /// bound lifetimes are resolved by name and associated with a binder ID (`binder_id`), so the
1235     /// ordering is not important there.
1236     fn visit_early_late<F>(
1237         &mut self,
1238         hir_id: hir::HirId,
1239         generics: &'tcx hir::Generics<'tcx>,
1240         walk: F,
1241     ) where
1242         F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>),
1243     {
1244         let mut named_late_bound_vars = 0;
1245         let lifetimes: FxIndexMap<LocalDefId, Region> = generics
1246             .params
1247             .iter()
1248             .filter_map(|param| match param.kind {
1249                 GenericParamKind::Lifetime { .. } => {
1250                     if self.tcx.is_late_bound(param.hir_id) {
1251                         let late_bound_idx = named_late_bound_vars;
1252                         named_late_bound_vars += 1;
1253                         Some(Region::late(late_bound_idx, self.tcx.hir(), param))
1254                     } else {
1255                         Some(Region::early(self.tcx.hir(), param))
1256                     }
1257                 }
1258                 GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None,
1259             })
1260             .collect();
1261
1262         let binders: Vec<_> = generics
1263             .params
1264             .iter()
1265             .filter(|param| {
1266                 matches!(param.kind, GenericParamKind::Lifetime { .. })
1267                     && self.tcx.is_late_bound(param.hir_id)
1268             })
1269             .enumerate()
1270             .map(|(late_bound_idx, param)| {
1271                 let pair = Region::late(late_bound_idx as u32, self.tcx.hir(), param);
1272                 late_region_as_bound_region(self.tcx, &pair.1)
1273             })
1274             .collect();
1275         self.map.late_bound_vars.insert(hir_id, binders);
1276         let scope = Scope::Binder {
1277             hir_id,
1278             lifetimes,
1279             s: self.scope,
1280             scope_type: BinderScopeType::Normal,
1281             where_bound_origin: None,
1282         };
1283         self.with(scope, walk);
1284     }
1285
1286     #[instrument(level = "debug", skip(self))]
1287     fn resolve_lifetime_ref(
1288         &mut self,
1289         region_def_id: LocalDefId,
1290         lifetime_ref: &'tcx hir::Lifetime,
1291     ) {
1292         // Walk up the scope chain, tracking the number of fn scopes
1293         // that we pass through, until we find a lifetime with the
1294         // given name or we run out of scopes.
1295         // search.
1296         let mut late_depth = 0;
1297         let mut scope = self.scope;
1298         let mut outermost_body = None;
1299         let result = loop {
1300             match *scope {
1301                 Scope::Body { id, s } => {
1302                     outermost_body = Some(id);
1303                     scope = s;
1304                 }
1305
1306                 Scope::Root => {
1307                     break None;
1308                 }
1309
1310                 Scope::Binder { ref lifetimes, scope_type, s, where_bound_origin, .. } => {
1311                     if let Some(&def) = lifetimes.get(&region_def_id) {
1312                         break Some(def.shifted(late_depth));
1313                     }
1314                     match scope_type {
1315                         BinderScopeType::Normal => late_depth += 1,
1316                         BinderScopeType::Concatenating => {}
1317                     }
1318                     // Fresh lifetimes in APIT used to be allowed in async fns and forbidden in
1319                     // regular fns.
1320                     if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin
1321                         && let hir::LifetimeName::Param(_, hir::ParamName::Fresh) = lifetime_ref.name
1322                         && let hir::IsAsync::NotAsync = self.tcx.asyncness(lifetime_ref.hir_id.owner)
1323                         && !self.tcx.features().anonymous_lifetime_in_impl_trait
1324                     {
1325                         rustc_session::parse::feature_err(
1326                             &self.tcx.sess.parse_sess,
1327                             sym::anonymous_lifetime_in_impl_trait,
1328                             lifetime_ref.span,
1329                             "anonymous lifetimes in `impl Trait` are unstable",
1330                         ).emit();
1331                         return;
1332                     }
1333                     scope = s;
1334                 }
1335
1336                 Scope::Elision { s, .. }
1337                 | Scope::ObjectLifetimeDefault { s, .. }
1338                 | Scope::Supertrait { s, .. }
1339                 | Scope::TraitRefBoundary { s, .. } => {
1340                     scope = s;
1341                 }
1342             }
1343         };
1344
1345         if let Some(mut def) = result {
1346             if let Region::EarlyBound(..) = def {
1347                 // Do not free early-bound regions, only late-bound ones.
1348             } else if let Some(body_id) = outermost_body {
1349                 let fn_id = self.tcx.hir().body_owner(body_id);
1350                 match self.tcx.hir().get(fn_id) {
1351                     Node::Item(&hir::Item { kind: hir::ItemKind::Fn(..), .. })
1352                     | Node::TraitItem(&hir::TraitItem {
1353                         kind: hir::TraitItemKind::Fn(..), ..
1354                     })
1355                     | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => {
1356                         let scope = self.tcx.hir().local_def_id(fn_id);
1357                         def = Region::Free(scope.to_def_id(), def.id().unwrap());
1358                     }
1359                     _ => {}
1360                 }
1361             }
1362
1363             self.insert_lifetime(lifetime_ref, def);
1364             return;
1365         }
1366
1367         // We may fail to resolve higher-ranked lifetimes that are mentioned by APIT.
1368         // AST-based resolution does not care for impl-trait desugaring, which are the
1369         // responibility of lowering.  This may create a mismatch between the resolution
1370         // AST found (`region_def_id`) which points to HRTB, and what HIR allows.
1371         // ```
1372         // fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
1373         // ```
1374         //
1375         // In such case, walk back the binders to diagnose it properly.
1376         let mut scope = self.scope;
1377         loop {
1378             match *scope {
1379                 Scope::Binder {
1380                     where_bound_origin: Some(hir::PredicateOrigin::ImplTrait), ..
1381                 } => {
1382                     let mut err = self.tcx.sess.struct_span_err(
1383                         lifetime_ref.span,
1384                         "`impl Trait` can only mention lifetimes bound at the fn or impl level",
1385                     );
1386                     err.span_note(self.tcx.def_span(region_def_id), "lifetime declared here");
1387                     err.emit();
1388                     return;
1389                 }
1390                 Scope::Root => break,
1391                 Scope::Binder { s, .. }
1392                 | Scope::Body { s, .. }
1393                 | Scope::Elision { s, .. }
1394                 | Scope::ObjectLifetimeDefault { s, .. }
1395                 | Scope::Supertrait { s, .. }
1396                 | Scope::TraitRefBoundary { s, .. } => {
1397                     scope = s;
1398                 }
1399             }
1400         }
1401
1402         self.tcx.sess.delay_span_bug(
1403             lifetime_ref.span,
1404             &format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
1405         );
1406     }
1407
1408     #[instrument(level = "debug", skip(self))]
1409     fn visit_segment_args(
1410         &mut self,
1411         res: Res,
1412         depth: usize,
1413         generic_args: &'tcx hir::GenericArgs<'tcx>,
1414     ) {
1415         if generic_args.parenthesized {
1416             self.visit_fn_like_elision(
1417                 generic_args.inputs(),
1418                 Some(generic_args.bindings[0].ty()),
1419                 false,
1420             );
1421             return;
1422         }
1423
1424         for arg in generic_args.args {
1425             if let hir::GenericArg::Lifetime(lt) = arg {
1426                 self.visit_lifetime(lt);
1427             }
1428         }
1429
1430         // Figure out if this is a type/trait segment,
1431         // which requires object lifetime defaults.
1432         let type_def_id = match res {
1433             Res::Def(DefKind::AssocTy, def_id) if depth == 1 => Some(self.tcx.parent(def_id)),
1434             Res::Def(DefKind::Variant, def_id) if depth == 0 => Some(self.tcx.parent(def_id)),
1435             Res::Def(
1436                 DefKind::Struct
1437                 | DefKind::Union
1438                 | DefKind::Enum
1439                 | DefKind::TyAlias
1440                 | DefKind::Trait,
1441                 def_id,
1442             ) if depth == 0 => Some(def_id),
1443             _ => None,
1444         };
1445
1446         debug!(?type_def_id);
1447
1448         // Compute a vector of defaults, one for each type parameter,
1449         // per the rules given in RFCs 599 and 1156. Example:
1450         //
1451         // ```rust
1452         // struct Foo<'a, T: 'a, U> { }
1453         // ```
1454         //
1455         // If you have `Foo<'x, dyn Bar, dyn Baz>`, we want to default
1456         // `dyn Bar` to `dyn Bar + 'x` (because of the `T: 'a` bound)
1457         // and `dyn Baz` to `dyn Baz + 'static` (because there is no
1458         // such bound).
1459         //
1460         // Therefore, we would compute `object_lifetime_defaults` to a
1461         // vector like `['x, 'static]`. Note that the vector only
1462         // includes type parameters.
1463         let object_lifetime_defaults = type_def_id.map_or_else(Vec::new, |def_id| {
1464             let in_body = {
1465                 let mut scope = self.scope;
1466                 loop {
1467                     match *scope {
1468                         Scope::Root => break false,
1469
1470                         Scope::Body { .. } => break true,
1471
1472                         Scope::Binder { s, .. }
1473                         | Scope::Elision { s, .. }
1474                         | Scope::ObjectLifetimeDefault { s, .. }
1475                         | Scope::Supertrait { s, .. }
1476                         | Scope::TraitRefBoundary { s, .. } => {
1477                             scope = s;
1478                         }
1479                     }
1480                 }
1481             };
1482
1483             let map = &self.map;
1484             let generics = self.tcx.generics_of(def_id);
1485
1486             // `type_def_id` points to an item, so there is nothing to inherit generics from.
1487             debug_assert_eq!(generics.parent_count, 0);
1488
1489             let set_to_region = |set: ObjectLifetimeDefault| match set {
1490                 ObjectLifetimeDefault::Empty => {
1491                     if in_body {
1492                         None
1493                     } else {
1494                         Some(Region::Static)
1495                     }
1496                 }
1497                 ObjectLifetimeDefault::Static => Some(Region::Static),
1498                 ObjectLifetimeDefault::Param(param_def_id) => {
1499                     // This index can be used with `generic_args` since `parent_count == 0`.
1500                     let index = generics.param_def_id_to_index[&param_def_id] as usize;
1501                     generic_args.args.get(index).and_then(|arg| match arg {
1502                         GenericArg::Lifetime(lt) => map.defs.get(&lt.hir_id).copied(),
1503                         _ => None,
1504                     })
1505                 }
1506                 ObjectLifetimeDefault::Ambiguous => None,
1507             };
1508             generics
1509                 .params
1510                 .iter()
1511                 .filter_map(|param| {
1512                     match self.tcx.def_kind(param.def_id) {
1513                         // Generic consts don't impose any constraints.
1514                         //
1515                         // We still store a dummy value here to allow generic parameters
1516                         // in an arbitrary order.
1517                         DefKind::ConstParam => Some(ObjectLifetimeDefault::Empty),
1518                         DefKind::TyParam => Some(self.tcx.object_lifetime_default(param.def_id)),
1519                         // We may also get a `Trait` or `TraitAlias` because of how generics `Self` parameter
1520                         // works.  Ignore it because it can't have a meaningful lifetime default.
1521                         DefKind::LifetimeParam | DefKind::Trait | DefKind::TraitAlias => None,
1522                         dk => bug!("unexpected def_kind {:?}", dk),
1523                     }
1524                 })
1525                 .map(set_to_region)
1526                 .collect()
1527         });
1528
1529         debug!(?object_lifetime_defaults);
1530
1531         let mut i = 0;
1532         for arg in generic_args.args {
1533             match arg {
1534                 GenericArg::Lifetime(_) => {}
1535                 GenericArg::Type(ty) => {
1536                     if let Some(&lt) = object_lifetime_defaults.get(i) {
1537                         let scope = Scope::ObjectLifetimeDefault { lifetime: lt, s: self.scope };
1538                         self.with(scope, |this| this.visit_ty(ty));
1539                     } else {
1540                         self.visit_ty(ty);
1541                     }
1542                     i += 1;
1543                 }
1544                 GenericArg::Const(ct) => {
1545                     self.visit_anon_const(&ct.value);
1546                     i += 1;
1547                 }
1548                 GenericArg::Infer(inf) => {
1549                     self.visit_id(inf.hir_id);
1550                     i += 1;
1551                 }
1552             }
1553         }
1554
1555         // Hack: when resolving the type `XX` in binding like `dyn
1556         // Foo<'b, Item = XX>`, the current object-lifetime default
1557         // would be to examine the trait `Foo` to check whether it has
1558         // a lifetime bound declared on `Item`. e.g., if `Foo` is
1559         // declared like so, then the default object lifetime bound in
1560         // `XX` should be `'b`:
1561         //
1562         // ```rust
1563         // trait Foo<'a> {
1564         //   type Item: 'a;
1565         // }
1566         // ```
1567         //
1568         // but if we just have `type Item;`, then it would be
1569         // `'static`. However, we don't get all of this logic correct.
1570         //
1571         // Instead, we do something hacky: if there are no lifetime parameters
1572         // to the trait, then we simply use a default object lifetime
1573         // bound of `'static`, because there is no other possibility. On the other hand,
1574         // if there ARE lifetime parameters, then we require the user to give an
1575         // explicit bound for now.
1576         //
1577         // This is intended to leave room for us to implement the
1578         // correct behavior in the future.
1579         let has_lifetime_parameter =
1580             generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)));
1581
1582         // Resolve lifetimes found in the bindings, so either in the type `XX` in `Item = XX` or
1583         // in the trait ref `YY<...>` in `Item: YY<...>`.
1584         for binding in generic_args.bindings {
1585             let scope = Scope::ObjectLifetimeDefault {
1586                 lifetime: if has_lifetime_parameter { None } else { Some(Region::Static) },
1587                 s: self.scope,
1588             };
1589             if let Some(type_def_id) = type_def_id {
1590                 let lifetimes = LifetimeContext::supertrait_hrtb_lifetimes(
1591                     self.tcx,
1592                     type_def_id,
1593                     binding.ident,
1594                 );
1595                 self.with(scope, |this| {
1596                     let scope = Scope::Supertrait {
1597                         lifetimes: lifetimes.unwrap_or_default(),
1598                         s: this.scope,
1599                     };
1600                     this.with(scope, |this| this.visit_assoc_type_binding(binding));
1601                 });
1602             } else {
1603                 self.with(scope, |this| this.visit_assoc_type_binding(binding));
1604             }
1605         }
1606     }
1607
1608     /// Returns all the late-bound vars that come into scope from supertrait HRTBs, based on the
1609     /// associated type name and starting trait.
1610     /// For example, imagine we have
1611     /// ```ignore (illustrative)
1612     /// trait Foo<'a, 'b> {
1613     ///   type As;
1614     /// }
1615     /// trait Bar<'b>: for<'a> Foo<'a, 'b> {}
1616     /// trait Bar: for<'b> Bar<'b> {}
1617     /// ```
1618     /// In this case, if we wanted to the supertrait HRTB lifetimes for `As` on
1619     /// the starting trait `Bar`, we would return `Some(['b, 'a])`.
1620     fn supertrait_hrtb_lifetimes(
1621         tcx: TyCtxt<'tcx>,
1622         def_id: DefId,
1623         assoc_name: Ident,
1624     ) -> Option<Vec<ty::BoundVariableKind>> {
1625         let trait_defines_associated_type_named = |trait_def_id: DefId| {
1626             tcx.associated_items(trait_def_id)
1627                 .find_by_name_and_kind(tcx, assoc_name, ty::AssocKind::Type, trait_def_id)
1628                 .is_some()
1629         };
1630
1631         use smallvec::{smallvec, SmallVec};
1632         let mut stack: SmallVec<[(DefId, SmallVec<[ty::BoundVariableKind; 8]>); 8]> =
1633             smallvec![(def_id, smallvec![])];
1634         let mut visited: FxHashSet<DefId> = FxHashSet::default();
1635         loop {
1636             let Some((def_id, bound_vars)) = stack.pop() else {
1637                 break None;
1638             };
1639             // See issue #83753. If someone writes an associated type on a non-trait, just treat it as
1640             // there being no supertrait HRTBs.
1641             match tcx.def_kind(def_id) {
1642                 DefKind::Trait | DefKind::TraitAlias | DefKind::Impl => {}
1643                 _ => break None,
1644             }
1645
1646             if trait_defines_associated_type_named(def_id) {
1647                 break Some(bound_vars.into_iter().collect());
1648             }
1649             let predicates =
1650                 tcx.super_predicates_that_define_assoc_type((def_id, Some(assoc_name)));
1651             let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| {
1652                 let bound_predicate = pred.kind();
1653                 match bound_predicate.skip_binder() {
1654                     ty::PredicateKind::Trait(data) => {
1655                         // The order here needs to match what we would get from `subst_supertrait`
1656                         let pred_bound_vars = bound_predicate.bound_vars();
1657                         let mut all_bound_vars = bound_vars.clone();
1658                         all_bound_vars.extend(pred_bound_vars.iter());
1659                         let super_def_id = data.trait_ref.def_id;
1660                         Some((super_def_id, all_bound_vars))
1661                     }
1662                     _ => None,
1663                 }
1664             });
1665
1666             let obligations = obligations.filter(|o| visited.insert(o.0));
1667             stack.extend(obligations);
1668         }
1669     }
1670
1671     #[instrument(level = "debug", skip(self))]
1672     fn visit_fn_like_elision(
1673         &mut self,
1674         inputs: &'tcx [hir::Ty<'tcx>],
1675         output: Option<&'tcx hir::Ty<'tcx>>,
1676         in_closure: bool,
1677     ) {
1678         self.with(Scope::Elision { s: self.scope }, |this| {
1679             for input in inputs {
1680                 this.visit_ty(input);
1681             }
1682             if !in_closure && let Some(output) = output {
1683                 this.visit_ty(output);
1684             }
1685         });
1686         if in_closure && let Some(output) = output {
1687             self.visit_ty(output);
1688         }
1689     }
1690
1691     fn resolve_object_lifetime_default(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
1692         debug!("resolve_object_lifetime_default(lifetime_ref={:?})", lifetime_ref);
1693         let mut late_depth = 0;
1694         let mut scope = self.scope;
1695         let lifetime = loop {
1696             match *scope {
1697                 Scope::Binder { s, scope_type, .. } => {
1698                     match scope_type {
1699                         BinderScopeType::Normal => late_depth += 1,
1700                         BinderScopeType::Concatenating => {}
1701                     }
1702                     scope = s;
1703                 }
1704
1705                 Scope::Root | Scope::Elision { .. } => break Region::Static,
1706
1707                 Scope::Body { .. } | Scope::ObjectLifetimeDefault { lifetime: None, .. } => return,
1708
1709                 Scope::ObjectLifetimeDefault { lifetime: Some(l), .. } => break l,
1710
1711                 Scope::Supertrait { s, .. } | Scope::TraitRefBoundary { s, .. } => {
1712                     scope = s;
1713                 }
1714             }
1715         };
1716         self.insert_lifetime(lifetime_ref, lifetime.shifted(late_depth));
1717     }
1718
1719     #[instrument(level = "debug", skip(self))]
1720     fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
1721         debug!(
1722             node = ?self.tcx.hir().node_to_string(lifetime_ref.hir_id),
1723             span = ?self.tcx.sess.source_map().span_to_diagnostic_string(lifetime_ref.span)
1724         );
1725         self.map.defs.insert(lifetime_ref.hir_id, def);
1726     }
1727
1728     /// Sometimes we resolve a lifetime, but later find that it is an
1729     /// error (esp. around impl trait). In that case, we remove the
1730     /// entry into `map.defs` so as not to confuse later code.
1731     fn uninsert_lifetime_on_error(&mut self, lifetime_ref: &'tcx hir::Lifetime, bad_def: Region) {
1732         let old_value = self.map.defs.remove(&lifetime_ref.hir_id);
1733         assert_eq!(old_value, Some(bad_def));
1734     }
1735 }
1736
1737 /// Detects late-bound lifetimes and inserts them into
1738 /// `late_bound`.
1739 ///
1740 /// A region declared on a fn is **late-bound** if:
1741 /// - it is constrained by an argument type;
1742 /// - it does not appear in a where-clause.
1743 ///
1744 /// "Constrained" basically means that it appears in any type but
1745 /// not amongst the inputs to a projection. In other words, `<&'a
1746 /// T as Trait<''b>>::Foo` does not constrain `'a` or `'b`.
1747 fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<LocalDefId>> {
1748     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
1749     let decl = tcx.hir().fn_decl_by_hir_id(hir_id)?;
1750     let generics = tcx.hir().get_generics(def_id)?;
1751
1752     let mut late_bound = FxIndexSet::default();
1753
1754     let mut constrained_by_input = ConstrainedCollector::default();
1755     for arg_ty in decl.inputs {
1756         constrained_by_input.visit_ty(arg_ty);
1757     }
1758
1759     let mut appears_in_output = AllCollector::default();
1760     intravisit::walk_fn_ret_ty(&mut appears_in_output, &decl.output);
1761
1762     debug!(?constrained_by_input.regions);
1763
1764     // Walk the lifetimes that appear in where clauses.
1765     //
1766     // Subtle point: because we disallow nested bindings, we can just
1767     // ignore binders here and scrape up all names we see.
1768     let mut appears_in_where_clause = AllCollector::default();
1769     appears_in_where_clause.visit_generics(generics);
1770     debug!(?appears_in_where_clause.regions);
1771
1772     // Late bound regions are those that:
1773     // - appear in the inputs
1774     // - do not appear in the where-clauses
1775     // - are not implicitly captured by `impl Trait`
1776     for param in generics.params {
1777         match param.kind {
1778             hir::GenericParamKind::Lifetime { .. } => { /* fall through */ }
1779
1780             // Neither types nor consts are late-bound.
1781             hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => continue,
1782         }
1783
1784         let param_def_id = tcx.hir().local_def_id(param.hir_id);
1785
1786         // appears in the where clauses? early-bound.
1787         if appears_in_where_clause.regions.contains(&param_def_id) {
1788             continue;
1789         }
1790
1791         // does not appear in the inputs, but appears in the return type? early-bound.
1792         if !constrained_by_input.regions.contains(&param_def_id)
1793             && appears_in_output.regions.contains(&param_def_id)
1794         {
1795             continue;
1796         }
1797
1798         debug!("lifetime {:?} with id {:?} is late-bound", param.name.ident(), param.hir_id);
1799
1800         let inserted = late_bound.insert(param_def_id);
1801         assert!(inserted, "visited lifetime {:?} twice", param.hir_id);
1802     }
1803
1804     debug!(?late_bound);
1805     return Some(tcx.arena.alloc(late_bound));
1806
1807     #[derive(Default)]
1808     struct ConstrainedCollector {
1809         regions: FxHashSet<LocalDefId>,
1810     }
1811
1812     impl<'v> Visitor<'v> for ConstrainedCollector {
1813         fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
1814             match ty.kind {
1815                 hir::TyKind::Path(
1816                     hir::QPath::Resolved(Some(_), _) | hir::QPath::TypeRelative(..),
1817                 ) => {
1818                     // ignore lifetimes appearing in associated type
1819                     // projections, as they are not *constrained*
1820                     // (defined above)
1821                 }
1822
1823                 hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => {
1824                     // consider only the lifetimes on the final
1825                     // segment; I am not sure it's even currently
1826                     // valid to have them elsewhere, but even if it
1827                     // is, those would be potentially inputs to
1828                     // projections
1829                     if let Some(last_segment) = path.segments.last() {
1830                         self.visit_path_segment(path.span, last_segment);
1831                     }
1832                 }
1833
1834                 _ => {
1835                     intravisit::walk_ty(self, ty);
1836                 }
1837             }
1838         }
1839
1840         fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
1841             if let hir::LifetimeName::Param(def_id, _) = lifetime_ref.name {
1842                 self.regions.insert(def_id);
1843             }
1844         }
1845     }
1846
1847     #[derive(Default)]
1848     struct AllCollector {
1849         regions: FxHashSet<LocalDefId>,
1850     }
1851
1852     impl<'v> Visitor<'v> for AllCollector {
1853         fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
1854             if let hir::LifetimeName::Param(def_id, _) = lifetime_ref.name {
1855                 self.regions.insert(def_id);
1856             }
1857         }
1858     }
1859 }