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