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