]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/resolve_lifetime.rs
Add an unstable FileTypeExt extension trait for Windows
[rust.git] / src / librustc / middle / resolve_lifetime.rs
1 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Name resolution for lifetimes.
12 //!
13 //! Name resolution for lifetimes follows MUCH simpler rules than the
14 //! full resolve. For example, lifetime names are never exported or
15 //! used between functions, and they operate in a purely top-down
16 //! way. Therefore we break lifetime name resolution into a separate pass.
17
18 use hir::map::Map;
19 use hir::def::Def;
20 use hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
21 use hir::ItemLocalId;
22 use ty::{self, TyCtxt};
23
24 use std::cell::Cell;
25 use std::mem::replace;
26 use std::rc::Rc;
27 use syntax::ast;
28 use syntax::attr;
29 use syntax::ptr::P;
30 use syntax_pos::Span;
31 use errors::DiagnosticBuilder;
32 use util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap, NodeSet};
33 use std::slice;
34 use rustc::lint;
35
36 use hir::{self, GenericParamsExt};
37 use hir::intravisit::{self, NestedVisitorMap, Visitor};
38
39 /// The origin of a named lifetime definition.
40 ///
41 /// This is used to prevent the usage of in-band lifetimes in `Fn`/`fn` syntax.
42 #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
43 pub enum LifetimeDefOrigin {
44     // Explicit binders like `fn foo<'a>(x: &'a u8)`
45     Explicit,
46     // In-band declarations like `fn foo(x: &'a u8)`
47     InBand,
48 }
49
50 impl LifetimeDefOrigin {
51     fn from_is_in_band(is_in_band: bool) -> Self {
52         if is_in_band {
53             LifetimeDefOrigin::InBand
54         } else {
55             LifetimeDefOrigin::Explicit
56         }
57     }
58 }
59
60 // This counts the no of times a lifetime is used
61 #[derive(Clone, Copy, Debug)]
62 pub enum LifetimeUseSet<'tcx> {
63     One(&'tcx hir::Lifetime),
64     Many,
65 }
66
67 #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
68 pub enum Region {
69     Static,
70     EarlyBound(
71         /* index */ u32,
72         /* lifetime decl */ DefId,
73         LifetimeDefOrigin,
74     ),
75     LateBound(
76         ty::DebruijnIndex,
77         /* lifetime decl */ DefId,
78         LifetimeDefOrigin,
79     ),
80     LateBoundAnon(ty::DebruijnIndex, /* anon index */ u32),
81     Free(DefId, /* lifetime decl */ DefId),
82 }
83
84 impl Region {
85     fn early(
86         hir_map: &Map,
87         index: &mut u32,
88         def: &hir::LifetimeDef,
89     ) -> (hir::LifetimeName, Region) {
90         let i = *index;
91         *index += 1;
92         let def_id = hir_map.local_def_id(def.lifetime.id);
93         let origin = LifetimeDefOrigin::from_is_in_band(def.in_band);
94         debug!("Region::early: index={} def_id={:?}", i, def_id);
95         (def.lifetime.name, Region::EarlyBound(i, def_id, origin))
96     }
97
98     fn late(hir_map: &Map, def: &hir::LifetimeDef) -> (hir::LifetimeName, Region) {
99         let depth = ty::DebruijnIndex::new(1);
100         let def_id = hir_map.local_def_id(def.lifetime.id);
101         let origin = LifetimeDefOrigin::from_is_in_band(def.in_band);
102         (def.lifetime.name, Region::LateBound(depth, def_id, origin))
103     }
104
105     fn late_anon(index: &Cell<u32>) -> Region {
106         let i = index.get();
107         index.set(i + 1);
108         let depth = ty::DebruijnIndex::new(1);
109         Region::LateBoundAnon(depth, i)
110     }
111
112     fn id(&self) -> Option<DefId> {
113         match *self {
114             Region::Static | Region::LateBoundAnon(..) => None,
115
116             Region::EarlyBound(_, id, _) | Region::LateBound(_, id, _) | Region::Free(_, id) => {
117                 Some(id)
118             }
119         }
120     }
121
122     fn shifted(self, amount: u32) -> Region {
123         match self {
124             Region::LateBound(depth, id, origin) => {
125                 Region::LateBound(depth.shifted(amount), id, origin)
126             }
127             Region::LateBoundAnon(depth, index) => {
128                 Region::LateBoundAnon(depth.shifted(amount), index)
129             }
130             _ => self,
131         }
132     }
133
134     fn from_depth(self, depth: u32) -> Region {
135         match self {
136             Region::LateBound(debruijn, id, origin) => Region::LateBound(
137                 ty::DebruijnIndex {
138                     depth: debruijn.depth - (depth - 1),
139                 },
140                 id,
141                 origin,
142             ),
143             Region::LateBoundAnon(debruijn, index) => Region::LateBoundAnon(
144                 ty::DebruijnIndex {
145                     depth: debruijn.depth - (depth - 1),
146                 },
147                 index,
148             ),
149             _ => self,
150         }
151     }
152
153     fn subst(self, params: &[hir::Lifetime], map: &NamedRegionMap) -> Option<Region> {
154         if let Region::EarlyBound(index, _, _) = self {
155             params
156                 .get(index as usize)
157                 .and_then(|lifetime| map.defs.get(&lifetime.id).cloned())
158         } else {
159             Some(self)
160         }
161     }
162 }
163
164 /// A set containing, at most, one known element.
165 /// If two distinct values are inserted into a set, then it
166 /// becomes `Many`, which can be used to detect ambiguities.
167 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
168 pub enum Set1<T> {
169     Empty,
170     One(T),
171     Many,
172 }
173
174 impl<T: PartialEq> Set1<T> {
175     pub fn insert(&mut self, value: T) {
176         if let Set1::Empty = *self {
177             *self = Set1::One(value);
178             return;
179         }
180         if let Set1::One(ref old) = *self {
181             if *old == value {
182                 return;
183             }
184         }
185         *self = Set1::Many;
186     }
187 }
188
189 pub type ObjectLifetimeDefault = Set1<Region>;
190
191 /// Maps the id of each lifetime reference to the lifetime decl
192 /// that it corresponds to.
193 ///
194 /// FIXME. This struct gets converted to a `ResolveLifetimes` for
195 /// actual use. It has the same data, but indexed by `DefIndex`.  This
196 /// is silly.
197 #[derive(Default)]
198 struct NamedRegionMap {
199     // maps from every use of a named (not anonymous) lifetime to a
200     // `Region` describing how that region is bound
201     pub defs: NodeMap<Region>,
202
203     // the set of lifetime def ids that are late-bound; a region can
204     // be late-bound if (a) it does NOT appear in a where-clause and
205     // (b) it DOES appear in the arguments.
206     pub late_bound: NodeSet,
207
208     // For each type and trait definition, maps type parameters
209     // to the trait object lifetime defaults computed from them.
210     pub object_lifetime_defaults: NodeMap<Vec<ObjectLifetimeDefault>>,
211 }
212
213 /// See `NamedRegionMap`.
214 pub struct ResolveLifetimes {
215     defs: FxHashMap<LocalDefId, Rc<FxHashMap<ItemLocalId, Region>>>,
216     late_bound: FxHashMap<LocalDefId, Rc<FxHashSet<ItemLocalId>>>,
217     object_lifetime_defaults:
218         FxHashMap<LocalDefId, Rc<FxHashMap<ItemLocalId, Rc<Vec<ObjectLifetimeDefault>>>>>,
219 }
220
221 impl_stable_hash_for!(struct ::middle::resolve_lifetime::ResolveLifetimes {
222     defs,
223     late_bound,
224     object_lifetime_defaults
225 });
226
227 struct LifetimeContext<'a, 'tcx: 'a> {
228     tcx: TyCtxt<'a, 'tcx, 'tcx>,
229     map: &'a mut NamedRegionMap,
230     scope: ScopeRef<'a>,
231     // Deep breath. Our representation for poly trait refs contains a single
232     // binder and thus we only allow a single level of quantification. However,
233     // the syntax of Rust permits quantification in two places, e.g., `T: for <'a> Foo<'a>`
234     // and `for <'a, 'b> &'b T: Foo<'a>`. In order to get the de Bruijn indices
235     // correct when representing these constraints, we should only introduce one
236     // scope. However, we want to support both locations for the quantifier and
237     // during lifetime resolution we want precise information (so we can't
238     // desugar in an earlier phase).
239
240     // SO, if we encounter a quantifier at the outer scope, we set
241     // trait_ref_hack to true (and introduce a scope), and then if we encounter
242     // a quantifier at the inner scope, we error. If trait_ref_hack is false,
243     // then we introduce the scope at the inner quantifier.
244
245     // I'm sorry.
246     trait_ref_hack: bool,
247
248     // Used to disallow the use of in-band lifetimes in `fn` or `Fn` syntax.
249     is_in_fn_syntax: bool,
250
251     // List of labels in the function/method currently under analysis.
252     labels_in_fn: Vec<(ast::Name, Span)>,
253
254     // Cache for cross-crate per-definition object lifetime defaults.
255     xcrate_object_lifetime_defaults: DefIdMap<Vec<ObjectLifetimeDefault>>,
256
257     lifetime_uses: DefIdMap<LifetimeUseSet<'tcx>>,
258 }
259
260 #[derive(Debug)]
261 enum Scope<'a> {
262     /// Declares lifetimes, and each can be early-bound or late-bound.
263     /// The `DebruijnIndex` of late-bound lifetimes starts at `1` and
264     /// it should be shifted by the number of `Binder`s in between the
265     /// declaration `Binder` and the location it's referenced from.
266     Binder {
267         lifetimes: FxHashMap<hir::LifetimeName, Region>,
268
269         /// if we extend this scope with another scope, what is the next index
270         /// we should use for an early-bound region?
271         next_early_index: u32,
272
273         s: ScopeRef<'a>,
274     },
275
276     /// Lifetimes introduced by a fn are scoped to the call-site for that fn,
277     /// if this is a fn body, otherwise the original definitions are used.
278     /// Unspecified lifetimes are inferred, unless an elision scope is nested,
279     /// e.g. `(&T, fn(&T) -> &T);` becomes `(&'_ T, for<'a> fn(&'a T) -> &'a T)`.
280     Body {
281         id: hir::BodyId,
282         s: ScopeRef<'a>,
283     },
284
285     /// A scope which either determines unspecified lifetimes or errors
286     /// on them (e.g. due to ambiguity). For more details, see `Elide`.
287     Elision {
288         elide: Elide,
289         s: ScopeRef<'a>,
290     },
291
292     /// Use a specific lifetime (if `Some`) or leave it unset (to be
293     /// inferred in a function body or potentially error outside one),
294     /// for the default choice of lifetime in a trait object type.
295     ObjectLifetimeDefault {
296         lifetime: Option<Region>,
297         s: ScopeRef<'a>,
298     },
299
300     Root,
301 }
302
303 #[derive(Clone, Debug)]
304 enum Elide {
305     /// Use a fresh anonymous late-bound lifetime each time, by
306     /// incrementing the counter to generate sequential indices.
307     FreshLateAnon(Cell<u32>),
308     /// Always use this one lifetime.
309     Exact(Region),
310     /// Less or more than one lifetime were found, error on unspecified.
311     Error(Vec<ElisionFailureInfo>),
312 }
313
314 #[derive(Clone, Debug)]
315 struct ElisionFailureInfo {
316     /// Where we can find the argument pattern.
317     parent: Option<hir::BodyId>,
318     /// The index of the argument in the original definition.
319     index: usize,
320     lifetime_count: usize,
321     have_bound_regions: bool,
322 }
323
324 type ScopeRef<'a> = &'a Scope<'a>;
325
326 const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root;
327
328 pub fn provide(providers: &mut ty::maps::Providers) {
329     *providers = ty::maps::Providers {
330         resolve_lifetimes,
331
332         named_region_map: |tcx, id| {
333             let id = LocalDefId::from_def_id(DefId::local(id)); // (*)
334             tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id).cloned()
335         },
336
337         is_late_bound_map: |tcx, id| {
338             let id = LocalDefId::from_def_id(DefId::local(id)); // (*)
339             tcx.resolve_lifetimes(LOCAL_CRATE)
340                 .late_bound
341                 .get(&id)
342                 .cloned()
343         },
344
345         object_lifetime_defaults_map: |tcx, id| {
346             let id = LocalDefId::from_def_id(DefId::local(id)); // (*)
347             tcx.resolve_lifetimes(LOCAL_CRATE)
348                 .object_lifetime_defaults
349                 .get(&id)
350                 .cloned()
351         },
352
353         ..*providers
354     };
355
356     // (*) FIXME the query should be defined to take a LocalDefId
357 }
358
359 /// Computes the `ResolveLifetimes` map that contains data for the
360 /// entire crate. You should not read the result of this query
361 /// directly, but rather use `named_region_map`, `is_late_bound_map`,
362 /// etc.
363 fn resolve_lifetimes<'tcx>(
364     tcx: TyCtxt<'_, 'tcx, 'tcx>,
365     for_krate: CrateNum,
366 ) -> Rc<ResolveLifetimes> {
367     assert_eq!(for_krate, LOCAL_CRATE);
368
369     let named_region_map = krate(tcx);
370
371     let mut defs = FxHashMap();
372     for (k, v) in named_region_map.defs {
373         let hir_id = tcx.hir.node_to_hir_id(k);
374         let map = defs.entry(hir_id.owner_local_def_id())
375             .or_insert_with(|| Rc::new(FxHashMap()));
376         Rc::get_mut(map).unwrap().insert(hir_id.local_id, v);
377     }
378     let mut late_bound = FxHashMap();
379     for k in named_region_map.late_bound {
380         let hir_id = tcx.hir.node_to_hir_id(k);
381         let map = late_bound
382             .entry(hir_id.owner_local_def_id())
383             .or_insert_with(|| Rc::new(FxHashSet()));
384         Rc::get_mut(map).unwrap().insert(hir_id.local_id);
385     }
386     let mut object_lifetime_defaults = FxHashMap();
387     for (k, v) in named_region_map.object_lifetime_defaults {
388         let hir_id = tcx.hir.node_to_hir_id(k);
389         let map = object_lifetime_defaults
390             .entry(hir_id.owner_local_def_id())
391             .or_insert_with(|| Rc::new(FxHashMap()));
392         Rc::get_mut(map)
393             .unwrap()
394             .insert(hir_id.local_id, Rc::new(v));
395     }
396
397     Rc::new(ResolveLifetimes {
398         defs,
399         late_bound,
400         object_lifetime_defaults,
401     })
402 }
403
404 fn krate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> NamedRegionMap {
405     let krate = tcx.hir.krate();
406     let mut map = NamedRegionMap {
407         defs: NodeMap(),
408         late_bound: NodeSet(),
409         object_lifetime_defaults: compute_object_lifetime_defaults(tcx),
410     };
411     {
412         let mut visitor = LifetimeContext {
413             tcx,
414             map: &mut map,
415             scope: ROOT_SCOPE,
416             trait_ref_hack: false,
417             is_in_fn_syntax: false,
418             labels_in_fn: vec![],
419             xcrate_object_lifetime_defaults: DefIdMap(),
420             lifetime_uses: DefIdMap(),
421         };
422         for (_, item) in &krate.items {
423             visitor.visit_item(item);
424         }
425     }
426     map
427 }
428
429 impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
430     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
431         NestedVisitorMap::All(&self.tcx.hir)
432     }
433
434     // We want to nest trait/impl items in their parent, but nothing else.
435     fn visit_nested_item(&mut self, _: hir::ItemId) {}
436
437     fn visit_nested_body(&mut self, body: hir::BodyId) {
438         // Each body has their own set of labels, save labels.
439         let saved = replace(&mut self.labels_in_fn, vec![]);
440         let body = self.tcx.hir.body(body);
441         extract_labels(self, body);
442         self.with(
443             Scope::Body {
444                 id: body.id(),
445                 s: self.scope,
446             },
447             |_, this| {
448                 this.visit_body(body);
449             },
450         );
451         replace(&mut self.labels_in_fn, saved);
452     }
453
454     fn visit_item(&mut self, item: &'tcx hir::Item) {
455         match item.node {
456             hir::ItemFn(ref decl, _, _, _, ref generics, _) => {
457                 self.visit_early_late(None,
458                                       decl,
459                                       generics,
460                                       |this| {
461                                           intravisit::walk_item(this, item);
462                 });
463             }
464
465             hir::ItemExternCrate(_)
466             | hir::ItemUse(..)
467             | hir::ItemMod(..)
468             | hir::ItemForeignMod(..)
469             | hir::ItemGlobalAsm(..) => {
470                 // These sorts of items have no lifetime parameters at all.
471                 intravisit::walk_item(self, item);
472             }
473             hir::ItemStatic(..) | hir::ItemConst(..) => {
474                 // No lifetime parameters, but implied 'static.
475                 let scope = Scope::Elision {
476                     elide: Elide::Exact(Region::Static),
477                     s: ROOT_SCOPE,
478                 };
479                 self.with(scope, |_, this| intravisit::walk_item(this, item));
480             }
481             hir::ItemTy(_, ref generics)
482             | hir::ItemEnum(_, ref generics)
483             | hir::ItemStruct(_, ref generics)
484             | hir::ItemUnion(_, ref generics)
485             | hir::ItemTrait(_, _, ref generics, ..)
486             | hir::ItemTraitAlias(ref generics, ..)
487             | hir::ItemImpl(_, _, _, ref generics, ..) => {
488                 // These kinds of items have only early bound lifetime parameters.
489                 let mut index = if let hir::ItemTrait(..) = item.node {
490                     1 // Self comes before lifetimes
491                 } else {
492                     0
493                 };
494                 let lifetimes = generics.lifetimes()
495                     .map(|def| Region::early(&self.tcx.hir, &mut index, def))
496                     .collect();
497                 let next_early_index = index + generics.ty_params().count() as u32;
498                 let scope = Scope::Binder {
499                     lifetimes,
500                     next_early_index,
501                     s: ROOT_SCOPE,
502                 };
503                 self.with(scope, |old_scope, this| {
504                     this.check_lifetime_params(old_scope, &generics.params);
505                     intravisit::walk_item(this, item);
506                 });
507             }
508         }
509     }
510
511     fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem) {
512         match item.node {
513             hir::ForeignItemFn(ref decl, _, ref generics) => {
514                 self.visit_early_late(None,
515                                       decl,
516                                       generics,
517                                       |this| {
518                                           intravisit::walk_foreign_item(this, item);
519                                       })
520             }
521             hir::ForeignItemStatic(..) => {
522                 intravisit::walk_foreign_item(self, item);
523             }
524             hir::ForeignItemType => {
525                 intravisit::walk_foreign_item(self, item);
526             }
527         }
528     }
529
530     fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
531         debug!("visit_ty: ty={:?}", ty);
532         match ty.node {
533             hir::TyBareFn(ref c) => {
534                 let next_early_index = self.next_early_index();
535                 let was_in_fn_syntax = self.is_in_fn_syntax;
536                 self.is_in_fn_syntax = true;
537                 let scope = Scope::Binder {
538                     lifetimes: c.generic_params
539                         .lifetimes()
540                         .map(|def| Region::late(&self.tcx.hir, def))
541                         .collect(),
542                     s: self.scope,
543                     next_early_index,
544                 };
545                 self.with(scope, |old_scope, this| {
546                     // a bare fn has no bounds, so everything
547                     // contained within is scoped within its binder.
548                     this.check_lifetime_params(old_scope, &c.generic_params);
549                     intravisit::walk_ty(this, ty);
550                 });
551                 self.is_in_fn_syntax = was_in_fn_syntax;
552             }
553             hir::TyTraitObject(ref bounds, ref lifetime) => {
554                 for bound in bounds {
555                     self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None);
556                 }
557                 if lifetime.is_elided() {
558                     self.resolve_object_lifetime_default(lifetime)
559                 } else {
560                     self.visit_lifetime(lifetime);
561                 }
562             }
563             hir::TyRptr(ref lifetime_ref, ref mt) => {
564                 self.visit_lifetime(lifetime_ref);
565                 let scope = Scope::ObjectLifetimeDefault {
566                     lifetime: self.map.defs.get(&lifetime_ref.id).cloned(),
567                     s: self.scope,
568                 };
569                 self.with(scope, |_, this| this.visit_ty(&mt.ty));
570             }
571             hir::TyImplTraitExistential(ref exist_ty, ref lifetimes) => {
572                 // Resolve the lifetimes that are applied to the existential type.
573                 // These are resolved in the current scope.
574                 // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
575                 // `fn foo<'a>() -> MyAnonTy<'a> { ... }`
576                 //          ^                 ^this gets resolved in the current scope
577                 for lifetime in lifetimes {
578                     self.visit_lifetime(lifetime);
579
580                     // Check for predicates like `impl for<'a> SomeTrait<impl OtherTrait<'a>>`
581                     // and ban them. Type variables instantiated inside binders aren't
582                     // well-supported at the moment, so this doesn't work.
583                     // In the future, this should be fixed and this error should be removed.
584                     let def = self.map.defs.get(&lifetime.id);
585                     if let Some(&Region::LateBound(_, def_id, _)) = def {
586                         if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
587                             // Ensure that the parent of the def is an item, not HRTB
588                             let parent_id = self.tcx.hir.get_parent_node(node_id);
589                             let parent_impl_id = hir::ImplItemId { node_id: parent_id };
590                             let parent_trait_id = hir::TraitItemId { node_id: parent_id };
591                             let krate = self.tcx.hir.forest.krate();
592                             if !(krate.items.contains_key(&parent_id)
593                                 || krate.impl_items.contains_key(&parent_impl_id)
594                                 || krate.trait_items.contains_key(&parent_trait_id))
595                             {
596                                 span_err!(
597                                     self.tcx.sess,
598                                     lifetime.span,
599                                     E0657,
600                                     "`impl Trait` can only capture lifetimes \
601                                      bound at the fn or impl level"
602                                 );
603                             }
604                         }
605                     }
606                 }
607
608                 // Resolve the lifetimes in the bounds to the lifetime defs in the generics.
609                 // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
610                 // `abstract type MyAnonTy<'b>: MyTrait<'b>;`
611                 //                          ^            ^ this gets resolved in the scope of
612                 //                                         the exist_ty generics
613                 let hir::ExistTy {
614                     ref generics,
615                     ref bounds,
616                 } = *exist_ty;
617                 let mut index = self.next_early_index();
618                 debug!("visit_ty: index = {}", index);
619
620                 let mut elision = None;
621                 let mut lifetimes = FxHashMap();
622                 for lt_def in generics.lifetimes() {
623                     let (lt_name, region) = Region::early(&self.tcx.hir, &mut index, &lt_def);
624                     if let hir::LifetimeName::Underscore = lt_name {
625                         // Pick the elided lifetime "definition" if one exists and use it to make an
626                         // elision scope.
627                         elision = Some(region);
628                     } else {
629                         lifetimes.insert(lt_name, region);
630                     }
631                 }
632
633                 let next_early_index = index + generics.ty_params().count() as u32;
634
635                 if let Some(elision_region) = elision {
636                     let scope = Scope::Elision {
637                         elide: Elide::Exact(elision_region),
638                         s: self.scope
639                     };
640                     self.with(scope, |_old_scope, this| {
641                         let scope = Scope::Binder { lifetimes, next_early_index, s: this.scope };
642                         this.with(scope, |_old_scope, this| {
643                             this.visit_generics(generics);
644                             for bound in bounds {
645                                 this.visit_ty_param_bound(bound);
646                             }
647                         });
648                     });
649                 } else {
650                     let scope = Scope::Binder { lifetimes, next_early_index, s: self.scope };
651                     self.with(scope, |_old_scope, this| {
652                         this.visit_generics(generics);
653                         for bound in bounds {
654                             this.visit_ty_param_bound(bound);
655                         }
656                     });
657                 }
658             }
659             _ => intravisit::walk_ty(self, ty),
660         }
661     }
662
663     fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
664         use self::hir::TraitItemKind::*;
665         match trait_item.node {
666             Method(ref sig, _) => {
667                 let tcx = self.tcx;
668                 self.visit_early_late(
669                     Some(tcx.hir.get_parent(trait_item.id)),
670                     &sig.decl,
671                     &trait_item.generics,
672                     |this| intravisit::walk_trait_item(this, trait_item),
673                 );
674             },
675             Type(ref bounds, ref ty) => {
676                 let generics = &trait_item.generics;
677                 let mut index = self.next_early_index();
678                 debug!("visit_ty: index = {}", index);
679                 let lifetimes = generics.lifetimes()
680                     .map(|lt_def| Region::early(&self.tcx.hir, &mut index, lt_def))
681                     .collect();
682
683                 let next_early_index = index + generics.ty_params().count() as u32;
684                 let scope = Scope::Binder { lifetimes, next_early_index, s: self.scope };
685                 self.with(scope, |_old_scope, this| {
686                     this.visit_generics(generics);
687                     for bound in bounds {
688                         this.visit_ty_param_bound(bound);
689                     }
690                     if let Some(ty) = ty {
691                         this.visit_ty(ty);
692                     }
693                 });
694             },
695             Const(_, _) => {
696                 // Only methods and types support generics.
697                 assert!(trait_item.generics.params.is_empty());
698                 intravisit::walk_trait_item(self, trait_item);
699             },
700         }
701     }
702
703     fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
704         use self::hir::ImplItemKind::*;
705         match impl_item.node {
706             Method(ref sig, _) => {
707                 let tcx = self.tcx;
708                 self.visit_early_late(
709                     Some(tcx.hir.get_parent(impl_item.id)),
710                     &sig.decl,
711                     &impl_item.generics,
712                     |this| intravisit::walk_impl_item(this, impl_item),
713                 )
714             },
715             Type(ref ty) => {
716                 let generics = &impl_item.generics;
717                 let mut index = self.next_early_index();
718                 debug!("visit_ty: index = {}", index);
719                 let lifetimes = generics.lifetimes()
720                     .map(|lt_def| Region::early(&self.tcx.hir, &mut index, lt_def))
721                     .collect();
722
723                 let next_early_index = index + generics.ty_params().count() as u32;
724                 let scope = Scope::Binder { lifetimes, next_early_index, s: self.scope };
725                 self.with(scope, |_old_scope, this| {
726                     this.visit_generics(generics);
727                     this.visit_ty(ty);
728                 });
729             },
730             Const(_, _) => {
731                 // Only methods and types support generics.
732                 assert!(impl_item.generics.params.is_empty());
733                 intravisit::walk_impl_item(self, impl_item);
734             },
735         }
736     }
737
738     fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
739         if lifetime_ref.is_elided() {
740             self.resolve_elided_lifetimes(slice::from_ref(lifetime_ref));
741             return;
742         }
743         if lifetime_ref.is_static() {
744             self.insert_lifetime(lifetime_ref, Region::Static);
745             return;
746         }
747         self.resolve_lifetime_ref(lifetime_ref);
748     }
749
750     fn visit_path(&mut self, path: &'tcx hir::Path, _: ast::NodeId) {
751         for (i, segment) in path.segments.iter().enumerate() {
752             let depth = path.segments.len() - i - 1;
753             if let Some(ref parameters) = segment.parameters {
754                 self.visit_segment_parameters(path.def, depth, parameters);
755             }
756         }
757     }
758
759     fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl) {
760         let output = match fd.output {
761             hir::DefaultReturn(_) => None,
762             hir::Return(ref ty) => Some(ty),
763         };
764         self.visit_fn_like_elision(&fd.inputs, output);
765     }
766
767     fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
768         check_mixed_explicit_and_in_band_defs(
769             self.tcx,
770             &generics.lifetimes().cloned().collect::<Vec<_>>()
771         );
772         for ty_param in generics.ty_params() {
773             walk_list!(self, visit_ty_param_bound, &ty_param.bounds);
774             if let Some(ref ty) = ty_param.default {
775                 self.visit_ty(&ty);
776             }
777         }
778         for predicate in &generics.where_clause.predicates {
779             match predicate {
780                 &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
781                     ref bounded_ty,
782                     ref bounds,
783                     ref bound_generic_params,
784                     ..
785                 }) => {
786                     if bound_generic_params.iter().any(|p| p.is_lifetime_param()) {
787                         self.trait_ref_hack = true;
788                         let next_early_index = self.next_early_index();
789                         let scope = Scope::Binder {
790                             lifetimes: bound_generic_params.lifetimes()
791                                 .map(|def| Region::late(&self.tcx.hir, def))
792                                 .collect(),
793                             s: self.scope,
794                             next_early_index,
795                         };
796                         let result = self.with(scope, |old_scope, this| {
797                             this.check_lifetime_params(old_scope, &bound_generic_params);
798                             this.visit_ty(&bounded_ty);
799                             walk_list!(this, visit_ty_param_bound, bounds);
800                         });
801                         self.trait_ref_hack = false;
802                         result
803                     } else {
804                         self.visit_ty(&bounded_ty);
805                         walk_list!(self, visit_ty_param_bound, bounds);
806                     }
807                 }
808                 &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
809                     ref lifetime,
810                     ref bounds,
811                     ..
812                 }) => {
813                     self.visit_lifetime(lifetime);
814                     for bound in bounds {
815                         self.visit_lifetime(bound);
816                     }
817                 }
818                 &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
819                     ref lhs_ty,
820                     ref rhs_ty,
821                     ..
822                 }) => {
823                     self.visit_ty(lhs_ty);
824                     self.visit_ty(rhs_ty);
825                 }
826             }
827         }
828     }
829
830     fn visit_poly_trait_ref(
831         &mut self,
832         trait_ref: &'tcx hir::PolyTraitRef,
833         _modifier: hir::TraitBoundModifier,
834     ) {
835         debug!("visit_poly_trait_ref trait_ref={:?}", trait_ref);
836
837         if !self.trait_ref_hack ||
838             trait_ref.bound_generic_params.iter().any(|p| p.is_lifetime_param())
839         {
840             if self.trait_ref_hack {
841                 span_err!(
842                     self.tcx.sess,
843                     trait_ref.span,
844                     E0316,
845                     "nested quantification of lifetimes"
846                 );
847             }
848             let next_early_index = self.next_early_index();
849             let scope = Scope::Binder {
850                 lifetimes: trait_ref.bound_generic_params
851                     .lifetimes()
852                     .map(|def| Region::late(&self.tcx.hir, def))
853                     .collect(),
854                 s: self.scope,
855                 next_early_index,
856             };
857             self.with(scope, |old_scope, this| {
858                 this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params);
859                 walk_list!(this, visit_generic_param, &trait_ref.bound_generic_params);
860                 this.visit_trait_ref(&trait_ref.trait_ref)
861             })
862         } else {
863             self.visit_trait_ref(&trait_ref.trait_ref)
864         }
865     }
866 }
867
868 #[derive(Copy, Clone, PartialEq)]
869 enum ShadowKind {
870     Label,
871     Lifetime,
872 }
873 struct Original {
874     kind: ShadowKind,
875     span: Span,
876 }
877 struct Shadower {
878     kind: ShadowKind,
879     span: Span,
880 }
881
882 fn original_label(span: Span) -> Original {
883     Original {
884         kind: ShadowKind::Label,
885         span: span,
886     }
887 }
888 fn shadower_label(span: Span) -> Shadower {
889     Shadower {
890         kind: ShadowKind::Label,
891         span: span,
892     }
893 }
894 fn original_lifetime(span: Span) -> Original {
895     Original {
896         kind: ShadowKind::Lifetime,
897         span: span,
898     }
899 }
900 fn shadower_lifetime(l: &hir::Lifetime) -> Shadower {
901     Shadower {
902         kind: ShadowKind::Lifetime,
903         span: l.span,
904     }
905 }
906
907 impl ShadowKind {
908     fn desc(&self) -> &'static str {
909         match *self {
910             ShadowKind::Label => "label",
911             ShadowKind::Lifetime => "lifetime",
912         }
913     }
914 }
915
916 fn check_mixed_explicit_and_in_band_defs(
917     tcx: TyCtxt<'_, '_, '_>,
918     lifetime_defs: &[hir::LifetimeDef],
919 ) {
920     let oob_def = lifetime_defs.iter().find(|lt| !lt.in_band);
921     let in_band_def = lifetime_defs.iter().find(|lt| lt.in_band);
922
923     if let (Some(oob_def), Some(in_band_def)) = (oob_def, in_band_def) {
924         struct_span_err!(
925             tcx.sess,
926             in_band_def.lifetime.span,
927             E0688,
928             "cannot mix in-band and explicit lifetime definitions"
929         ).span_label(
930             in_band_def.lifetime.span,
931             "in-band lifetime definition here",
932         )
933             .span_label(oob_def.lifetime.span, "explicit lifetime definition here")
934             .emit();
935     }
936 }
937
938 fn signal_shadowing_problem(
939     tcx: TyCtxt<'_, '_, '_>,
940     name: ast::Name,
941     orig: Original,
942     shadower: Shadower,
943 ) {
944     let mut err = if let (ShadowKind::Lifetime, ShadowKind::Lifetime) = (orig.kind, shadower.kind) {
945         // lifetime/lifetime shadowing is an error
946         struct_span_err!(
947             tcx.sess,
948             shadower.span,
949             E0496,
950             "{} name `{}` shadows a \
951              {} name that is already in scope",
952             shadower.kind.desc(),
953             name,
954             orig.kind.desc()
955         )
956     } else {
957         // shadowing involving a label is only a warning, due to issues with
958         // labels and lifetimes not being macro-hygienic.
959         tcx.sess.struct_span_warn(
960             shadower.span,
961             &format!(
962                 "{} name `{}` shadows a \
963                  {} name that is already in scope",
964                 shadower.kind.desc(),
965                 name,
966                 orig.kind.desc()
967             ),
968         )
969     };
970     err.span_label(orig.span, "first declared here");
971     err.span_label(shadower.span, format!("lifetime {} already in scope", name));
972     err.emit();
973 }
974
975 // Adds all labels in `b` to `ctxt.labels_in_fn`, signalling a warning
976 // if one of the label shadows a lifetime or another label.
977 fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body) {
978     struct GatherLabels<'a, 'tcx: 'a> {
979         tcx: TyCtxt<'a, 'tcx, 'tcx>,
980         scope: ScopeRef<'a>,
981         labels_in_fn: &'a mut Vec<(ast::Name, Span)>,
982     }
983
984     let mut gather = GatherLabels {
985         tcx: ctxt.tcx,
986         scope: ctxt.scope,
987         labels_in_fn: &mut ctxt.labels_in_fn,
988     };
989     gather.visit_body(body);
990
991     impl<'v, 'a, 'tcx> Visitor<'v> for GatherLabels<'a, 'tcx> {
992         fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
993             NestedVisitorMap::None
994         }
995
996         fn visit_expr(&mut self, ex: &hir::Expr) {
997             if let Some((label, label_span)) = expression_label(ex) {
998                 for &(prior, prior_span) in &self.labels_in_fn[..] {
999                     // FIXME (#24278): non-hygienic comparison
1000                     if label == prior {
1001                         signal_shadowing_problem(
1002                             self.tcx,
1003                             label,
1004                             original_label(prior_span),
1005                             shadower_label(label_span),
1006                         );
1007                     }
1008                 }
1009
1010                 check_if_label_shadows_lifetime(self.tcx, self.scope, label, label_span);
1011
1012                 self.labels_in_fn.push((label, label_span));
1013             }
1014             intravisit::walk_expr(self, ex)
1015         }
1016     }
1017
1018     fn expression_label(ex: &hir::Expr) -> Option<(ast::Name, Span)> {
1019         match ex.node {
1020             hir::ExprWhile(.., Some(label)) | hir::ExprLoop(_, Some(label), _) => {
1021                 Some((label.name, label.span))
1022             }
1023             _ => None,
1024         }
1025     }
1026
1027     fn check_if_label_shadows_lifetime(
1028         tcx: TyCtxt<'_, '_, '_>,
1029         mut scope: ScopeRef<'_>,
1030         label: ast::Name,
1031         label_span: Span,
1032     ) {
1033         loop {
1034             match *scope {
1035                 Scope::Body { s, .. }
1036                 | Scope::Elision { s, .. }
1037                 | Scope::ObjectLifetimeDefault { s, .. } => {
1038                     scope = s;
1039                 }
1040
1041                 Scope::Root => {
1042                     return;
1043                 }
1044
1045                 Scope::Binder {
1046                     ref lifetimes,
1047                     s,
1048                     next_early_index: _,
1049                 } => {
1050                     // FIXME (#24278): non-hygienic comparison
1051                     if let Some(def) = lifetimes.get(&hir::LifetimeName::Name(label)) {
1052                         let node_id = tcx.hir.as_local_node_id(def.id().unwrap()).unwrap();
1053
1054                         signal_shadowing_problem(
1055                             tcx,
1056                             label,
1057                             original_lifetime(tcx.hir.span(node_id)),
1058                             shadower_label(label_span),
1059                         );
1060                         return;
1061                     }
1062                     scope = s;
1063                 }
1064             }
1065         }
1066     }
1067 }
1068
1069 fn compute_object_lifetime_defaults(
1070     tcx: TyCtxt<'_, '_, '_>,
1071 ) -> NodeMap<Vec<ObjectLifetimeDefault>> {
1072     let mut map = NodeMap();
1073     for item in tcx.hir.krate().items.values() {
1074         match item.node {
1075             hir::ItemStruct(_, ref generics)
1076             | hir::ItemUnion(_, ref generics)
1077             | hir::ItemEnum(_, ref generics)
1078             | hir::ItemTy(_, ref generics)
1079             | hir::ItemTrait(_, _, ref generics, ..) => {
1080                 let result = object_lifetime_defaults_for_item(tcx, generics);
1081
1082                 // Debugging aid.
1083                 if attr::contains_name(&item.attrs, "rustc_object_lifetime_default") {
1084                     let object_lifetime_default_reprs: String = result
1085                         .iter()
1086                         .map(|set| match *set {
1087                             Set1::Empty => "BaseDefault".to_string(),
1088                             Set1::One(Region::Static) => "'static".to_string(),
1089                             Set1::One(Region::EarlyBound(i, _, _)) => generics.lifetimes()
1090                                 .nth(i as usize)
1091                                 .unwrap()
1092                                 .lifetime
1093                                 .name
1094                                 .name()
1095                                 .to_string(),
1096                             Set1::One(_) => bug!(),
1097                             Set1::Many => "Ambiguous".to_string(),
1098                         })
1099                         .collect::<Vec<String>>()
1100                         .join(",");
1101                     tcx.sess.span_err(item.span, &object_lifetime_default_reprs);
1102                 }
1103
1104                 map.insert(item.id, result);
1105             }
1106             _ => {}
1107         }
1108     }
1109     map
1110 }
1111
1112 /// Scan the bounds and where-clauses on parameters to extract bounds
1113 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
1114 /// for each type parameter.
1115 fn object_lifetime_defaults_for_item(
1116     tcx: TyCtxt<'_, '_, '_>,
1117     generics: &hir::Generics,
1118 ) -> Vec<ObjectLifetimeDefault> {
1119     fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::TyParamBound]) {
1120         for bound in bounds {
1121             if let hir::RegionTyParamBound(ref lifetime) = *bound {
1122                 set.insert(lifetime.name);
1123             }
1124         }
1125     }
1126
1127     generics.ty_params()
1128         .map(|param| {
1129             let mut set = Set1::Empty;
1130
1131             add_bounds(&mut set, &param.bounds);
1132
1133             let param_def_id = tcx.hir.local_def_id(param.id);
1134             for predicate in &generics.where_clause.predicates {
1135                 // Look for `type: ...` where clauses.
1136                 let data = match *predicate {
1137                     hir::WherePredicate::BoundPredicate(ref data) => data,
1138                     _ => continue,
1139                 };
1140
1141                 // Ignore `for<'a> type: ...` as they can change what
1142                 // lifetimes mean (although we could "just" handle it).
1143                 if !data.bound_generic_params.is_empty() {
1144                     continue;
1145                 }
1146
1147                 let def = match data.bounded_ty.node {
1148                     hir::TyPath(hir::QPath::Resolved(None, ref path)) => path.def,
1149                     _ => continue,
1150                 };
1151
1152                 if def == Def::TyParam(param_def_id) {
1153                     add_bounds(&mut set, &data.bounds);
1154                 }
1155             }
1156
1157             match set {
1158                 Set1::Empty => Set1::Empty,
1159                 Set1::One(name) => {
1160                     if name == hir::LifetimeName::Static {
1161                         Set1::One(Region::Static)
1162                     } else {
1163                         generics
1164                             .lifetimes()
1165                             .enumerate()
1166                             .find(|&(_, def)| def.lifetime.name == name)
1167                             .map_or(Set1::Many, |(i, def)| {
1168                                 let def_id = tcx.hir.local_def_id(def.lifetime.id);
1169                                 let origin = LifetimeDefOrigin::from_is_in_band(def.in_band);
1170                                 Set1::One(Region::EarlyBound(i as u32, def_id, origin))
1171                             })
1172                     }
1173                 }
1174                 Set1::Many => Set1::Many,
1175             }
1176         })
1177         .collect()
1178 }
1179
1180 impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
1181     // FIXME(#37666) this works around a limitation in the region inferencer
1182     fn hack<F>(&mut self, f: F)
1183     where
1184         F: for<'b> FnOnce(&mut LifetimeContext<'b, 'tcx>),
1185     {
1186         f(self)
1187     }
1188
1189     fn with<F>(&mut self, wrap_scope: Scope, f: F)
1190     where
1191         F: for<'b> FnOnce(ScopeRef, &mut LifetimeContext<'b, 'tcx>),
1192     {
1193         let LifetimeContext {
1194             tcx, ref mut map, ..
1195         } = *self;
1196         let labels_in_fn = replace(&mut self.labels_in_fn, vec![]);
1197         let xcrate_object_lifetime_defaults =
1198             replace(&mut self.xcrate_object_lifetime_defaults, DefIdMap());
1199         let mut this = LifetimeContext {
1200             tcx,
1201             map: *map,
1202             scope: &wrap_scope,
1203             trait_ref_hack: self.trait_ref_hack,
1204             is_in_fn_syntax: self.is_in_fn_syntax,
1205             labels_in_fn,
1206             xcrate_object_lifetime_defaults,
1207             lifetime_uses: DefIdMap(),
1208         };
1209         debug!("entering scope {:?}", this.scope);
1210         f(self.scope, &mut this);
1211         debug!("exiting scope {:?}", this.scope);
1212         self.labels_in_fn = this.labels_in_fn;
1213         self.xcrate_object_lifetime_defaults = this.xcrate_object_lifetime_defaults;
1214
1215         for (def_id, lifetimeuseset) in &this.lifetime_uses {
1216             match lifetimeuseset {
1217                 &LifetimeUseSet::One(_) => {
1218                     let node_id = this.tcx.hir.as_local_node_id(*def_id).unwrap();
1219                     debug!("node id first={:?}", node_id);
1220                     if let hir::map::NodeLifetime(hir_lifetime) = this.tcx.hir.get(node_id) {
1221                         let span = hir_lifetime.span;
1222                         let id = hir_lifetime.id;
1223                         debug!("id ={:?} span = {:?} hir_lifetime = {:?}",
1224                             node_id,
1225                             span,
1226                             hir_lifetime);
1227
1228                         this.tcx
1229                             .struct_span_lint_node(lint::builtin::SINGLE_USE_LIFETIME,
1230                                                    id,
1231                                                    span,
1232                                                    &format!("lifetime name `{}` only used once",
1233                                                    hir_lifetime.name.name()))
1234                             .emit();
1235                     }
1236                 }
1237                 _ => {
1238                     debug!("Not one use lifetime");
1239                 }
1240             }
1241         }
1242     }
1243
1244     /// Visits self by adding a scope and handling recursive walk over the contents with `walk`.
1245     ///
1246     /// Handles visiting fns and methods. These are a bit complicated because we must distinguish
1247     /// early- vs late-bound lifetime parameters. We do this by checking which lifetimes appear
1248     /// within type bounds; those are early bound lifetimes, and the rest are late bound.
1249     ///
1250     /// For example:
1251     ///
1252     ///    fn foo<'a,'b,'c,T:Trait<'b>>(...)
1253     ///
1254     /// Here `'a` and `'c` are late bound but `'b` is early bound. Note that early- and late-bound
1255     /// lifetimes may be interspersed together.
1256     ///
1257     /// If early bound lifetimes are present, we separate them into their own list (and likewise
1258     /// for late bound). They will be numbered sequentially, starting from the lowest index that is
1259     /// already in scope (for a fn item, that will be 0, but for a method it might not be). Late
1260     /// bound lifetimes are resolved by name and associated with a binder id (`binder_id`), so the
1261     /// ordering is not important there.
1262     fn visit_early_late<F>(
1263         &mut self,
1264         parent_id: Option<ast::NodeId>,
1265         decl: &'tcx hir::FnDecl,
1266         generics: &'tcx hir::Generics,
1267         walk: F,
1268     ) where
1269         F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>),
1270     {
1271         insert_late_bound_lifetimes(self.map, decl, generics);
1272
1273         // Find the start of nested early scopes, e.g. in methods.
1274         let mut index = 0;
1275         if let Some(parent_id) = parent_id {
1276             let parent = self.tcx.hir.expect_item(parent_id);
1277             if let hir::ItemTrait(..) = parent.node {
1278                 index += 1; // Self comes first.
1279             }
1280             match parent.node {
1281                 hir::ItemTrait(_, _, ref generics, ..)
1282                 | hir::ItemImpl(_, _, _, ref generics, ..) => {
1283                     index += generics.params.len() as u32;
1284                 }
1285                 _ => {}
1286             }
1287         }
1288
1289         let lifetimes = generics
1290             .lifetimes()
1291             .map(|def| {
1292                 if self.map.late_bound.contains(&def.lifetime.id) {
1293                     Region::late(&self.tcx.hir, def)
1294                 } else {
1295                     Region::early(&self.tcx.hir, &mut index, def)
1296                 }
1297             })
1298             .collect();
1299
1300         let next_early_index = index + generics.ty_params().count() as u32;
1301
1302         let scope = Scope::Binder {
1303             lifetimes,
1304             next_early_index,
1305             s: self.scope,
1306         };
1307         self.with(scope, move |old_scope, this| {
1308             this.check_lifetime_params(old_scope, &generics.params);
1309             this.hack(walk); // FIXME(#37666) workaround in place of `walk(this)`
1310         });
1311     }
1312
1313     /// Returns the next index one would use for an early-bound-region
1314     /// if extending the current scope.
1315     fn next_early_index(&self) -> u32 {
1316         let mut scope = self.scope;
1317         loop {
1318             match *scope {
1319                 Scope::Root => return 0,
1320
1321                 Scope::Binder {
1322                     next_early_index, ..
1323                 } => return next_early_index,
1324
1325                 Scope::Body { s, .. }
1326                 | Scope::Elision { s, .. }
1327                 | Scope::ObjectLifetimeDefault { s, .. } => scope = s,
1328             }
1329         }
1330     }
1331
1332     fn resolve_lifetime_ref(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
1333         debug!("resolve_lifetime_ref(lifetime_ref={:?})", lifetime_ref);
1334         // Walk up the scope chain, tracking the number of fn scopes
1335         // that we pass through, until we find a lifetime with the
1336         // given name or we run out of scopes.
1337         // search.
1338         let mut late_depth = 0;
1339         let mut scope = self.scope;
1340         let mut outermost_body = None;
1341         let result = loop {
1342             match *scope {
1343                 Scope::Body { id, s } => {
1344                     outermost_body = Some(id);
1345                     scope = s;
1346                 }
1347
1348                 Scope::Root => {
1349                     break None;
1350                 }
1351
1352                 Scope::Binder {
1353                     ref lifetimes,
1354                     s,
1355                     next_early_index: _,
1356                 } => {
1357                     if let Some(&def) = lifetimes.get(&lifetime_ref.name) {
1358                         break Some(def.shifted(late_depth));
1359                     } else {
1360                         late_depth += 1;
1361                         scope = s;
1362                     }
1363                 }
1364
1365                 Scope::Elision { s, .. } | Scope::ObjectLifetimeDefault { s, .. } => {
1366                     scope = s;
1367                 }
1368             }
1369         };
1370
1371         if let Some(mut def) = result {
1372             if let Region::EarlyBound(..) = def {
1373                 // Do not free early-bound regions, only late-bound ones.
1374             } else if let Some(body_id) = outermost_body {
1375                 let fn_id = self.tcx.hir.body_owner(body_id);
1376                 match self.tcx.hir.get(fn_id) {
1377                     hir::map::NodeItem(&hir::Item {
1378                         node: hir::ItemFn(..),
1379                         ..
1380                     })
1381                     | hir::map::NodeTraitItem(&hir::TraitItem {
1382                         node: hir::TraitItemKind::Method(..),
1383                         ..
1384                     })
1385                     | hir::map::NodeImplItem(&hir::ImplItem {
1386                         node: hir::ImplItemKind::Method(..),
1387                         ..
1388                     }) => {
1389                         let scope = self.tcx.hir.local_def_id(fn_id);
1390                         def = Region::Free(scope, def.id().unwrap());
1391                     }
1392                     _ => {}
1393                 }
1394             }
1395
1396             // Check for fn-syntax conflicts with in-band lifetime definitions
1397             if self.is_in_fn_syntax {
1398                 match def {
1399                     Region::EarlyBound(_, _, LifetimeDefOrigin::InBand)
1400                     | Region::LateBound(_, _, LifetimeDefOrigin::InBand) => {
1401                         struct_span_err!(
1402                             self.tcx.sess,
1403                             lifetime_ref.span,
1404                             E0687,
1405                             "lifetimes used in `fn` or `Fn` syntax must be \
1406                              explicitly declared using `<...>` binders"
1407                         ).span_label(lifetime_ref.span, "in-band lifetime definition")
1408                             .emit();
1409                     }
1410
1411                     Region::Static
1412                     | Region::EarlyBound(_, _, LifetimeDefOrigin::Explicit)
1413                     | Region::LateBound(_, _, LifetimeDefOrigin::Explicit)
1414                     | Region::LateBoundAnon(..)
1415                     | Region::Free(..) => {}
1416                 }
1417             }
1418
1419             self.insert_lifetime(lifetime_ref, def);
1420         } else {
1421             struct_span_err!(
1422                 self.tcx.sess,
1423                 lifetime_ref.span,
1424                 E0261,
1425                 "use of undeclared lifetime name `{}`",
1426                 lifetime_ref.name.name()
1427             ).span_label(lifetime_ref.span, "undeclared lifetime")
1428                 .emit();
1429         }
1430     }
1431
1432     fn visit_segment_parameters(
1433         &mut self,
1434         def: Def,
1435         depth: usize,
1436         params: &'tcx hir::PathParameters,
1437     ) {
1438         if params.parenthesized {
1439             let was_in_fn_syntax = self.is_in_fn_syntax;
1440             self.is_in_fn_syntax = true;
1441             self.visit_fn_like_elision(params.inputs(), Some(&params.bindings[0].ty));
1442             self.is_in_fn_syntax = was_in_fn_syntax;
1443             return;
1444         }
1445
1446         if params.lifetimes.iter().all(|l| l.is_elided()) {
1447             self.resolve_elided_lifetimes(&params.lifetimes);
1448         } else {
1449             for l in &params.lifetimes {
1450                 self.visit_lifetime(l);
1451             }
1452         }
1453
1454         // Figure out if this is a type/trait segment,
1455         // which requires object lifetime defaults.
1456         let parent_def_id = |this: &mut Self, def_id: DefId| {
1457             let def_key = this.tcx.def_key(def_id);
1458             DefId {
1459                 krate: def_id.krate,
1460                 index: def_key.parent.expect("missing parent"),
1461             }
1462         };
1463         let type_def_id = match def {
1464             Def::AssociatedTy(def_id) if depth == 1 => Some(parent_def_id(self, def_id)),
1465             Def::Variant(def_id) if depth == 0 => Some(parent_def_id(self, def_id)),
1466             Def::Struct(def_id)
1467             | Def::Union(def_id)
1468             | Def::Enum(def_id)
1469             | Def::TyAlias(def_id)
1470             | Def::Trait(def_id) if depth == 0 =>
1471             {
1472                 Some(def_id)
1473             }
1474             _ => None,
1475         };
1476
1477         let object_lifetime_defaults = type_def_id.map_or(vec![], |def_id| {
1478             let in_body = {
1479                 let mut scope = self.scope;
1480                 loop {
1481                     match *scope {
1482                         Scope::Root => break false,
1483
1484                         Scope::Body { .. } => break true,
1485
1486                         Scope::Binder { s, .. }
1487                         | Scope::Elision { s, .. }
1488                         | Scope::ObjectLifetimeDefault { s, .. } => {
1489                             scope = s;
1490                         }
1491                     }
1492                 }
1493             };
1494
1495             let map = &self.map;
1496             let unsubst = if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
1497                 &map.object_lifetime_defaults[&id]
1498             } else {
1499                 let tcx = self.tcx;
1500                 self.xcrate_object_lifetime_defaults
1501                     .entry(def_id)
1502                     .or_insert_with(|| {
1503                         tcx.generics_of(def_id)
1504                             .types
1505                             .iter()
1506                             .map(|def| def.object_lifetime_default)
1507                             .collect()
1508                     })
1509             };
1510             unsubst
1511                 .iter()
1512                 .map(|set| match *set {
1513                     Set1::Empty => if in_body {
1514                         None
1515                     } else {
1516                         Some(Region::Static)
1517                     },
1518                     Set1::One(r) => r.subst(&params.lifetimes, map),
1519                     Set1::Many => None,
1520                 })
1521                 .collect()
1522         });
1523
1524         for (i, ty) in params.types.iter().enumerate() {
1525             if let Some(&lt) = object_lifetime_defaults.get(i) {
1526                 let scope = Scope::ObjectLifetimeDefault {
1527                     lifetime: lt,
1528                     s: self.scope,
1529                 };
1530                 self.with(scope, |_, this| this.visit_ty(ty));
1531             } else {
1532                 self.visit_ty(ty);
1533             }
1534         }
1535
1536         for b in &params.bindings {
1537             self.visit_assoc_type_binding(b);
1538         }
1539     }
1540
1541     fn visit_fn_like_elision(
1542         &mut self,
1543         inputs: &'tcx [P<hir::Ty>],
1544         output: Option<&'tcx P<hir::Ty>>,
1545     ) {
1546         let mut arg_elide = Elide::FreshLateAnon(Cell::new(0));
1547         let arg_scope = Scope::Elision {
1548             elide: arg_elide.clone(),
1549             s: self.scope,
1550         };
1551         self.with(arg_scope, |_, this| {
1552             for input in inputs {
1553                 this.visit_ty(input);
1554             }
1555             match *this.scope {
1556                 Scope::Elision { ref elide, .. } => {
1557                     arg_elide = elide.clone();
1558                 }
1559                 _ => bug!(),
1560             }
1561         });
1562
1563         let output = match output {
1564             Some(ty) => ty,
1565             None => return,
1566         };
1567
1568         // Figure out if there's a body we can get argument names from,
1569         // and whether there's a `self` argument (treated specially).
1570         let mut assoc_item_kind = None;
1571         let mut impl_self = None;
1572         let parent = self.tcx.hir.get_parent_node(output.id);
1573         let body = match self.tcx.hir.get(parent) {
1574             // `fn` definitions and methods.
1575             hir::map::NodeItem(&hir::Item {
1576                 node: hir::ItemFn(.., body),
1577                 ..
1578             }) => Some(body),
1579
1580             hir::map::NodeTraitItem(&hir::TraitItem {
1581                 node: hir::TraitItemKind::Method(_, ref m),
1582                 ..
1583             }) => {
1584                 match self.tcx
1585                     .hir
1586                     .expect_item(self.tcx.hir.get_parent(parent))
1587                     .node
1588                 {
1589                     hir::ItemTrait(.., ref trait_items) => {
1590                         assoc_item_kind = trait_items
1591                             .iter()
1592                             .find(|ti| ti.id.node_id == parent)
1593                             .map(|ti| ti.kind);
1594                     }
1595                     _ => {}
1596                 }
1597                 match *m {
1598                     hir::TraitMethod::Required(_) => None,
1599                     hir::TraitMethod::Provided(body) => Some(body),
1600                 }
1601             }
1602
1603             hir::map::NodeImplItem(&hir::ImplItem {
1604                 node: hir::ImplItemKind::Method(_, body),
1605                 ..
1606             }) => {
1607                 match self.tcx
1608                     .hir
1609                     .expect_item(self.tcx.hir.get_parent(parent))
1610                     .node
1611                 {
1612                     hir::ItemImpl(.., ref self_ty, ref impl_items) => {
1613                         impl_self = Some(self_ty);
1614                         assoc_item_kind = impl_items
1615                             .iter()
1616                             .find(|ii| ii.id.node_id == parent)
1617                             .map(|ii| ii.kind);
1618                     }
1619                     _ => {}
1620                 }
1621                 Some(body)
1622             }
1623
1624             // Foreign functions, `fn(...) -> R` and `Trait(...) -> R` (both types and bounds).
1625             hir::map::NodeForeignItem(_) | hir::map::NodeTy(_) | hir::map::NodeTraitRef(_) =>
1626                 None,
1627             // Everything else (only closures?) doesn't
1628             // actually enjoy elision in return types.
1629             _ => {
1630                 self.visit_ty(output);
1631                 return;
1632             }
1633         };
1634
1635         let has_self = match assoc_item_kind {
1636             Some(hir::AssociatedItemKind::Method { has_self }) => has_self,
1637             _ => false,
1638         };
1639
1640         // In accordance with the rules for lifetime elision, we can determine
1641         // what region to use for elision in the output type in two ways.
1642         // First (determined here), if `self` is by-reference, then the
1643         // implied output region is the region of the self parameter.
1644         if has_self {
1645             // Look for `self: &'a Self` - also desugared from `&'a self`,
1646             // and if that matches, use it for elision and return early.
1647             let is_self_ty = |def: Def| {
1648                 if let Def::SelfTy(..) = def {
1649                     return true;
1650                 }
1651
1652                 // Can't always rely on literal (or implied) `Self` due
1653                 // to the way elision rules were originally specified.
1654                 let impl_self = impl_self.map(|ty| &ty.node);
1655                 if let Some(&hir::TyPath(hir::QPath::Resolved(None, ref path))) = impl_self {
1656                     match path.def {
1657                         // Whitelist the types that unambiguously always
1658                         // result in the same type constructor being used
1659                         // (it can't differ between `Self` and `self`).
1660                         Def::Struct(_) | Def::Union(_) | Def::Enum(_) | Def::PrimTy(_) => {
1661                             return def == path.def
1662                         }
1663                         _ => {}
1664                     }
1665                 }
1666
1667                 false
1668             };
1669
1670             if let hir::TyRptr(lifetime_ref, ref mt) = inputs[0].node {
1671                 if let hir::TyPath(hir::QPath::Resolved(None, ref path)) = mt.ty.node {
1672                     if is_self_ty(path.def) {
1673                         if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.id) {
1674                             let scope = Scope::Elision {
1675                                 elide: Elide::Exact(lifetime),
1676                                 s: self.scope,
1677                             };
1678                             self.with(scope, |_, this| this.visit_ty(output));
1679                             return;
1680                         }
1681                     }
1682                 }
1683             }
1684         }
1685
1686         // Second, if there was exactly one lifetime (either a substitution or a
1687         // reference) in the arguments, then any anonymous regions in the output
1688         // have that lifetime.
1689         let mut possible_implied_output_region = None;
1690         let mut lifetime_count = 0;
1691         let arg_lifetimes = inputs
1692             .iter()
1693             .enumerate()
1694             .skip(has_self as usize)
1695             .map(|(i, input)| {
1696                 let mut gather = GatherLifetimes {
1697                     map: self.map,
1698                     binder_depth: 1,
1699                     have_bound_regions: false,
1700                     lifetimes: FxHashSet(),
1701                 };
1702                 gather.visit_ty(input);
1703
1704                 lifetime_count += gather.lifetimes.len();
1705
1706                 if lifetime_count == 1 && gather.lifetimes.len() == 1 {
1707                     // there's a chance that the unique lifetime of this
1708                     // iteration will be the appropriate lifetime for output
1709                     // parameters, so lets store it.
1710                     possible_implied_output_region = gather.lifetimes.iter().cloned().next();
1711                 }
1712
1713                 ElisionFailureInfo {
1714                     parent: body,
1715                     index: i,
1716                     lifetime_count: gather.lifetimes.len(),
1717                     have_bound_regions: gather.have_bound_regions,
1718                 }
1719             })
1720             .collect();
1721
1722         let elide = if lifetime_count == 1 {
1723             Elide::Exact(possible_implied_output_region.unwrap())
1724         } else {
1725             Elide::Error(arg_lifetimes)
1726         };
1727
1728         let scope = Scope::Elision {
1729             elide,
1730             s: self.scope,
1731         };
1732         self.with(scope, |_, this| this.visit_ty(output));
1733
1734         struct GatherLifetimes<'a> {
1735             map: &'a NamedRegionMap,
1736             binder_depth: u32,
1737             have_bound_regions: bool,
1738             lifetimes: FxHashSet<Region>,
1739         }
1740
1741         impl<'v, 'a> Visitor<'v> for GatherLifetimes<'a> {
1742             fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
1743                 NestedVisitorMap::None
1744             }
1745
1746             fn visit_ty(&mut self, ty: &hir::Ty) {
1747                 if let hir::TyBareFn(_) = ty.node {
1748                     self.binder_depth += 1;
1749                 }
1750                 if let hir::TyTraitObject(ref bounds, ref lifetime) = ty.node {
1751                     for bound in bounds {
1752                         self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None);
1753                     }
1754
1755                     // Stay on the safe side and don't include the object
1756                     // lifetime default (which may not end up being used).
1757                     if !lifetime.is_elided() {
1758                         self.visit_lifetime(lifetime);
1759                     }
1760                 } else {
1761                     intravisit::walk_ty(self, ty);
1762                 }
1763                 if let hir::TyBareFn(_) = ty.node {
1764                     self.binder_depth -= 1;
1765                 }
1766             }
1767
1768             fn visit_generic_param(&mut self, param: &hir::GenericParam) {
1769                 if let hir::GenericParam::Lifetime(ref lifetime_def) = *param {
1770                     for l in &lifetime_def.bounds {
1771                         self.visit_lifetime(l);
1772                     }
1773                 }
1774
1775                 intravisit::walk_generic_param(self, param);
1776             }
1777
1778             fn visit_poly_trait_ref(
1779                 &mut self,
1780                 trait_ref: &hir::PolyTraitRef,
1781                 modifier: hir::TraitBoundModifier,
1782             ) {
1783                 self.binder_depth += 1;
1784                 intravisit::walk_poly_trait_ref(self, trait_ref, modifier);
1785                 self.binder_depth -= 1;
1786             }
1787
1788             fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) {
1789                 if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.id) {
1790                     match lifetime {
1791                         Region::LateBound(debruijn, _, _) | Region::LateBoundAnon(debruijn, _)
1792                             if debruijn.depth < self.binder_depth =>
1793                         {
1794                             self.have_bound_regions = true;
1795                         }
1796                         _ => {
1797                             self.lifetimes
1798                                 .insert(lifetime.from_depth(self.binder_depth));
1799                         }
1800                     }
1801                 }
1802             }
1803         }
1804     }
1805
1806     fn resolve_elided_lifetimes(&mut self, lifetime_refs: &'tcx [hir::Lifetime]) {
1807         if lifetime_refs.is_empty() {
1808             return;
1809         }
1810
1811         let span = lifetime_refs[0].span;
1812         let mut late_depth = 0;
1813         let mut scope = self.scope;
1814         let error = loop {
1815             match *scope {
1816                 // Do not assign any resolution, it will be inferred.
1817                 Scope::Body { .. } => return,
1818
1819                 Scope::Root => break None,
1820
1821                 Scope::Binder { s, .. } => {
1822                     late_depth += 1;
1823                     scope = s;
1824                 }
1825
1826                 Scope::Elision { ref elide, .. } => {
1827                     let lifetime = match *elide {
1828                         Elide::FreshLateAnon(ref counter) => {
1829                             for lifetime_ref in lifetime_refs {
1830                                 let lifetime = Region::late_anon(counter).shifted(late_depth);
1831                                 self.insert_lifetime(lifetime_ref, lifetime);
1832                             }
1833                             return;
1834                         }
1835                         Elide::Exact(l) => l.shifted(late_depth),
1836                         Elide::Error(ref e) => break Some(e),
1837                     };
1838                     for lifetime_ref in lifetime_refs {
1839                         self.insert_lifetime(lifetime_ref, lifetime);
1840                     }
1841                     return;
1842                 }
1843
1844                 Scope::ObjectLifetimeDefault { s, .. } => {
1845                     scope = s;
1846                 }
1847             }
1848         };
1849
1850         let mut err = struct_span_err!(
1851             self.tcx.sess,
1852             span,
1853             E0106,
1854             "missing lifetime specifier{}",
1855             if lifetime_refs.len() > 1 { "s" } else { "" }
1856         );
1857         let msg = if lifetime_refs.len() > 1 {
1858             format!("expected {} lifetime parameters", lifetime_refs.len())
1859         } else {
1860             format!("expected lifetime parameter")
1861         };
1862         err.span_label(span, msg);
1863
1864         if let Some(params) = error {
1865             if lifetime_refs.len() == 1 {
1866                 self.report_elision_failure(&mut err, params);
1867             }
1868         }
1869         err.emit();
1870     }
1871
1872     fn report_elision_failure(
1873         &mut self,
1874         db: &mut DiagnosticBuilder,
1875         params: &[ElisionFailureInfo],
1876     ) {
1877         let mut m = String::new();
1878         let len = params.len();
1879
1880         let elided_params: Vec<_> = params
1881             .iter()
1882             .cloned()
1883             .filter(|info| info.lifetime_count > 0)
1884             .collect();
1885
1886         let elided_len = elided_params.len();
1887
1888         for (i, info) in elided_params.into_iter().enumerate() {
1889             let ElisionFailureInfo {
1890                 parent,
1891                 index,
1892                 lifetime_count: n,
1893                 have_bound_regions,
1894             } = info;
1895
1896             let help_name = if let Some(body) = parent {
1897                 let arg = &self.tcx.hir.body(body).arguments[index];
1898                 format!("`{}`", self.tcx.hir.node_to_pretty_string(arg.pat.id))
1899             } else {
1900                 format!("argument {}", index + 1)
1901             };
1902
1903             m.push_str(
1904                 &(if n == 1 {
1905                     help_name
1906                 } else {
1907                     format!(
1908                         "one of {}'s {} {}lifetimes",
1909                         help_name,
1910                         n,
1911                         if have_bound_regions { "free " } else { "" }
1912                     )
1913                 })[..],
1914             );
1915
1916             if elided_len == 2 && i == 0 {
1917                 m.push_str(" or ");
1918             } else if i + 2 == elided_len {
1919                 m.push_str(", or ");
1920             } else if i != elided_len - 1 {
1921                 m.push_str(", ");
1922             }
1923         }
1924
1925         if len == 0 {
1926             help!(
1927                 db,
1928                 "this function's return type contains a borrowed value, but \
1929                  there is no value for it to be borrowed from"
1930             );
1931             help!(db, "consider giving it a 'static lifetime");
1932         } else if elided_len == 0 {
1933             help!(
1934                 db,
1935                 "this function's return type contains a borrowed value with \
1936                  an elided lifetime, but the lifetime cannot be derived from \
1937                  the arguments"
1938             );
1939             help!(
1940                 db,
1941                 "consider giving it an explicit bounded or 'static \
1942                  lifetime"
1943             );
1944         } else if elided_len == 1 {
1945             help!(
1946                 db,
1947                 "this function's return type contains a borrowed value, but \
1948                  the signature does not say which {} it is borrowed from",
1949                 m
1950             );
1951         } else {
1952             help!(
1953                 db,
1954                 "this function's return type contains a borrowed value, but \
1955                  the signature does not say whether it is borrowed from {}",
1956                 m
1957             );
1958         }
1959     }
1960
1961     fn resolve_object_lifetime_default(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
1962         let mut late_depth = 0;
1963         let mut scope = self.scope;
1964         let lifetime = loop {
1965             match *scope {
1966                 Scope::Binder { s, .. } => {
1967                     late_depth += 1;
1968                     scope = s;
1969                 }
1970
1971                 Scope::Root | Scope::Elision { .. } => break Region::Static,
1972
1973                 Scope::Body { .. } | Scope::ObjectLifetimeDefault { lifetime: None, .. } => return,
1974
1975                 Scope::ObjectLifetimeDefault {
1976                     lifetime: Some(l), ..
1977                 } => break l,
1978             }
1979         };
1980         self.insert_lifetime(lifetime_ref, lifetime.shifted(late_depth));
1981     }
1982
1983     fn check_lifetime_params(&mut self, old_scope: ScopeRef, params: &'tcx [hir::GenericParam]) {
1984         for (i, lifetime_i) in params.lifetimes().enumerate() {
1985             for lifetime in params.lifetimes() {
1986                 match lifetime.lifetime.name {
1987                     hir::LifetimeName::Static | hir::LifetimeName::Underscore => {
1988                         let lifetime = lifetime.lifetime;
1989                         let name = lifetime.name.name();
1990                         let mut err = struct_span_err!(
1991                             self.tcx.sess,
1992                             lifetime.span,
1993                             E0262,
1994                             "invalid lifetime parameter name: `{}`",
1995                             name
1996                         );
1997                         err.span_label(
1998                             lifetime.span,
1999                             format!("{} is a reserved lifetime name", name),
2000                         );
2001                         err.emit();
2002                     }
2003                     hir::LifetimeName::Implicit | hir::LifetimeName::Name(_) => {}
2004                 }
2005             }
2006
2007             // It is a hard error to shadow a lifetime within the same scope.
2008             for lifetime_j in params.lifetimes().skip(i + 1) {
2009                 if lifetime_i.lifetime.name == lifetime_j.lifetime.name {
2010                     struct_span_err!(
2011                         self.tcx.sess,
2012                         lifetime_j.lifetime.span,
2013                         E0263,
2014                         "lifetime name `{}` declared twice in the same scope",
2015                         lifetime_j.lifetime.name.name()
2016                     ).span_label(lifetime_j.lifetime.span, "declared twice")
2017                         .span_label(lifetime_i.lifetime.span, "previous declaration here")
2018                         .emit();
2019                 }
2020             }
2021
2022             // It is a soft error to shadow a lifetime within a parent scope.
2023             self.check_lifetime_def_for_shadowing(old_scope, &lifetime_i.lifetime);
2024
2025             for bound in &lifetime_i.bounds {
2026                 match bound.name {
2027                     hir::LifetimeName::Underscore => {
2028                         let mut err = struct_span_err!(
2029                             self.tcx.sess,
2030                             bound.span,
2031                             E0637,
2032                             "invalid lifetime bound name: `'_`"
2033                         );
2034                         err.span_label(bound.span, "`'_` is a reserved lifetime name");
2035                         err.emit();
2036                     }
2037                     hir::LifetimeName::Static => {
2038                         self.insert_lifetime(bound, Region::Static);
2039                         self.tcx
2040                             .sess
2041                             .struct_span_warn(
2042                                 lifetime_i.lifetime.span.to(bound.span),
2043                                 &format!(
2044                                     "unnecessary lifetime parameter `{}`",
2045                                     lifetime_i.lifetime.name.name()
2046                                 ),
2047                             )
2048                             .help(&format!(
2049                                 "you can use the `'static` lifetime directly, in place \
2050                                  of `{}`",
2051                                 lifetime_i.lifetime.name.name()
2052                             ))
2053                             .emit();
2054                     }
2055                     hir::LifetimeName::Implicit | hir::LifetimeName::Name(_) => {
2056                         self.resolve_lifetime_ref(bound);
2057                     }
2058                 }
2059             }
2060         }
2061     }
2062
2063     fn check_lifetime_def_for_shadowing(&self,
2064                                         mut old_scope: ScopeRef,
2065                                         lifetime: &'tcx hir::Lifetime) {
2066         for &(label, label_span) in &self.labels_in_fn {
2067             // FIXME (#24278): non-hygienic comparison
2068             if lifetime.name.name() == label {
2069                 signal_shadowing_problem(
2070                     self.tcx,
2071                     label,
2072                     original_label(label_span),
2073                     shadower_lifetime(&lifetime),
2074                 );
2075                 return;
2076             }
2077         }
2078
2079         loop {
2080             match *old_scope {
2081                 Scope::Body { s, .. }
2082                 | Scope::Elision { s, .. }
2083                 | Scope::ObjectLifetimeDefault { s, .. } => {
2084                     old_scope = s;
2085                 }
2086
2087                 Scope::Root => {
2088                     return;
2089                 }
2090
2091                 Scope::Binder {
2092                     ref lifetimes,
2093                     s,
2094                     next_early_index: _,
2095                 } => {
2096                     if let Some(&def) = lifetimes.get(&lifetime.name) {
2097                         let node_id = self.tcx.hir.as_local_node_id(def.id().unwrap()).unwrap();
2098
2099                         signal_shadowing_problem(
2100                             self.tcx,
2101                             lifetime.name.name(),
2102                             original_lifetime(self.tcx.hir.span(node_id)),
2103                             shadower_lifetime(&lifetime),
2104                         );
2105                         return;
2106                     }
2107
2108                     old_scope = s;
2109                 }
2110             }
2111         }
2112     }
2113
2114     fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
2115         if lifetime_ref.id == ast::DUMMY_NODE_ID {
2116             span_bug!(
2117                 lifetime_ref.span,
2118                 "lifetime reference not renumbered, \
2119                  probably a bug in syntax::fold"
2120             );
2121         }
2122
2123         debug!(
2124             "insert_lifetime: {} resolved to {:?} span={:?}",
2125             self.tcx.hir.node_to_string(lifetime_ref.id),
2126             def,
2127             self.tcx.sess.codemap().span_to_string(lifetime_ref.span)
2128         );
2129         self.map.defs.insert(lifetime_ref.id, def);
2130
2131         match def {
2132             Region::LateBoundAnon(..) |
2133             Region::Static => {
2134                 // These are anonymous lifetimes or lifetimes that are not declared.
2135             }
2136
2137             Region::Free(_, def_id) |
2138             Region::LateBound(_, def_id, _) |
2139             Region::EarlyBound(_, def_id, _) => {
2140                 // A lifetime declared by the user.
2141                 if !self.lifetime_uses.contains_key(&def_id) {
2142                     self.lifetime_uses
2143                         .insert(def_id, LifetimeUseSet::One(lifetime_ref));
2144                 } else {
2145                     self.lifetime_uses.insert(def_id, LifetimeUseSet::Many);
2146                 }
2147             }
2148         }
2149     }
2150 }
2151
2152 ///////////////////////////////////////////////////////////////////////////
2153
2154 /// Detects late-bound lifetimes and inserts them into
2155 /// `map.late_bound`.
2156 ///
2157 /// A region declared on a fn is **late-bound** if:
2158 /// - it is constrained by an argument type;
2159 /// - it does not appear in a where-clause.
2160 ///
2161 /// "Constrained" basically means that it appears in any type but
2162 /// not amongst the inputs to a projection.  In other words, `<&'a
2163 /// T as Trait<''b>>::Foo` does not constrain `'a` or `'b`.
2164 fn insert_late_bound_lifetimes(
2165     map: &mut NamedRegionMap,
2166     decl: &hir::FnDecl,
2167     generics: &hir::Generics,
2168 ) {
2169     debug!(
2170         "insert_late_bound_lifetimes(decl={:?}, generics={:?})",
2171         decl,
2172         generics
2173     );
2174
2175     let mut constrained_by_input = ConstrainedCollector {
2176         regions: FxHashSet(),
2177     };
2178     for arg_ty in &decl.inputs {
2179         constrained_by_input.visit_ty(arg_ty);
2180     }
2181
2182     let mut appears_in_output = AllCollector {
2183         regions: FxHashSet(),
2184     };
2185     intravisit::walk_fn_ret_ty(&mut appears_in_output, &decl.output);
2186
2187     debug!(
2188         "insert_late_bound_lifetimes: constrained_by_input={:?}",
2189         constrained_by_input.regions
2190     );
2191
2192     // Walk the lifetimes that appear in where clauses.
2193     //
2194     // Subtle point: because we disallow nested bindings, we can just
2195     // ignore binders here and scrape up all names we see.
2196     let mut appears_in_where_clause = AllCollector {
2197         regions: FxHashSet(),
2198     };
2199
2200     for param in &generics.params {
2201         match *param {
2202             hir::GenericParam::Lifetime(ref lifetime_def) => {
2203                 if !lifetime_def.bounds.is_empty() {
2204                     // `'a: 'b` means both `'a` and `'b` are referenced
2205                     appears_in_where_clause.visit_generic_param(param);
2206                 }
2207             }
2208             hir::GenericParam::Type(ref ty_param) => {
2209                 walk_list!(
2210                     &mut appears_in_where_clause,
2211                     visit_ty_param_bound,
2212                     &ty_param.bounds
2213                 );
2214             }
2215         }
2216     }
2217
2218     walk_list!(
2219         &mut appears_in_where_clause,
2220         visit_where_predicate,
2221         &generics.where_clause.predicates
2222     );
2223
2224     debug!(
2225         "insert_late_bound_lifetimes: appears_in_where_clause={:?}",
2226         appears_in_where_clause.regions
2227     );
2228
2229     // Late bound regions are those that:
2230     // - appear in the inputs
2231     // - do not appear in the where-clauses
2232     // - are not implicitly captured by `impl Trait`
2233     for lifetime in generics.lifetimes() {
2234         let name = lifetime.lifetime.name;
2235
2236         // appears in the where clauses? early-bound.
2237         if appears_in_where_clause.regions.contains(&name) {
2238             continue;
2239         }
2240
2241         // does not appear in the inputs, but appears in the return type? early-bound.
2242         if !constrained_by_input.regions.contains(&name)
2243             && appears_in_output.regions.contains(&name)
2244         {
2245             continue;
2246         }
2247
2248         debug!(
2249             "insert_late_bound_lifetimes: \
2250              lifetime {:?} with id {:?} is late-bound",
2251             lifetime.lifetime.name,
2252             lifetime.lifetime.id
2253         );
2254
2255         let inserted = map.late_bound.insert(lifetime.lifetime.id);
2256         assert!(
2257             inserted,
2258             "visited lifetime {:?} twice",
2259             lifetime.lifetime.id
2260         );
2261     }
2262
2263     return;
2264
2265     struct ConstrainedCollector {
2266         regions: FxHashSet<hir::LifetimeName>,
2267     }
2268
2269     impl<'v> Visitor<'v> for ConstrainedCollector {
2270         fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
2271             NestedVisitorMap::None
2272         }
2273
2274         fn visit_ty(&mut self, ty: &'v hir::Ty) {
2275             match ty.node {
2276                 hir::TyPath(hir::QPath::Resolved(Some(_), _))
2277                 | hir::TyPath(hir::QPath::TypeRelative(..)) => {
2278                     // ignore lifetimes appearing in associated type
2279                     // projections, as they are not *constrained*
2280                     // (defined above)
2281                 }
2282
2283                 hir::TyPath(hir::QPath::Resolved(None, ref path)) => {
2284                     // consider only the lifetimes on the final
2285                     // segment; I am not sure it's even currently
2286                     // valid to have them elsewhere, but even if it
2287                     // is, those would be potentially inputs to
2288                     // projections
2289                     if let Some(last_segment) = path.segments.last() {
2290                         self.visit_path_segment(path.span, last_segment);
2291                     }
2292                 }
2293
2294                 _ => {
2295                     intravisit::walk_ty(self, ty);
2296                 }
2297             }
2298         }
2299
2300         fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
2301             self.regions.insert(lifetime_ref.name);
2302         }
2303     }
2304
2305     struct AllCollector {
2306         regions: FxHashSet<hir::LifetimeName>,
2307     }
2308
2309     impl<'v> Visitor<'v> for AllCollector {
2310         fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
2311             NestedVisitorMap::None
2312         }
2313
2314         fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
2315             self.regions.insert(lifetime_ref.name);
2316         }
2317     }
2318 }