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