about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-03-24 13:23:17 +0000
committerbors <bors@rust-lang.org>2018-03-24 13:23:17 +0000
commitb4aa80dd73df9708022cc383aad8da1dcf38d1df (patch)
tree96feb584c23b8680534b22f984fe70834ead5ec2 /src
parenta0b0f5fba5d7bf18b24d1fa0e454a4fe871fecee (diff)
parent94468dac6350a29dc2eb1eed01308ec78224f7ba (diff)
downloadrust-b4aa80dd73df9708022cc383aad8da1dcf38d1df.tar.gz
rust-b4aa80dd73df9708022cc383aad8da1dcf38d1df.zip
Auto merge of #49251 - nikomatsakis:issue-15872-elision-impl-header, r=cramertj
support elision in impl headers

You can now do things like:

```
impl MyTrait<'_> for &u32 { ... }
```

Each `'_` or elided lifetime is a fresh parameter. `'_` and elision are still not permitted in associated type values. (Plausibly we could support that if there is a single input lifetime.) The original lifetime elision RFC was a bit unclear on this point: [as documented here, I think this is the correct interpretation, both because it fits existing impls and it's most analogous to the behavior in fns](https://github.com/rust-lang/rust/issues/15872#issuecomment-338700138).

We do not support elision with deprecated forms:

```
impl MyTrait for std::cell::Ref<u32> { } // ERROR
```

Builds on the in-band lifetime stuff.

r? @cramertj

Fixes #15872
Diffstat (limited to 'src')
-rw-r--r--src/librustc/hir/intravisit.rs5
-rw-r--r--src/librustc/hir/lowering.rs2586
-rw-r--r--src/librustc/hir/mod.rs32
-rw-r--r--src/librustc/ich/impls_hir.rs1
-rw-r--r--src/librustc/middle/resolve_lifetime.rs165
-rw-r--r--src/test/ui/feature-gate-in_band_lifetimes-impl.rs22
-rw-r--r--src/test/ui/feature-gate-in_band_lifetimes-impl.stderr15
-rw-r--r--src/test/ui/in-band-lifetimes/impl/assoc-type.rs38
-rw-r--r--src/test/ui/in-band-lifetimes/impl/assoc-type.stderr15
-rw-r--r--src/test/ui/in-band-lifetimes/impl/dyn-trait.rs45
-rw-r--r--src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr22
-rw-r--r--src/test/ui/in-band-lifetimes/impl/path-elided.rs23
-rw-r--r--src/test/ui/in-band-lifetimes/impl/path-elided.stderr9
-rw-r--r--src/test/ui/in-band-lifetimes/impl/path-underscore.rs47
-rw-r--r--src/test/ui/in-band-lifetimes/impl/ref-underscore.rs43
-rw-r--r--src/test/ui/in-band-lifetimes/impl/trait-elided.rs21
-rw-r--r--src/test/ui/in-band-lifetimes/impl/trait-elided.stderr9
-rw-r--r--src/test/ui/in-band-lifetimes/impl/trait-underscore.rs48
-rw-r--r--src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs26
-rw-r--r--src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr16
20 files changed, 2081 insertions, 1107 deletions
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 972278bdf86..9f51eb8c35a 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -420,7 +420,10 @@ pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime
         LifetimeName::Name(name) => {
             visitor.visit_name(lifetime.span, name);
         }
-        LifetimeName::Static | LifetimeName::Implicit | LifetimeName::Underscore => {}
+        LifetimeName::Fresh(_) |
+        LifetimeName::Static |
+        LifetimeName::Implicit |
+        LifetimeName::Underscore => {}
     }
 }
 
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index f6bdfde15fc..ad848949f62 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -43,8 +43,8 @@
 use dep_graph::DepGraph;
 use hir;
 use hir::HirVec;
-use hir::map::{Definitions, DefKey, DefPathData};
-use hir::def_id::{DefIndex, DefId, CRATE_DEF_INDEX, DefIndexAddressSpace};
+use hir::map::{DefKey, DefPathData, Definitions};
+use hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX};
 use hir::def::{Def, PathResolution};
 use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES};
 use middle::cstore::CrateStore;
@@ -63,10 +63,10 @@ use syntax::errors;
 use syntax::ext::hygiene::{Mark, SyntaxContext};
 use syntax::print::pprust;
 use syntax::ptr::P;
-use syntax::codemap::{self, respan, Spanned, CompilerDesugaringKind};
+use syntax::codemap::{self, respan, CompilerDesugaringKind, Spanned};
 use syntax::std_inject;
-use syntax::symbol::{Symbol, keywords};
-use syntax::tokenstream::{TokenStream, TokenTree, Delimited};
+use syntax::symbol::{keywords, Symbol};
+use syntax::tokenstream::{Delimited, TokenStream, TokenTree};
 use syntax::parse::token::Token;
 use syntax::util::small_vector::SmallVector;
 use syntax::visit::{self, Visitor};
@@ -80,13 +80,13 @@ pub struct LoweringContext<'a> {
     // Use to assign ids to hir nodes that do not directly correspond to an ast node
     sess: &'a Session,
 
-    cstore: &'a dyn CrateStore,
+    cstore: &'a CrateStore,
 
     // As we walk the AST we must keep track of the current 'parent' def id (in
     // the form of a DefIndex) so that if we create a new node which introduces
     // a definition, then we can properly create the def id.
     parent_def: Option<DefIndex>,
-    resolver: &'a mut dyn Resolver,
+    resolver: &'a mut Resolver,
     name_map: FxHashMap<Ident, Name>,
 
     /// The items being lowered are collected here.
@@ -107,6 +107,12 @@ pub struct LoweringContext<'a> {
     is_in_loop_condition: bool,
     is_in_trait_impl: bool,
 
+    /// What to do when we encounter either an "anonymous lifetime
+    /// reference". The term "anonymous" is meant to encompass both
+    /// `'_` lifetimes as well as fully elided cases where nothing is
+    /// written at all (e.g., `&T` or `std::cell::Ref<T>`).
+    anonymous_lifetime_mode: AnonymousLifetimeMode,
+
     // This is a list of in-band type definitions being generated by
     // Argument-position `impl Trait`.
     // When traversing a signature such as `fn foo(x: impl Trait)`,
@@ -121,13 +127,15 @@ pub struct LoweringContext<'a> {
     // (i.e. it doesn't appear in the in_scope_lifetimes list), it is added
     // to this list. The results of this list are then added to the list of
     // lifetime definitions in the corresponding impl or function generics.
-    lifetimes_to_define: Vec<(Span, Name)>,
+    lifetimes_to_define: Vec<(Span, hir::LifetimeName)>,
+
     // Whether or not in-band lifetimes are being collected. This is used to
     // indicate whether or not we're in a place where new lifetimes will result
     // in in-band lifetime definitions, such a function or an impl header.
     // This will always be false unless the `in_band_lifetimes` feature is
     // enabled.
     is_collecting_in_band_lifetimes: bool,
+
     // Currently in-scope lifetimes defined in impl headers, fn headers, or HRTB.
     // When `is_collectin_in_band_lifetimes` is true, each lifetime is checked
     // against this list to see if it is already in-scope, or if a definition
@@ -154,8 +162,13 @@ pub trait Resolver {
 
     /// Given suffix ["b","c","d"], creates a HIR path for `[::crate_root]::b::c::d` and resolves
     /// it based on `is_value`.
-    fn resolve_str_path(&mut self, span: Span, crate_root: Option<&str>,
-                components: &[&str], is_value: bool) -> hir::Path;
+    fn resolve_str_path(
+        &mut self,
+        span: Span,
+        crate_root: Option<&str>,
+        components: &[&str],
+        is_value: bool,
+    ) -> hir::Path;
 }
 
 #[derive(Clone, Copy, Debug)]
@@ -176,12 +189,13 @@ enum ImplTraitContext {
     Disallowed,
 }
 
-pub fn lower_crate(sess: &Session,
-                   cstore: &dyn CrateStore,
-                   dep_graph: &DepGraph,
-                   krate: &Crate,
-                   resolver: &mut dyn Resolver)
-                   -> hir::Crate {
+pub fn lower_crate(
+    sess: &Session,
+    cstore: &CrateStore,
+    dep_graph: &DepGraph,
+    krate: &Crate,
+    resolver: &mut Resolver,
+) -> hir::Crate {
     // We're constructing the HIR here; we don't care what we will
     // read, since we haven't even constructed the *input* to
     // incr. comp. yet.
@@ -204,6 +218,7 @@ pub fn lower_crate(sess: &Session,
         catch_scopes: Vec::new(),
         loop_scopes: Vec::new(),
         is_in_loop_condition: false,
+        anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
         type_def_lifetime_params: DefIdMap(),
         current_hir_id_owner: vec![(CRATE_DEF_INDEX, 0)],
         item_local_id_counters: NodeMap(),
@@ -222,7 +237,7 @@ enum ParamMode {
     /// Any path in a type context.
     Explicit,
     /// The `module::Type` in `module::Type::method` in an expression.
-    Optional
+    Optional,
 }
 
 struct LoweredNodeId {
@@ -236,6 +251,51 @@ enum ParenthesizedGenericArgs {
     Err,
 }
 
+/// What to do when we encounter an **anonymous** lifetime
+/// reference. Anonymous lifetime references come in two flavors.  You
+/// have implicit, or fully elided, references to lifetimes, like the
+/// one in `&T` or `Ref<T>`, and you have `'_` lifetimes, like `&'_ T`
+/// or `Ref<'_, T>`.  These often behave the same, but not always:
+///
+/// - certain usages of implicit references are deprecated, like
+///   `Ref<T>`, and we sometimes just give hard errors in those cases
+///   as well.
+/// - for object bounds there is a difference: `Box<dyn Foo>` is not
+///   the same as `Box<dyn Foo + '_>`.
+///
+/// We describe the effects of the various modes in terms of three cases:
+///
+/// - **Modern** -- includes all uses of `'_`, but also the lifetime arg
+///   of a `&` (e.g., the missing lifetime in something like `&T`)
+/// - **Dyn Bound** -- if you have something like `Box<dyn Foo>`,
+///   there is an elided lifetime bound (`Box<dyn Foo + 'X>`). These
+///   elided bounds follow special rules. Note that this only covers
+///   cases where *nothing* is written; the `'_` in `Box<dyn Foo +
+///   '_>` is a case of "modern" elision.
+/// - **Deprecated** -- this coverse cases like `Ref<T>`, where the lifetime
+///   parameter to ref is completely elided. `Ref<'_, T>` would be the modern,
+///   non-deprecated equivalent.
+///
+/// Currently, the handling of lifetime elision is somewhat spread out
+/// between HIR lowering and -- as described below -- the
+/// `resolve_lifetime` module. Often we "fallthrough" to that code by generating
+/// an "elided" or "underscore" lifetime name. In the future, we probably want to move
+/// everything into HIR lowering.
+#[derive(Copy, Clone)]
+enum AnonymousLifetimeMode {
+    /// For **Modern** cases, create a new anonymous region parameter
+    /// and reference that.
+    ///
+    /// For **Dyn Bound** cases, pass responsibility to
+    /// `resolve_lifetime` code.
+    ///
+    /// For **Deprecated** cases, report an error.
+    CreateParameter,
+
+    /// Pass responsibility to `resolve_lifetime` code for all cases.
+    PassThrough,
+}
+
 impl<'a> LoweringContext<'a> {
     fn lower_crate(mut self, c: &Crate) -> hir::Crate {
         /// Full-crate AST visitor that inserts into a fresh
@@ -252,13 +312,15 @@ impl<'a> LoweringContext<'a> {
                 self.lctx.allocate_hir_id_counter(item.id, item);
 
                 match item.node {
-                    ItemKind::Struct(_, ref generics) |
-                    ItemKind::Union(_, ref generics) |
-                    ItemKind::Enum(_, ref generics) |
-                    ItemKind::Ty(_, ref generics) |
-                    ItemKind::Trait(_, _, ref generics, ..) => {
+                    ItemKind::Struct(_, ref generics)
+                    | ItemKind::Union(_, ref generics)
+                    | ItemKind::Enum(_, ref generics)
+                    | ItemKind::Ty(_, ref generics)
+                    | ItemKind::Trait(_, _, ref generics, ..) => {
                         let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
-                        let count = generics.params.iter()
+                        let count = generics
+                            .params
+                            .iter()
                             .filter(|param| param.is_lifetime_param())
                             .count();
                         self.lctx.type_def_lifetime_params.insert(def_id, count);
@@ -285,7 +347,8 @@ impl<'a> LoweringContext<'a> {
 
         impl<'lcx, 'interner> ItemLowerer<'lcx, 'interner> {
             fn with_trait_impl_ref<F>(&mut self, trait_impl_ref: &Option<TraitRef>, f: F)
-                where F: FnOnce(&mut Self)
+            where
+                F: FnOnce(&mut Self),
             {
                 let old = self.lctx.is_in_trait_impl;
                 self.lctx.is_in_trait_impl = if let &None = trait_impl_ref {
@@ -311,22 +374,24 @@ impl<'a> LoweringContext<'a> {
 
                 if item_lowered {
                     let item_lifetimes = match self.lctx.items.get(&item.id).unwrap().node {
-                        hir::Item_::ItemImpl(_,_,_,ref generics,..) |
-                        hir::Item_::ItemTrait(_,_,ref generics,..) =>
-                            generics.lifetimes().cloned().collect::<Vec<_>>(),
+                        hir::Item_::ItemImpl(_, _, _, ref generics, ..)
+                        | hir::Item_::ItemTrait(_, _, ref generics, ..) => {
+                            generics.lifetimes().cloned().collect::<Vec<_>>()
+                        }
                         _ => Vec::new(),
                     };
 
-                    self.lctx.with_parent_impl_lifetime_defs(&item_lifetimes, |this| {
-                        let this = &mut ItemLowerer { lctx: this };
-                        if let ItemKind::Impl(_,_,_,_,ref opt_trait_ref,_,_) = item.node {
-                            this.with_trait_impl_ref(opt_trait_ref, |this| {
-                                visit::walk_item(this, item)
-                            });
-                        } else {
-                            visit::walk_item(this, item);
-                        }
-                    });
+                    self.lctx
+                        .with_parent_impl_lifetime_defs(&item_lifetimes, |this| {
+                            let this = &mut ItemLowerer { lctx: this };
+                            if let ItemKind::Impl(_, _, _, _, ref opt_trait_ref, _, _) = item.node {
+                                this.with_trait_impl_ref(opt_trait_ref, |this| {
+                                    visit::walk_item(this, item)
+                                });
+                            } else {
+                                visit::walk_item(this, item);
+                            }
+                        });
                 }
             }
 
@@ -379,27 +444,26 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn allocate_hir_id_counter<T: Debug>(&mut self,
-                                         owner: NodeId,
-                                         debug: &T) {
+    fn allocate_hir_id_counter<T: Debug>(&mut self, owner: NodeId, debug: &T) {
         if self.item_local_id_counters.insert(owner, 0).is_some() {
-            bug!("Tried to allocate item_local_id_counter for {:?} twice", debug);
+            bug!(
+                "Tried to allocate item_local_id_counter for {:?} twice",
+                debug
+            );
         }
         // Always allocate the first HirId for the owner itself
         self.lower_node_id_with_owner(owner, owner);
     }
 
-    fn lower_node_id_generic<F>(&mut self,
-                                ast_node_id: NodeId,
-                                alloc_hir_id: F)
-                                -> LoweredNodeId
-        where F: FnOnce(&mut Self) -> hir::HirId
+    fn lower_node_id_generic<F>(&mut self, ast_node_id: NodeId, alloc_hir_id: F) -> LoweredNodeId
+    where
+        F: FnOnce(&mut Self) -> hir::HirId,
     {
         if ast_node_id == DUMMY_NODE_ID {
             return LoweredNodeId {
                 node_id: DUMMY_NODE_ID,
                 hir_id: hir::DUMMY_HIR_ID,
-            }
+            };
         }
 
         let min_size = ast_node_id.as_usize() + 1;
@@ -427,11 +491,12 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn with_hir_id_owner<F>(&mut self, owner: NodeId, f: F)
-        where F: FnOnce(&mut Self)
+    where
+        F: FnOnce(&mut Self),
     {
         let counter = self.item_local_id_counters
-                          .insert(owner, HIR_ID_COUNTER_LOCKED)
-                          .unwrap();
+            .insert(owner, HIR_ID_COUNTER_LOCKED)
+            .unwrap();
         let def_index = self.resolver.definitions().opt_def_index(owner).unwrap();
         self.current_hir_id_owner.push((def_index, counter));
         f(self);
@@ -440,7 +505,9 @@ impl<'a> LoweringContext<'a> {
         debug_assert!(def_index == new_def_index);
         debug_assert!(new_counter >= counter);
 
-        let prev = self.item_local_id_counters.insert(owner, new_counter).unwrap();
+        let prev = self.item_local_id_counters
+            .insert(owner, new_counter)
+            .unwrap();
         debug_assert!(prev == HIR_ID_COUNTER_LOCKED);
     }
 
@@ -452,9 +519,8 @@ impl<'a> LoweringContext<'a> {
     /// properly. Calling the method twice with the same NodeId is fine though.
     fn lower_node_id(&mut self, ast_node_id: NodeId) -> LoweredNodeId {
         self.lower_node_id_generic(ast_node_id, |this| {
-            let &mut (def_index, ref mut local_id_counter) = this.current_hir_id_owner
-                                                                 .last_mut()
-                                                                 .unwrap();
+            let &mut (def_index, ref mut local_id_counter) =
+                this.current_hir_id_owner.last_mut().unwrap();
             let local_id = *local_id_counter;
             *local_id_counter += 1;
             hir::HirId {
@@ -464,14 +530,9 @@ impl<'a> LoweringContext<'a> {
         })
     }
 
-    fn lower_node_id_with_owner(&mut self,
-                                ast_node_id: NodeId,
-                                owner: NodeId)
-                                -> LoweredNodeId {
+    fn lower_node_id_with_owner(&mut self, ast_node_id: NodeId, owner: NodeId) -> LoweredNodeId {
         self.lower_node_id_generic(ast_node_id, |this| {
-            let local_id_counter = this.item_local_id_counters
-                                       .get_mut(&owner)
-                                       .unwrap();
+            let local_id_counter = this.item_local_id_counters.get_mut(&owner).unwrap();
             let local_id = *local_id_counter;
 
             // We want to be sure not to modify the counter in the map while it
@@ -489,8 +550,7 @@ impl<'a> LoweringContext<'a> {
         })
     }
 
-    fn record_body(&mut self, value: hir::Expr, decl: Option<&FnDecl>)
-                   -> hir::BodyId {
+    fn record_body(&mut self, value: hir::Expr, decl: Option<&FnDecl>) -> hir::BodyId {
         let body = hir::Body {
             arguments: decl.map_or(hir_vec![], |decl| {
                 decl.inputs.iter().map(|x| self.lower_arg(x)).collect()
@@ -524,8 +584,7 @@ impl<'a> LoweringContext<'a> {
         Symbol::gensym(s)
     }
 
-    fn allow_internal_unstable(&self, reason: CompilerDesugaringKind, span: Span) -> Span
-    {
+    fn allow_internal_unstable(&self, reason: CompilerDesugaringKind, span: Span) -> Span {
         let mark = Mark::fresh(Mark::root());
         mark.set_expn_info(codemap::ExpnInfo {
             call_site: span,
@@ -539,73 +598,139 @@ impl<'a> LoweringContext<'a> {
         span.with_ctxt(SyntaxContext::empty().apply_mark(mark))
     }
 
-    // Creates a new hir::GenericParam for every new lifetime and type parameter
-    // encountered while evaluating `f`. Definitions are created with the parent
-    // provided. If no `parent_id` is provided, no definitions will be returned.
+    /// Creates a new hir::GenericParam for every new lifetime and
+    /// type parameter encountered while evaluating `f`. Definitions
+    /// are created with the parent provided. If no `parent_id` is
+    /// provided, no definitions will be returned.
+    ///
+    /// Presuming that in-band lifetimes are enabled, then
+    /// `self.anonymous_lifetime_mode` will be updated to match the
+    /// argument while `f` is running (and restored afterwards).
     fn collect_in_band_defs<T, F>(
         &mut self,
-        parent_id: Option<DefId>,
-        f: F
-    ) -> (Vec<hir::GenericParam>, T) where F: FnOnce(&mut LoweringContext) -> T
+        parent_id: DefId,
+        anonymous_lifetime_mode: AnonymousLifetimeMode,
+        f: F,
+    ) -> (Vec<hir::GenericParam>, T)
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         assert!(!self.is_collecting_in_band_lifetimes);
         assert!(self.lifetimes_to_define.is_empty());
+        let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode;
+
         self.is_collecting_in_band_lifetimes = self.sess.features_untracked().in_band_lifetimes;
+        if self.is_collecting_in_band_lifetimes {
+            self.anonymous_lifetime_mode = anonymous_lifetime_mode;
+        }
 
         assert!(self.in_band_ty_params.is_empty());
-
         let res = f(self);
 
         self.is_collecting_in_band_lifetimes = false;
+        self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
 
         let in_band_ty_params = self.in_band_ty_params.split_off(0);
         let lifetimes_to_define = self.lifetimes_to_define.split_off(0);
 
-        let mut params = match parent_id {
-            Some(parent_id) => lifetimes_to_define.into_iter().map(|(span, name)| {
-                    let def_node_id = self.next_id().node_id;
-
-                    // Add a definition for the in-band lifetime def
-                    self.resolver.definitions().create_def_with_parent(
-                        parent_id.index,
-                        def_node_id,
-                        DefPathData::LifetimeDef(name.as_str()),
-                        DefIndexAddressSpace::High,
-                        Mark::root(),
-                        span
-                    );
+        let params = lifetimes_to_define
+            .into_iter()
+            .map(|(span, hir_name)| {
+                let def_node_id = self.next_id().node_id;
+
+                // Get the name we'll use to make the def-path. Note
+                // that collisions are ok here and this shouldn't
+                // really show up for end-user.
+                let str_name = match hir_name {
+                    hir::LifetimeName::Name(n) => n.as_str(),
+                    hir::LifetimeName::Fresh(_) => keywords::UnderscoreLifetime.name().as_str(),
+                    hir::LifetimeName::Implicit
+                    | hir::LifetimeName::Underscore
+                    | hir::LifetimeName::Static => {
+                        span_bug!(span, "unexpected in-band lifetime name: {:?}", hir_name)
+                    }
+                };
 
-                    hir::GenericParam::Lifetime(hir::LifetimeDef {
-                        lifetime: hir::Lifetime {
-                            id: def_node_id,
-                            span,
-                            name: hir::LifetimeName::Name(name),
-                        },
-                        bounds: Vec::new().into(),
-                        pure_wrt_drop: false,
-                        in_band: true,
-                    })
-                }).collect(),
-            None => Vec::new(),
-        };
+                // Add a definition for the in-band lifetime def
+                self.resolver.definitions().create_def_with_parent(
+                    parent_id.index,
+                    def_node_id,
+                    DefPathData::LifetimeDef(str_name),
+                    DefIndexAddressSpace::High,
+                    Mark::root(),
+                    span,
+                );
 
-        params.extend(in_band_ty_params.into_iter().map(|tp| hir::GenericParam::Type(tp)));
+                hir::GenericParam::Lifetime(hir::LifetimeDef {
+                    lifetime: hir::Lifetime {
+                        id: def_node_id,
+                        span,
+                        name: hir_name,
+                    },
+                    bounds: Vec::new().into(),
+                    pure_wrt_drop: false,
+                    in_band: true,
+                })
+            })
+            .chain(
+                in_band_ty_params
+                    .into_iter()
+                    .map(|tp| hir::GenericParam::Type(tp)),
+            )
+            .collect();
 
         (params, res)
     }
 
+    /// When there is a reference to some lifetime `'a`, and in-band
+    /// lifetimes are enabled, then we want to push that lifetime into
+    /// the vector of names to define later. In that case, it will get
+    /// added to the appropriate generics.
+    fn maybe_collect_in_band_lifetime(&mut self, span: Span, name: Name) {
+        if !self.is_collecting_in_band_lifetimes {
+            return;
+        }
+
+        if self.in_scope_lifetimes.contains(&name) {
+            return;
+        }
+
+        let hir_name = hir::LifetimeName::Name(name);
+
+        if self.lifetimes_to_define
+            .iter()
+            .any(|(_, lt_name)| *lt_name == hir_name)
+        {
+            return;
+        }
+
+        self.lifetimes_to_define.push((span, hir_name));
+    }
+
+    /// When we have either an elided or `'_` lifetime in an impl
+    /// header, we convert it to
+    fn collect_fresh_in_band_lifetime(&mut self, span: Span) -> hir::LifetimeName {
+        assert!(self.is_collecting_in_band_lifetimes);
+        let index = self.lifetimes_to_define.len();
+        let hir_name = hir::LifetimeName::Fresh(index);
+        self.lifetimes_to_define.push((span, hir_name));
+        hir_name
+    }
+
     // Evaluates `f` with the lifetimes in `lt_defs` in-scope.
     // This is used to track which lifetimes have already been defined, and
     // which are new in-band lifetimes that need to have a definition created
     // for them.
-    fn with_in_scope_lifetime_defs<T, F>(
+    fn with_in_scope_lifetime_defs<'l, T, F>(
         &mut self,
-        lt_defs: &[LifetimeDef],
-        f: F
-    ) -> T where F: FnOnce(&mut LoweringContext) -> T
+        lt_defs: impl Iterator<Item = &'l LifetimeDef>,
+        f: F,
+    ) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         let old_len = self.in_scope_lifetimes.len();
-        let lt_def_names = lt_defs.iter().map(|lt_def| lt_def.lifetime.ident.name);
+        let lt_def_names = lt_defs.map(|lt_def| lt_def.lifetime.ident.name);
         self.in_scope_lifetimes.extend(lt_def_names);
 
         let res = f(self);
@@ -619,11 +744,9 @@ impl<'a> LoweringContext<'a> {
     // This should only be used with generics that have already had their
     // in-band lifetimes added. In practice, this means that this function is
     // only used when lowering a child item of a trait or impl.
-    fn with_parent_impl_lifetime_defs<T, F>(
-        &mut self,
-        lt_defs: &[hir::LifetimeDef],
-        f: F
-    ) -> T where F: FnOnce(&mut LoweringContext) -> T
+    fn with_parent_impl_lifetime_defs<T, F>(&mut self, lt_defs: &[hir::LifetimeDef], f: F) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         let old_len = self.in_scope_lifetimes.len();
         let lt_def_names = lt_defs.iter().map(|lt_def| lt_def.lifetime.name.name());
@@ -635,47 +758,57 @@ impl<'a> LoweringContext<'a> {
         res
     }
 
-    // Appends in-band lifetime defs and argument-position `impl Trait` defs
-    // to the existing set of generics.
+    /// Appends in-band lifetime defs and argument-position `impl
+    /// Trait` defs to the existing set of generics.
+    ///
+    /// Presuming that in-band lifetimes are enabled, then
+    /// `self.anonymous_lifetime_mode` will be updated to match the
+    /// argument while `f` is running (and restored afterwards).
     fn add_in_band_defs<F, T>(
         &mut self,
         generics: &Generics,
-        parent_id: Option<DefId>,
-        f: F
+        parent_id: DefId,
+        anonymous_lifetime_mode: AnonymousLifetimeMode,
+        f: F,
     ) -> (hir::Generics, T)
-        where F: FnOnce(&mut LoweringContext) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
-        let (in_band_defs, (mut lowered_generics, res)) =
-            self.with_in_scope_lifetime_defs(
-                &generics.params
-                    .iter()
-                    .filter_map(|p| match *p {
-                        GenericParam::Lifetime(ref ld) => Some(ld.clone()),
-                        _ => None,
-                    })
-                    .collect::<Vec<_>>(),
-                |this| {
-                    this.collect_in_band_defs(parent_id, |this| {
-                        (this.lower_generics(generics), f(this))
-                    })
-                }
-            );
+        let (in_band_defs, (mut lowered_generics, res)) = self.with_in_scope_lifetime_defs(
+            generics.params.iter().filter_map(|p| match p {
+                GenericParam::Lifetime(ld) => Some(ld),
+                _ => None,
+            }),
+            |this| {
+                this.collect_in_band_defs(parent_id, anonymous_lifetime_mode, |this| {
+                    (this.lower_generics(generics), f(this))
+                })
+            },
+        );
 
-        lowered_generics.params =
-            lowered_generics.params.iter().cloned().chain(in_band_defs).collect();
+        lowered_generics.params = lowered_generics
+            .params
+            .iter()
+            .cloned()
+            .chain(in_band_defs)
+            .collect();
 
         (lowered_generics, res)
     }
 
     fn with_catch_scope<T, F>(&mut self, catch_id: NodeId, f: F) -> T
-        where F: FnOnce(&mut LoweringContext) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         let len = self.catch_scopes.len();
         self.catch_scopes.push(catch_id);
 
         let result = f(self);
-        assert_eq!(len + 1, self.catch_scopes.len(),
-            "catch scopes should be added and removed in stack order");
+        assert_eq!(
+            len + 1,
+            self.catch_scopes.len(),
+            "catch scopes should be added and removed in stack order"
+        );
 
         self.catch_scopes.pop().unwrap();
 
@@ -683,17 +816,19 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn lower_body<F>(&mut self, decl: Option<&FnDecl>, f: F) -> hir::BodyId
-        where F: FnOnce(&mut LoweringContext) -> hir::Expr
+    where
+        F: FnOnce(&mut LoweringContext) -> hir::Expr,
     {
         let prev = mem::replace(&mut self.is_generator, false);
         let result = f(self);
         let r = self.record_body(result, decl);
         self.is_generator = prev;
-        return r
+        return r;
     }
 
     fn with_loop_scope<T, F>(&mut self, loop_id: NodeId, f: F) -> T
-        where F: FnOnce(&mut LoweringContext) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         // We're no longer in the base loop's condition; we're in another loop.
         let was_in_loop_condition = self.is_in_loop_condition;
@@ -703,8 +838,11 @@ impl<'a> LoweringContext<'a> {
         self.loop_scopes.push(loop_id);
 
         let result = f(self);
-        assert_eq!(len + 1, self.loop_scopes.len(),
-            "Loop scopes should be added and removed in stack order");
+        assert_eq!(
+            len + 1,
+            self.loop_scopes.len(),
+            "Loop scopes should be added and removed in stack order"
+        );
 
         self.loop_scopes.pop().unwrap();
 
@@ -714,7 +852,8 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn with_loop_condition_scope<T, F>(&mut self, f: F) -> T
-        where F: FnOnce(&mut LoweringContext) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         let was_in_loop_condition = self.is_in_loop_condition;
         self.is_in_loop_condition = true;
@@ -727,7 +866,8 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn with_new_scopes<T, F>(&mut self, f: F) -> T
-        where F: FnOnce(&mut LoweringContext) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         let was_in_loop_condition = self.is_in_loop_condition;
         self.is_in_loop_condition = false;
@@ -744,7 +884,8 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn with_parent_def<T, F>(&mut self, parent_id: NodeId, f: F) -> T
-        where F: FnOnce(&mut LoweringContext) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         let old_def = self.parent_def;
         self.parent_def = {
@@ -771,16 +912,19 @@ impl<'a> LoweringContext<'a> {
         if ident.ctxt == SyntaxContext::empty() {
             return ident.name;
         }
-        *self.name_map.entry(ident).or_insert_with(|| Symbol::from_ident(ident))
+        *self.name_map
+            .entry(ident)
+            .or_insert_with(|| Symbol::from_ident(ident))
     }
 
     fn lower_label(&mut self, label: Option<Label>) -> Option<hir::Label> {
-        label.map(|label| hir::Label { name: label.ident.name, span: label.span })
+        label.map(|label| hir::Label {
+            name: label.ident.name,
+            span: label.span,
+        })
     }
 
-    fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>)
-        -> hir::Destination
-    {
+    fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination {
         match destination {
             Some((id, label)) => {
                 let target = if let Def::Label(loop_id) = self.expect_full_def(id) {
@@ -792,25 +936,31 @@ impl<'a> LoweringContext<'a> {
                     label: self.lower_label(Some(label)),
                     target_id: hir::ScopeTarget::Loop(target),
                 }
-            },
+            }
             None => {
                 let loop_id = self.loop_scopes
-                                  .last()
-                                  .map(|innermost_loop_id| *innermost_loop_id);
+                    .last()
+                    .map(|innermost_loop_id| *innermost_loop_id);
 
                 hir::Destination {
                     label: None,
                     target_id: hir::ScopeTarget::Loop(
-                        loop_id.map(|id| Ok(self.lower_node_id(id).node_id))
-                               .unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
-                               .into())
+                        loop_id
+                            .map(|id| Ok(self.lower_node_id(id).node_id))
+                            .unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
+                            .into(),
+                    ),
                 }
             }
         }
     }
 
     fn lower_attrs(&mut self, attrs: &[Attribute]) -> hir::HirVec<Attribute> {
-        attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into()
+        attrs
+            .iter()
+            .map(|a| self.lower_attr(a))
+            .collect::<Vec<_>>()
+            .into()
     }
 
     fn lower_attr(&mut self, attr: &Attribute) -> Attribute {
@@ -825,22 +975,22 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn lower_token_stream(&mut self, tokens: TokenStream) -> TokenStream {
-        tokens.into_trees()
+        tokens
+            .into_trees()
             .flat_map(|tree| self.lower_token_tree(tree).into_trees())
             .collect()
     }
 
     fn lower_token_tree(&mut self, tree: TokenTree) -> TokenStream {
         match tree {
-            TokenTree::Token(span, token) => {
-                self.lower_token(token, span)
-            }
-            TokenTree::Delimited(span, delimited) => {
-                TokenTree::Delimited(span, Delimited {
+            TokenTree::Token(span, token) => self.lower_token(token, span),
+            TokenTree::Delimited(span, delimited) => TokenTree::Delimited(
+                span,
+                Delimited {
                     delim: delimited.delim,
                     tts: self.lower_token_stream(delimited.tts.into()).into(),
-                }).into()
-            }
+                },
+            ).into(),
         }
     }
 
@@ -882,27 +1032,25 @@ impl<'a> LoweringContext<'a> {
                 let span = t.span.shrink_to_lo();
                 let lifetime = match *region {
                     Some(ref lt) => self.lower_lifetime(lt),
-                    None => self.elided_lifetime(span)
+                    None => self.elided_ref_lifetime(span),
                 };
                 hir::TyRptr(lifetime, self.lower_mt(mt, itctx))
             }
-            TyKind::BareFn(ref f) => {
-                self.with_in_scope_lifetime_defs(
-                    &f.generic_params
-                        .iter()
-                        .filter_map(|p| match *p {
-                            GenericParam::Lifetime(ref ld) => Some(ld.clone()),
-                            _ => None,
-                        })
-                        .collect::<Vec<_>>(),
-                    |this| hir::TyBareFn(P(hir::BareFnTy {
+            TyKind::BareFn(ref f) => self.with_in_scope_lifetime_defs(
+                f.generic_params.iter().filter_map(|p| match p {
+                    GenericParam::Lifetime(ld) => Some(ld),
+                    _ => None,
+                }),
+                |this| {
+                    hir::TyBareFn(P(hir::BareFnTy {
                         generic_params: this.lower_generic_params(&f.generic_params, &NodeMap()),
                         unsafety: this.lower_unsafety(f.unsafety),
                         abi: f.abi,
                         decl: this.lower_fn_decl(&f.decl, None, false),
                         arg_names: this.lower_fn_args_to_names(&f.decl),
-                    })))
-            }
+                    }))
+                },
+            ),
             TyKind::Never => hir::TyNever,
             TyKind::Tup(ref tys) => {
                 hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty, itctx)).collect())
@@ -919,15 +1067,14 @@ impl<'a> LoweringContext<'a> {
                 }
                 return ty;
             }
-            TyKind::ImplicitSelf => {
-                hir::TyPath(hir::QPath::Resolved(None, P(hir::Path {
+            TyKind::ImplicitSelf => hir::TyPath(hir::QPath::Resolved(
+                None,
+                P(hir::Path {
                     def: self.expect_full_def(t.id),
-                    segments: hir_vec![
-                        hir::PathSegment::from_name(keywords::SelfType.name())
-                    ],
+                    segments: hir_vec![hir::PathSegment::from_name(keywords::SelfType.name())],
                     span: t.span,
-                })))
-            }
+                }),
+            )),
             TyKind::Array(ref ty, ref length) => {
                 let length = self.lower_body(None, |this| this.lower_expr(length));
                 hir::TyArray(self.lower_ty(ty, itctx), length)
@@ -938,8 +1085,9 @@ impl<'a> LoweringContext<'a> {
             }
             TyKind::TraitObject(ref bounds, kind) => {
                 let mut lifetime_bound = None;
-                let bounds = bounds.iter().filter_map(|bound| {
-                    match *bound {
+                let bounds = bounds
+                    .iter()
+                    .filter_map(|bound| match *bound {
                         TraitTyParamBound(ref ty, TraitBoundModifier::None) => {
                             Some(self.lower_poly_trait_ref(ty, itctx))
                         }
@@ -950,11 +1098,10 @@ impl<'a> LoweringContext<'a> {
                             }
                             None
                         }
-                    }
-                }).collect();
-                let lifetime_bound = lifetime_bound.unwrap_or_else(|| {
-                    self.elided_lifetime(t.span)
-                });
+                    })
+                    .collect();
+                let lifetime_bound =
+                    lifetime_bound.unwrap_or_else(|| self.elided_dyn_bound(t.span));
                 if kind != TraitObjectSyntax::Dyn {
                     self.maybe_lint_bare_trait(t.span, t.id, false);
                 }
@@ -967,33 +1114,44 @@ impl<'a> LoweringContext<'a> {
                     ImplTraitContext::Existential => {
                         let has_feature = self.sess.features_untracked().conservative_impl_trait;
                         if !t.span.allows_unstable() && !has_feature {
-                            emit_feature_err(&self.sess.parse_sess, "conservative_impl_trait",
-                                             t.span, GateIssue::Language,
-                                             "`impl Trait` in return position is experimental");
+                            emit_feature_err(
+                                &self.sess.parse_sess,
+                                "conservative_impl_trait",
+                                t.span,
+                                GateIssue::Language,
+                                "`impl Trait` in return position is experimental",
+                            );
                         }
                         let def_index = self.resolver.definitions().opt_def_index(t.id).unwrap();
                         let hir_bounds = self.lower_bounds(bounds, itctx);
                         let (lifetimes, lifetime_defs) =
                             self.lifetimes_from_impl_trait_bounds(def_index, &hir_bounds);
 
-                        hir::TyImplTraitExistential(hir::ExistTy {
-                            generics: hir::Generics {
-                                params: lifetime_defs,
-                                where_clause: hir::WhereClause {
-                                    id: self.next_id().node_id,
-                                    predicates: Vec::new().into(),
+                        hir::TyImplTraitExistential(
+                            hir::ExistTy {
+                                generics: hir::Generics {
+                                    params: lifetime_defs,
+                                    where_clause: hir::WhereClause {
+                                        id: self.next_id().node_id,
+                                        predicates: Vec::new().into(),
+                                    },
+                                    span,
                                 },
-                                span,
+                                bounds: hir_bounds,
                             },
-                            bounds: hir_bounds,
-                        }, lifetimes)
-                    },
+                            lifetimes,
+                        )
+                    }
                     ImplTraitContext::Universal(def_id) => {
                         let has_feature = self.sess.features_untracked().universal_impl_trait;
                         if !t.span.allows_unstable() && !has_feature {
-                            emit_feature_err(&self.sess.parse_sess, "universal_impl_trait",
-                                             t.span, GateIssue::Language,
-                                             "`impl Trait` in argument position is experimental");
+                            emit_feature_err(
+                                &self.sess.parse_sess,
+                                "universal_impl_trait",
+                                t.span,
+                                GateIssue::Language,
+                                "`impl Trait` in argument position is experimental",
+                            );
                         }
 
                         let def_node_id = self.next_id().node_id;
@@ -1005,7 +1163,7 @@ impl<'a> LoweringContext<'a> {
                             DefPathData::ImplTrait,
                             DefIndexAddressSpace::High,
                             Mark::root(),
-                            span
+                            span,
                         );
 
                         let hir_bounds = self.lower_bounds(bounds, itctx);
@@ -1022,16 +1180,23 @@ impl<'a> LoweringContext<'a> {
                             attrs: P::new(),
                         });
 
-                        hir::TyPath(hir::QPath::Resolved(None, P(hir::Path {
-                            span,
-                            def: Def::TyParam(DefId::local(def_index)),
-                            segments: hir_vec![hir::PathSegment::from_name(name)],
-                        })))
-                    },
+                        hir::TyPath(hir::QPath::Resolved(
+                            None,
+                            P(hir::Path {
+                                span,
+                                def: Def::TyParam(DefId::local(def_index)),
+                                segments: hir_vec![hir::PathSegment::from_name(name)],
+                            }),
+                        ))
+                    }
                     ImplTraitContext::Disallowed => {
-                        span_err!(self.sess, t.span, E0562,
-                                  "`impl Trait` not allowed outside of function \
-                                  and inherent method return types");
+                        span_err!(
+                            self.sess,
+                            t.span,
+                            E0562,
+                            "`impl Trait` not allowed outside of function \
+                             and inherent method return types"
+                        );
                         hir::TyErr
                     }
                 }
@@ -1051,9 +1216,8 @@ impl<'a> LoweringContext<'a> {
     fn lifetimes_from_impl_trait_bounds(
         &mut self,
         parent_index: DefIndex,
-        bounds: &hir::TyParamBounds
+        bounds: &hir::TyParamBounds,
     ) -> (HirVec<hir::Lifetime>, HirVec<hir::GenericParam>) {
-
         // This visitor walks over impl trait bounds and creates defs for all lifetimes which
         // appear in the bounds, excluding lifetimes that are created within the bounds.
         // e.g. 'a, 'b, but not 'c in `impl for<'c> SomeTrait<'a, 'b, 'c>`
@@ -1068,8 +1232,9 @@ impl<'a> LoweringContext<'a> {
         }
 
         impl<'r, 'a: 'r, 'v> hir::intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a> {
-            fn nested_visit_map<'this>(&'this mut self)
-                -> hir::intravisit::NestedVisitorMap<'this, 'v> {
+            fn nested_visit_map<'this>(
+                &'this mut self,
+            ) -> hir::intravisit::NestedVisitorMap<'this, 'v> {
                 hir::intravisit::NestedVisitorMap::None
             }
 
@@ -1097,9 +1262,11 @@ impl<'a> LoweringContext<'a> {
                 }
             }
 
-            fn visit_poly_trait_ref(&mut self,
-                                    polytr: &'v hir::PolyTraitRef,
-                                    _: hir::TraitBoundModifier) {
+            fn visit_poly_trait_ref(
+                &mut self,
+                polytr: &'v hir::PolyTraitRef,
+                _: hir::TraitBoundModifier,
+            ) {
                 let old_len = self.currently_bound_lifetimes.len();
 
                 // Record the introduction of 'a in `for<'a> ...`
@@ -1123,21 +1290,22 @@ impl<'a> LoweringContext<'a> {
 
             fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
                 let name = match lifetime.name {
-                    hir::LifetimeName::Implicit |
-                    hir::LifetimeName::Underscore =>
+                    hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => {
                         if self.collect_elided_lifetimes {
                             // Use `'_` for both implicit and underscore lifetimes in
                             // `abstract type Foo<'_>: SomeTrait<'_>;`
                             hir::LifetimeName::Underscore
                         } else {
-                            return
+                            return;
                         }
+                    }
+                    name @ hir::LifetimeName::Fresh(_) => name,
                     name @ hir::LifetimeName::Name(_) => name,
                     hir::LifetimeName::Static => return,
                 };
 
-                if !self.currently_bound_lifetimes.contains(&name) &&
-                   !self.already_defined_lifetimes.contains(&name)
+                if !self.currently_bound_lifetimes.contains(&name)
+                    && !self.already_defined_lifetimes.contains(&name)
                 {
                     self.already_defined_lifetimes.insert(name);
 
@@ -1154,19 +1322,20 @@ impl<'a> LoweringContext<'a> {
                         DefPathData::LifetimeDef(name.name().as_str()),
                         DefIndexAddressSpace::High,
                         Mark::root(),
-                        lifetime.span
+                        lifetime.span,
                     );
                     let def_lifetime = hir::Lifetime {
                         id: def_node_id,
                         span: lifetime.span,
                         name: name,
                     };
-                    self.output_lifetime_params.push(hir::GenericParam::Lifetime(hir::LifetimeDef {
-                        lifetime: def_lifetime,
-                        bounds: Vec::new().into(),
-                        pure_wrt_drop: false,
-                        in_band: false,
-                    }));
+                    self.output_lifetime_params
+                        .push(hir::GenericParam::Lifetime(hir::LifetimeDef {
+                            lifetime: def_lifetime,
+                            bounds: Vec::new().into(),
+                            pure_wrt_drop: false,
+                            in_band: false,
+                        }));
                 }
             }
         }
@@ -1187,14 +1356,17 @@ impl<'a> LoweringContext<'a> {
 
         (
             lifetime_collector.output_lifetimes.into(),
-            lifetime_collector.output_lifetime_params.into()
+            lifetime_collector.output_lifetime_params.into(),
         )
     }
 
     fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
         hir::ForeignMod {
             abi: fm.abi,
-            items: fm.items.iter().map(|x| self.lower_foreign_item(x)).collect(),
+            items: fm.items
+                .iter()
+                .map(|x| self.lower_foreign_item(x))
+                .collect(),
         }
     }
 
@@ -1211,94 +1383,116 @@ impl<'a> LoweringContext<'a> {
                 name: v.node.name.name,
                 attrs: self.lower_attrs(&v.node.attrs),
                 data: self.lower_variant_data(&v.node.data),
-                disr_expr: v.node.disr_expr.as_ref().map(|e| {
-                    self.lower_body(None, |this| this.lower_expr(e))
-                }),
+                disr_expr: v.node
+                    .disr_expr
+                    .as_ref()
+                    .map(|e| self.lower_body(None, |this| this.lower_expr(e))),
             },
             span: v.span,
         }
     }
 
-    fn lower_qpath(&mut self,
-                   id: NodeId,
-                   qself: &Option<QSelf>,
-                   p: &Path,
-                   param_mode: ParamMode,
-                   itctx: ImplTraitContext)
-                   -> hir::QPath {
+    fn lower_qpath(
+        &mut self,
+        id: NodeId,
+        qself: &Option<QSelf>,
+        p: &Path,
+        param_mode: ParamMode,
+        itctx: ImplTraitContext,
+    ) -> hir::QPath {
         let qself_position = qself.as_ref().map(|q| q.position);
         let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx));
 
-        let resolution = self.resolver.get_resolution(id)
-                                      .unwrap_or(PathResolution::new(Def::Err));
+        let resolution = self.resolver
+            .get_resolution(id)
+            .unwrap_or(PathResolution::new(Def::Err));
 
         let proj_start = p.segments.len() - resolution.unresolved_segments();
         let path = P(hir::Path {
             def: resolution.base_def(),
-            segments: p.segments[..proj_start].iter().enumerate().map(|(i, segment)| {
-                let param_mode = match (qself_position, param_mode) {
-                    (Some(j), ParamMode::Optional) if i < j => {
-                        // This segment is part of the trait path in a
-                        // qualified path - one of `a`, `b` or `Trait`
-                        // in `<X as a::b::Trait>::T::U::method`.
-                        ParamMode::Explicit
-                    }
-                    _ => param_mode
-                };
+            segments: p.segments[..proj_start]
+                .iter()
+                .enumerate()
+                .map(|(i, segment)| {
+                    let param_mode = match (qself_position, param_mode) {
+                        (Some(j), ParamMode::Optional) if i < j => {
+                            // This segment is part of the trait path in a
+                            // qualified path - one of `a`, `b` or `Trait`
+                            // in `<X as a::b::Trait>::T::U::method`.
+                            ParamMode::Explicit
+                        }
+                        _ => param_mode,
+                    };
 
-                // Figure out if this is a type/trait segment,
-                // which may need lifetime elision performed.
-                let parent_def_id = |this: &mut Self, def_id: DefId| {
-                    DefId {
+                    // Figure out if this is a type/trait segment,
+                    // which may need lifetime elision performed.
+                    let parent_def_id = |this: &mut Self, def_id: DefId| DefId {
                         krate: def_id.krate,
-                        index: this.def_key(def_id).parent.expect("missing parent")
-                    }
-                };
-                let type_def_id = match resolution.base_def() {
-                    Def::AssociatedTy(def_id) if i + 2 == proj_start => {
-                        Some(parent_def_id(self, def_id))
-                    }
-                    Def::Variant(def_id) if i + 1 == proj_start => {
-                        Some(parent_def_id(self, def_id))
-                    }
-                    Def::Struct(def_id) |
-                    Def::Union(def_id) |
-                    Def::Enum(def_id) |
-                    Def::TyAlias(def_id) |
-                    Def::Trait(def_id) if i + 1 == proj_start => Some(def_id),
-                    _ => None
-                };
-                let parenthesized_generic_args = match resolution.base_def() {
-                    // `a::b::Trait(Args)`
-                    Def::Trait(..) if i + 1 == proj_start => ParenthesizedGenericArgs::Ok,
-                    // `a::b::Trait(Args)::TraitItem`
-                    Def::Method(..) |
-                    Def::AssociatedConst(..) |
-                    Def::AssociatedTy(..) if i + 2 == proj_start => ParenthesizedGenericArgs::Ok,
-                    // Avoid duplicated errors
-                    Def::Err => ParenthesizedGenericArgs::Ok,
-                    // An error
-                    Def::Struct(..) | Def::Enum(..) | Def::Union(..) | Def::TyAlias(..) |
-                    Def::Variant(..) if i + 1 == proj_start => ParenthesizedGenericArgs::Err,
-                    // A warning for now, for compatibility reasons
-                    _ => ParenthesizedGenericArgs::Warn,
-                };
+                        index: this.def_key(def_id).parent.expect("missing parent"),
+                    };
+                    let type_def_id = match resolution.base_def() {
+                        Def::AssociatedTy(def_id) if i + 2 == proj_start => {
+                            Some(parent_def_id(self, def_id))
+                        }
+                        Def::Variant(def_id) if i + 1 == proj_start => {
+                            Some(parent_def_id(self, def_id))
+                        }
+                        Def::Struct(def_id)
+                        | Def::Union(def_id)
+                        | Def::Enum(def_id)
+                        | Def::TyAlias(def_id)
+                        | Def::Trait(def_id) if i + 1 == proj_start =>
+                        {
+                            Some(def_id)
+                        }
+                        _ => None,
+                    };
+                    let parenthesized_generic_args = match resolution.base_def() {
+                        // `a::b::Trait(Args)`
+                        Def::Trait(..) if i + 1 == proj_start => ParenthesizedGenericArgs::Ok,
+                        // `a::b::Trait(Args)::TraitItem`
+                        Def::Method(..) | Def::AssociatedConst(..) | Def::AssociatedTy(..)
+                            if i + 2 == proj_start =>
+                        {
+                            ParenthesizedGenericArgs::Ok
+                        }
+                        // Avoid duplicated errors
+                        Def::Err => ParenthesizedGenericArgs::Ok,
+                        // An error
+                        Def::Struct(..)
+                        | Def::Enum(..)
+                        | Def::Union(..)
+                        | Def::TyAlias(..)
+                        | Def::Variant(..) if i + 1 == proj_start =>
+                        {
+                            ParenthesizedGenericArgs::Err
+                        }
+                        // A warning for now, for compatibility reasons
+                        _ => ParenthesizedGenericArgs::Warn,
+                    };
 
-                let num_lifetimes = type_def_id.map_or(0, |def_id| {
-                    if let Some(&n) = self.type_def_lifetime_params.get(&def_id) {
-                        return n;
-                    }
-                    assert!(!def_id.is_local());
-                    let n = self.cstore
-                                .item_generics_cloned_untracked(def_id, self.sess)
-                                .regions
-                                .len();
-                    self.type_def_lifetime_params.insert(def_id, n);
-                    n
-                });
-                self.lower_path_segment(p.span, segment, param_mode, num_lifetimes,
-                                        parenthesized_generic_args, itctx)
-            }).collect(),
+                    let num_lifetimes = type_def_id.map_or(0, |def_id| {
+                        if let Some(&n) = self.type_def_lifetime_params.get(&def_id) {
+                            return n;
+                        }
+                        assert!(!def_id.is_local());
+                        let n = self.cstore
+                            .item_generics_cloned_untracked(def_id, self.sess)
+                            .regions
+                            .len();
+                        self.type_def_lifetime_params.insert(def_id, n);
+                        n
+                    });
+                    self.lower_path_segment(
+                        p.span,
+                        segment,
+                        param_mode,
+                        num_lifetimes,
+                        parenthesized_generic_args,
+                        itctx,
+                    )
+                })
+                .collect(),
             span: p.span,
         });
 
@@ -1332,9 +1526,14 @@ impl<'a> LoweringContext<'a> {
         //   3. `<<std::vec::Vec<T>>::IntoIter>::Item`
         // * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
         for (i, segment) in p.segments.iter().enumerate().skip(proj_start) {
-            let segment = P(self.lower_path_segment(p.span, segment, param_mode, 0,
-                                                    ParenthesizedGenericArgs::Warn,
-                                                    itctx));
+            let segment = P(self.lower_path_segment(
+                p.span,
+                segment,
+                param_mode,
+                0,
+                ParenthesizedGenericArgs::Warn,
+                itctx,
+            ));
             let qpath = hir::QPath::TypeRelative(ty, segment);
 
             // It's finished, return the extension of the right node type.
@@ -1348,44 +1547,54 @@ impl<'a> LoweringContext<'a> {
         }
 
         // Should've returned in the for loop above.
-        span_bug!(p.span, "lower_qpath: no final extension segment in {}..{}",
-                  proj_start, p.segments.len())
+        span_bug!(
+            p.span,
+            "lower_qpath: no final extension segment in {}..{}",
+            proj_start,
+            p.segments.len()
+        )
     }
 
-    fn lower_path_extra(&mut self,
-                        id: NodeId,
-                        p: &Path,
-                        name: Option<Name>,
-                        param_mode: ParamMode)
-                        -> hir::Path {
+    fn lower_path_extra(
+        &mut self,
+        id: NodeId,
+        p: &Path,
+        name: Option<Name>,
+        param_mode: ParamMode,
+    ) -> hir::Path {
         hir::Path {
             def: self.expect_full_def(id),
-            segments: p.segments.iter().map(|segment| {
-                self.lower_path_segment(p.span, segment, param_mode, 0,
-                                        ParenthesizedGenericArgs::Err,
-                                        ImplTraitContext::Disallowed)
-            }).chain(name.map(|name| hir::PathSegment::from_name(name)))
-              .collect(),
+            segments: p.segments
+                .iter()
+                .map(|segment| {
+                    self.lower_path_segment(
+                        p.span,
+                        segment,
+                        param_mode,
+                        0,
+                        ParenthesizedGenericArgs::Err,
+                        ImplTraitContext::Disallowed,
+                    )
+                })
+                .chain(name.map(|name| hir::PathSegment::from_name(name)))
+                .collect(),
             span: p.span,
         }
     }
 
-    fn lower_path(&mut self,
-                  id: NodeId,
-                  p: &Path,
-                  param_mode: ParamMode)
-                  -> hir::Path {
+    fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path {
         self.lower_path_extra(id, p, None, param_mode)
     }
 
-    fn lower_path_segment(&mut self,
-                          path_span: Span,
-                          segment: &PathSegment,
-                          param_mode: ParamMode,
-                          expected_lifetimes: usize,
-                          parenthesized_generic_args: ParenthesizedGenericArgs,
-                          itctx: ImplTraitContext)
-                          -> hir::PathSegment {
+    fn lower_path_segment(
+        &mut self,
+        path_span: Span,
+        segment: &PathSegment,
+        param_mode: ParamMode,
+        expected_lifetimes: usize,
+        parenthesized_generic_args: ParenthesizedGenericArgs,
+        itctx: ImplTraitContext,
+    ) -> hir::PathSegment {
         let (mut parameters, infer_types) = if let Some(ref parameters) = segment.parameters {
             let msg = "parenthesized parameters may only be used with a trait";
             match **parameters {
@@ -1393,74 +1602,108 @@ impl<'a> LoweringContext<'a> {
                     self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
                 }
                 PathParameters::Parenthesized(ref data) => match parenthesized_generic_args {
-                    ParenthesizedGenericArgs::Ok =>
-                        self.lower_parenthesized_parameter_data(data),
+                    ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
                     ParenthesizedGenericArgs::Warn => {
-                        self.sess.buffer_lint(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
-                                              CRATE_NODE_ID, data.span, msg.into());
+                        self.sess.buffer_lint(
+                            PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
+                            CRATE_NODE_ID,
+                            data.span,
+                            msg.into(),
+                        );
                         (hir::PathParameters::none(), true)
                     }
                     ParenthesizedGenericArgs::Err => {
                         struct_span_err!(self.sess, data.span, E0214, "{}", msg)
-                            .span_label(data.span, "only traits may use parentheses").emit();
+                            .span_label(data.span, "only traits may use parentheses")
+                            .emit();
                         (hir::PathParameters::none(), true)
                     }
-                }
+                },
             }
         } else {
             self.lower_angle_bracketed_parameter_data(&Default::default(), param_mode, itctx)
         };
 
         if !parameters.parenthesized && parameters.lifetimes.is_empty() {
-            parameters.lifetimes = (0..expected_lifetimes).map(|_| {
-                self.elided_lifetime(path_span)
-            }).collect();
+            parameters.lifetimes = self.elided_path_lifetimes(path_span, expected_lifetimes);
         }
 
         hir::PathSegment::new(
             self.lower_ident(segment.identifier),
             parameters,
-            infer_types
+            infer_types,
         )
     }
 
-    fn lower_angle_bracketed_parameter_data(&mut self,
-                                            data: &AngleBracketedParameterData,
-                                            param_mode: ParamMode,
-                                            itctx: ImplTraitContext)
-                                            -> (hir::PathParameters, bool) {
-        let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings, .. } = data;
-        (hir::PathParameters {
-            lifetimes: self.lower_lifetimes(lifetimes),
-            types: types.iter().map(|ty| self.lower_ty(ty, itctx)).collect(),
-            bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx)).collect(),
-            parenthesized: false,
-        }, types.is_empty() && param_mode == ParamMode::Optional)
+    fn lower_angle_bracketed_parameter_data(
+        &mut self,
+        data: &AngleBracketedParameterData,
+        param_mode: ParamMode,
+        itctx: ImplTraitContext,
+    ) -> (hir::PathParameters, bool) {
+        let &AngleBracketedParameterData {
+            ref lifetimes,
+            ref types,
+            ref bindings,
+            ..
+        } = data;
+        (
+            hir::PathParameters {
+                lifetimes: self.lower_lifetimes(lifetimes),
+                types: types.iter().map(|ty| self.lower_ty(ty, itctx)).collect(),
+                bindings: bindings
+                    .iter()
+                    .map(|b| self.lower_ty_binding(b, itctx))
+                    .collect(),
+                parenthesized: false,
+            },
+            types.is_empty() && param_mode == ParamMode::Optional,
+        )
     }
 
-    fn lower_parenthesized_parameter_data(&mut self,
-                                          data: &ParenthesizedParameterData)
-                                          -> (hir::PathParameters, bool) {
+    fn lower_parenthesized_parameter_data(
+        &mut self,
+        data: &ParenthesizedParameterData,
+    ) -> (hir::PathParameters, bool) {
         const DISALLOWED: ImplTraitContext = ImplTraitContext::Disallowed;
-        let &ParenthesizedParameterData { ref inputs, ref output, span } = data;
-        let inputs = inputs.iter().map(|ty| self.lower_ty(ty, DISALLOWED)).collect();
+        let &ParenthesizedParameterData {
+            ref inputs,
+            ref output,
+            span,
+        } = data;
+        let inputs = inputs
+            .iter()
+            .map(|ty| self.lower_ty(ty, DISALLOWED))
+            .collect();
         let mk_tup = |this: &mut Self, tys, span| {
             let LoweredNodeId { node_id, hir_id } = this.next_id();
-            P(hir::Ty { node: hir::TyTup(tys), id: node_id, hir_id, span })
+            P(hir::Ty {
+                node: hir::TyTup(tys),
+                id: node_id,
+                hir_id,
+                span,
+            })
         };
 
-        (hir::PathParameters {
-            lifetimes: hir::HirVec::new(),
-            types: hir_vec![mk_tup(self, inputs, span)],
-            bindings: hir_vec![hir::TypeBinding {
-                id: self.next_id().node_id,
-                name: Symbol::intern(FN_OUTPUT_NAME),
-                ty: output.as_ref().map(|ty| self.lower_ty(&ty, DISALLOWED))
-                                   .unwrap_or_else(|| mk_tup(self, hir::HirVec::new(), span)),
-                span: output.as_ref().map_or(span, |ty| ty.span),
-            }],
-            parenthesized: true,
-        }, false)
+        (
+            hir::PathParameters {
+                lifetimes: hir::HirVec::new(),
+                types: hir_vec![mk_tup(self, inputs, span)],
+                bindings: hir_vec![
+                    hir::TypeBinding {
+                        id: self.next_id().node_id,
+                        name: Symbol::intern(FN_OUTPUT_NAME),
+                        ty: output
+                            .as_ref()
+                            .map(|ty| self.lower_ty(&ty, DISALLOWED))
+                            .unwrap_or_else(|| mk_tup(self, hir::HirVec::new(), span)),
+                        span: output.as_ref().map_or(span, |ty| ty.span),
+                    }
+                ],
+                parenthesized: true,
+            },
+            false,
+        )
     }
 
     fn lower_local(&mut self, l: &Local) -> P<hir::Local> {
@@ -1468,7 +1711,9 @@ impl<'a> LoweringContext<'a> {
         P(hir::Local {
             id: node_id,
             hir_id,
-            ty: l.ty.as_ref().map(|t| self.lower_ty(t, ImplTraitContext::Disallowed)),
+            ty: l.ty
+                .as_ref()
+                .map(|t| self.lower_ty(t, ImplTraitContext::Disallowed)),
             pat: self.lower_pat(&l.pat),
             init: l.init.as_ref().map(|e| P(self.lower_expr(e))),
             span: l.span,
@@ -1493,24 +1738,22 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn lower_fn_args_to_names(&mut self, decl: &FnDecl)
-                              -> hir::HirVec<Spanned<Name>> {
-        decl.inputs.iter().map(|arg| {
-            match arg.pat.node {
-                PatKind::Ident(_, ident, None) => {
-                    respan(ident.span, ident.node.name)
-                }
+    fn lower_fn_args_to_names(&mut self, decl: &FnDecl) -> hir::HirVec<Spanned<Name>> {
+        decl.inputs
+            .iter()
+            .map(|arg| match arg.pat.node {
+                PatKind::Ident(_, ident, None) => respan(ident.span, ident.node.name),
                 _ => respan(arg.pat.span, keywords::Invalid.name()),
-            }
-        }).collect()
+            })
+            .collect()
     }
 
-
-    fn lower_fn_decl(&mut self,
-                     decl: &FnDecl,
-                     fn_def_id: Option<DefId>,
-                     impl_trait_return_allow: bool)
-                     -> P<hir::FnDecl> {
+    fn lower_fn_decl(
+        &mut self,
+        decl: &FnDecl,
+        fn_def_id: Option<DefId>,
+        impl_trait_return_allow: bool,
+    ) -> P<hir::FnDecl> {
         // NOTE: The two last parameters here have to do with impl Trait. If fn_def_id is Some,
         //       then impl Trait arguments are lowered into generic parameters on the given
         //       fn_def_id, otherwise impl Trait is disallowed. (for now)
@@ -1519,38 +1762,44 @@ impl<'a> LoweringContext<'a> {
         //       return positions as well. This guards against trait declarations and their impls
         //       where impl Trait is disallowed. (again for now)
         P(hir::FnDecl {
-            inputs: decl.inputs.iter()
-                .map(|arg| if let Some(def_id) = fn_def_id {
-                    self.lower_ty(&arg.ty, ImplTraitContext::Universal(def_id))
-                } else {
-                    self.lower_ty(&arg.ty, ImplTraitContext::Disallowed)
-                }).collect(),
+            inputs: decl.inputs
+                .iter()
+                .map(|arg| {
+                    if let Some(def_id) = fn_def_id {
+                        self.lower_ty(&arg.ty, ImplTraitContext::Universal(def_id))
+                    } else {
+                        self.lower_ty(&arg.ty, ImplTraitContext::Disallowed)
+                    }
+                })
+                .collect(),
             output: match decl.output {
                 FunctionRetTy::Ty(ref ty) => match fn_def_id {
-                    Some(_) if impl_trait_return_allow =>
-                        hir::Return(self.lower_ty(ty, ImplTraitContext::Existential)),
+                    Some(_) if impl_trait_return_allow => {
+                        hir::Return(self.lower_ty(ty, ImplTraitContext::Existential))
+                    }
                     _ => hir::Return(self.lower_ty(ty, ImplTraitContext::Disallowed)),
                 },
                 FunctionRetTy::Default(span) => hir::DefaultReturn(span),
             },
             variadic: decl.variadic,
-            has_implicit_self: decl.inputs.get(0).map_or(false, |arg| {
-                match arg.ty.node {
-                    TyKind::ImplicitSelf => true,
-                    TyKind::Rptr(_, ref mt) => mt.ty.node == TyKind::ImplicitSelf,
-                    _ => false
-                }
-            })
+            has_implicit_self: decl.inputs.get(0).map_or(false, |arg| match arg.ty.node {
+                TyKind::ImplicitSelf => true,
+                TyKind::Rptr(_, ref mt) => mt.ty.node == TyKind::ImplicitSelf,
+                _ => false,
+            }),
         })
     }
 
-    fn lower_ty_param_bound(&mut self, tpb: &TyParamBound, itctx: ImplTraitContext)
-                            -> hir::TyParamBound {
+    fn lower_ty_param_bound(
+        &mut self,
+        tpb: &TyParamBound,
+        itctx: ImplTraitContext,
+    ) -> hir::TyParamBound {
         match *tpb {
-            TraitTyParamBound(ref ty, modifier) => {
-                hir::TraitTyParamBound(self.lower_poly_trait_ref(ty, itctx),
-                                       self.lower_trait_bound_modifier(modifier))
-            }
+            TraitTyParamBound(ref ty, modifier) => hir::TraitTyParamBound(
+                self.lower_poly_trait_ref(ty, itctx),
+                self.lower_trait_bound_modifier(modifier),
+            ),
             RegionTyParamBound(ref lifetime) => {
                 hir::RegionTyParamBound(self.lower_lifetime(lifetime))
             }
@@ -1570,48 +1819,60 @@ impl<'a> LoweringContext<'a> {
         let itctx = ImplTraitContext::Universal(self.resolver.definitions().local_def_id(tp.id));
         let mut bounds = self.lower_bounds(&tp.bounds, itctx);
         if !add_bounds.is_empty() {
-            bounds = bounds.into_iter().chain(
-                self.lower_bounds(add_bounds, itctx).into_iter()
-            ).collect();
+            bounds = bounds
+                .into_iter()
+                .chain(self.lower_bounds(add_bounds, itctx).into_iter())
+                .collect();
         }
 
         hir::TyParam {
             id: self.lower_node_id(tp.id).node_id,
             name,
             bounds,
-            default: tp.default.as_ref().map(|x| self.lower_ty(x, ImplTraitContext::Disallowed)),
+            default: tp.default
+                .as_ref()
+                .map(|x| self.lower_ty(x, ImplTraitContext::Disallowed)),
             span: tp.span,
             pure_wrt_drop: attr::contains_name(&tp.attrs, "may_dangle"),
-            synthetic: tp.attrs.iter()
-                               .filter(|attr| attr.check_name("rustc_synthetic"))
-                               .map(|_| hir::SyntheticTyParamKind::ImplTrait)
-                               .nth(0),
+            synthetic: tp.attrs
+                .iter()
+                .filter(|attr| attr.check_name("rustc_synthetic"))
+                .map(|_| hir::SyntheticTyParamKind::ImplTrait)
+                .nth(0),
             attrs: self.lower_attrs(&tp.attrs),
         }
     }
 
     fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
-        let name = match self.lower_ident(l.ident) {
-            x if x == "'_" => hir::LifetimeName::Underscore,
-            x if x == "'static" => hir::LifetimeName::Static,
-            name => {
-                if  self.is_collecting_in_band_lifetimes &&
-                    !self.in_scope_lifetimes.contains(&name) &&
-                    self.lifetimes_to_define.iter()
-                        .find(|&&(_, lt_name)| lt_name == name)
-                        .is_none()
-                {
-                    self.lifetimes_to_define.push((l.span, name));
+        match self.lower_ident(l.ident) {
+            x if x == "'static" => self.new_named_lifetime(l.id, l.span, hir::LifetimeName::Static),
+            x if x == "'_" => match self.anonymous_lifetime_mode {
+                AnonymousLifetimeMode::CreateParameter => {
+                    let fresh_name = self.collect_fresh_in_band_lifetime(l.span);
+                    self.new_named_lifetime(l.id, l.span, fresh_name)
                 }
 
-                hir::LifetimeName::Name(name)
+                AnonymousLifetimeMode::PassThrough => {
+                    self.new_named_lifetime(l.id, l.span, hir::LifetimeName::Underscore)
+                }
+            },
+            name => {
+                self.maybe_collect_in_band_lifetime(l.span, name);
+                self.new_named_lifetime(l.id, l.span, hir::LifetimeName::Name(name))
             }
-        };
+        }
+    }
 
+    fn new_named_lifetime(
+        &mut self,
+        id: NodeId,
+        span: Span,
+        name: hir::LifetimeName,
+    ) -> hir::Lifetime {
         hir::Lifetime {
-            id: self.lower_node_id(l.id).node_id,
-            name,
-            span: l.span,
+            id: self.lower_node_id(id).node_id,
+            span,
+            name: name,
         }
     }
 
@@ -1640,17 +1901,16 @@ impl<'a> LoweringContext<'a> {
         params: &Vec<GenericParam>,
         add_bounds: &NodeMap<Vec<TyParamBound>>,
     ) -> hir::HirVec<hir::GenericParam> {
-        params.iter()
+        params
+            .iter()
             .map(|param| match *param {
                 GenericParam::Lifetime(ref lifetime_def) => {
                     hir::GenericParam::Lifetime(self.lower_lifetime_def(lifetime_def))
                 }
-                GenericParam::Type(ref ty_param) => {
-                    hir::GenericParam::Type(self.lower_ty_param(
-                        ty_param,
-                        add_bounds.get(&ty_param.id).map_or(&[][..], |x| &x)
-                    ))
-                }
+                GenericParam::Type(ref ty_param) => hir::GenericParam::Type(self.lower_ty_param(
+                    ty_param,
+                    add_bounds.get(&ty_param.id).map_or(&[][..], |x| &x),
+                )),
             })
             .collect()
     }
@@ -1666,24 +1926,30 @@ impl<'a> LoweringContext<'a> {
                 'next_bound: for bound in &bound_pred.bounds {
                     if let TraitTyParamBound(_, TraitBoundModifier::Maybe) = *bound {
                         let report_error = |this: &mut Self| {
-                            this.diagnostic().span_err(bound_pred.bounded_ty.span,
-                                                       "`?Trait` bounds are only permitted at the \
-                                                        point where a type parameter is declared");
+                            this.diagnostic().span_err(
+                                bound_pred.bounded_ty.span,
+                                "`?Trait` bounds are only permitted at the \
+                                 point where a type parameter is declared",
+                            );
                         };
                         // Check if the where clause type is a plain type parameter.
                         match bound_pred.bounded_ty.node {
                             TyKind::Path(None, ref path)
-                                    if path.segments.len() == 1 &&
-                                       bound_pred.bound_generic_params.is_empty() => {
-                                if let Some(Def::TyParam(def_id)) =
-                                        self.resolver.get_resolution(bound_pred.bounded_ty.id)
-                                                     .map(|d| d.base_def()) {
+                                if path.segments.len() == 1
+                                    && bound_pred.bound_generic_params.is_empty() =>
+                            {
+                                if let Some(Def::TyParam(def_id)) = self.resolver
+                                    .get_resolution(bound_pred.bounded_ty.id)
+                                    .map(|d| d.base_def())
+                                {
                                     if let Some(node_id) =
-                                            self.resolver.definitions().as_local_node_id(def_id) {
+                                        self.resolver.definitions().as_local_node_id(def_id)
+                                    {
                                         for param in &g.params {
                                             if let GenericParam::Type(ref ty_param) = *param {
                                                 if node_id == ty_param.id {
-                                                    add_bounds.entry(ty_param.id)
+                                                    add_bounds
+                                                        .entry(ty_param.id)
                                                         .or_insert(Vec::new())
                                                         .push(bound.clone());
                                                     continue 'next_bound;
@@ -1694,7 +1960,7 @@ impl<'a> LoweringContext<'a> {
                                 }
                                 report_error(self)
                             }
-                            _ => report_error(self)
+                            _ => report_error(self),
                         }
                     }
                 }
@@ -1712,81 +1978,93 @@ impl<'a> LoweringContext<'a> {
         hir::WhereClause {
             id: self.lower_node_id(wc.id).node_id,
             predicates: wc.predicates
-                          .iter()
-                          .map(|predicate| self.lower_where_predicate(predicate))
-                          .collect(),
+                .iter()
+                .map(|predicate| self.lower_where_predicate(predicate))
+                .collect(),
         }
     }
 
     fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate {
         match *pred {
-            WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_generic_params,
-                                                                ref bounded_ty,
-                                                                ref bounds,
-                                                                span}) => {
+            WherePredicate::BoundPredicate(WhereBoundPredicate {
+                ref bound_generic_params,
+                ref bounded_ty,
+                ref bounds,
+                span,
+            }) => {
                 self.with_in_scope_lifetime_defs(
-                    &bound_generic_params.iter()
-                        .filter_map(|p| match *p {
-                            GenericParam::Lifetime(ref ld) => Some(ld.clone()),
-                            _ => None,
-                        })
-                        .collect::<Vec<_>>(),
+                    bound_generic_params.iter().filter_map(|p| match p {
+                        GenericParam::Lifetime(ld) => Some(ld),
+                        _ => None,
+                    }),
                     |this| {
                         hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
-                            bound_generic_params:
-                                this.lower_generic_params(bound_generic_params, &NodeMap()),
+                            bound_generic_params: this.lower_generic_params(
+                                bound_generic_params,
+                                &NodeMap(),
+                            ),
                             bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::Disallowed),
-                            bounds: bounds.iter().filter_map(|bound| match *bound {
-                                // Ignore `?Trait` bounds.
-                                // Tthey were copied into type parameters already.
-                                TraitTyParamBound(_, TraitBoundModifier::Maybe) => None,
-                                _ => Some(this.lower_ty_param_bound(
-                                        bound, ImplTraitContext::Disallowed))
-                            }).collect(),
+                            bounds: bounds
+                                .iter()
+                                .filter_map(|bound| match *bound {
+                                    // Ignore `?Trait` bounds.
+                                    // Tthey were copied into type parameters already.
+                                    TraitTyParamBound(_, TraitBoundModifier::Maybe) => None,
+                                    _ => Some(this.lower_ty_param_bound(
+                                        bound,
+                                        ImplTraitContext::Disallowed,
+                                    )),
+                                })
+                                .collect(),
                             span,
                         })
-                    }
+                    },
                 )
             }
-            WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime,
-                                                                  ref bounds,
-                                                                  span}) => {
-                hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
-                    span,
-                    lifetime: self.lower_lifetime(lifetime),
-                    bounds: bounds.iter().map(|bound| self.lower_lifetime(bound)).collect(),
-                })
-            }
-            WherePredicate::EqPredicate(WhereEqPredicate{ id,
-                                                          ref lhs_ty,
-                                                          ref rhs_ty,
-                                                          span}) => {
-                hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
-                    id: self.lower_node_id(id).node_id,
-                    lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::Disallowed),
-                    rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::Disallowed),
-                    span,
-                })
-            }
+            WherePredicate::RegionPredicate(WhereRegionPredicate {
+                ref lifetime,
+                ref bounds,
+                span,
+            }) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
+                span,
+                lifetime: self.lower_lifetime(lifetime),
+                bounds: bounds
+                    .iter()
+                    .map(|bound| self.lower_lifetime(bound))
+                    .collect(),
+            }),
+            WherePredicate::EqPredicate(WhereEqPredicate {
+                id,
+                ref lhs_ty,
+                ref rhs_ty,
+                span,
+            }) => hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
+                id: self.lower_node_id(id).node_id,
+                lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::Disallowed),
+                rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::Disallowed),
+                span,
+            }),
         }
     }
 
     fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
         match *vdata {
-            VariantData::Struct(ref fields, id) => {
-                hir::VariantData::Struct(fields.iter()
-                                               .enumerate()
-                                               .map(|f| self.lower_struct_field(f))
-                                               .collect(),
-                                         self.lower_node_id(id).node_id)
-            }
-            VariantData::Tuple(ref fields, id) => {
-                hir::VariantData::Tuple(fields.iter()
-                                              .enumerate()
-                                              .map(|f| self.lower_struct_field(f))
-                                              .collect(),
-                                        self.lower_node_id(id).node_id)
-            }
+            VariantData::Struct(ref fields, id) => hir::VariantData::Struct(
+                fields
+                    .iter()
+                    .enumerate()
+                    .map(|f| self.lower_struct_field(f))
+                    .collect(),
+                self.lower_node_id(id).node_id,
+            ),
+            VariantData::Tuple(ref fields, id) => hir::VariantData::Tuple(
+                fields
+                    .iter()
+                    .enumerate()
+                    .map(|f| self.lower_struct_field(f))
+                    .collect(),
+                self.lower_node_id(id).node_id,
+            ),
             VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id).node_id),
         }
     }
@@ -1794,7 +2072,7 @@ impl<'a> LoweringContext<'a> {
     fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext) -> hir::TraitRef {
         let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
             hir::QPath::Resolved(None, path) => path.and_then(|path| path),
-            qpath => bug!("lower_trait_ref: unexpected QPath `{:?}`", qpath)
+            qpath => bug!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
         };
         hir::TraitRef {
             path,
@@ -1802,13 +2080,15 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn lower_poly_trait_ref(&mut self,
-                            p: &PolyTraitRef,
-                            itctx: ImplTraitContext)
-                            -> hir::PolyTraitRef {
+    fn lower_poly_trait_ref(
+        &mut self,
+        p: &PolyTraitRef,
+        itctx: ImplTraitContext,
+    ) -> hir::PolyTraitRef {
         let bound_generic_params = self.lower_generic_params(&p.bound_generic_params, &NodeMap());
         let trait_ref = self.with_parent_impl_lifetime_defs(
-            &bound_generic_params.iter()
+            &bound_generic_params
+                .iter()
                 .filter_map(|p| match *p {
                     hir::GenericParam::Lifetime(ref ld) => Some(ld.clone()),
                     _ => None,
@@ -1831,7 +2111,10 @@ impl<'a> LoweringContext<'a> {
             name: self.lower_ident(match f.ident {
                 Some(ident) => ident,
                 // FIXME(jseyfried) positional field hygiene
-                None => Ident { name: Symbol::intern(&index.to_string()), ctxt: f.span.ctxt() },
+                None => Ident {
+                    name: Symbol::intern(&index.to_string()),
+                    ctxt: f.span.ctxt(),
+                },
             }),
             vis: self.lower_visibility(&f.vis, None),
             ty: self.lower_ty(&f.ty, ImplTraitContext::Disallowed),
@@ -1855,9 +2138,15 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn lower_bounds(&mut self, bounds: &[TyParamBound], itctx: ImplTraitContext)
-                    -> hir::TyParamBounds {
-        bounds.iter().map(|bound| self.lower_ty_param_bound(bound, itctx)).collect()
+    fn lower_bounds(
+        &mut self,
+        bounds: &[TyParamBound],
+        itctx: ImplTraitContext,
+    ) -> hir::TyParamBounds {
+        bounds
+            .iter()
+            .map(|bound| self.lower_ty_param_bound(bound, itctx))
+            .collect()
     }
 
     fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P<hir::Block> {
@@ -1891,13 +2180,14 @@ impl<'a> LoweringContext<'a> {
         })
     }
 
-    fn lower_item_kind(&mut self,
-                       id: NodeId,
-                       name: &mut Name,
-                       attrs: &hir::HirVec<Attribute>,
-                       vis: &mut hir::Visibility,
-                       i: &ItemKind)
-                       -> hir::Item_ {
+    fn lower_item_kind(
+        &mut self,
+        id: NodeId,
+        name: &mut Name,
+        attrs: &hir::HirVec<Attribute>,
+        vis: &mut hir::Visibility,
+        i: &ItemKind,
+    ) -> hir::Item_ {
         match *i {
             ItemKind::ExternCrate(orig_name) => hir::ItemExternCrate(orig_name),
             ItemKind::Use(ref use_tree) => {
@@ -1911,49 +2201,57 @@ impl<'a> LoweringContext<'a> {
             }
             ItemKind::Static(ref t, m, ref e) => {
                 let value = self.lower_body(None, |this| this.lower_expr(e));
-                hir::ItemStatic(self.lower_ty(t, ImplTraitContext::Disallowed),
-                                self.lower_mutability(m),
-                                value)
+                hir::ItemStatic(
+                    self.lower_ty(t, ImplTraitContext::Disallowed),
+                    self.lower_mutability(m),
+                    value,
+                )
             }
             ItemKind::Const(ref t, ref e) => {
                 let value = self.lower_body(None, |this| this.lower_expr(e));
                 hir::ItemConst(self.lower_ty(t, ImplTraitContext::Disallowed), value)
             }
             ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
-                let fn_def_id = self.resolver.definitions().opt_local_def_id(id);
+                let fn_def_id = self.resolver.definitions().local_def_id(id);
                 self.with_new_scopes(|this| {
                     let body_id = this.lower_body(Some(decl), |this| {
                         let body = this.lower_block(body, false);
                         this.expr_block(body, ThinVec::new())
                     });
-                    let (generics, fn_decl) =
-                        this.add_in_band_defs(generics, fn_def_id, |this|
-                            this.lower_fn_decl(decl, fn_def_id, true));
-
-                    hir::ItemFn(fn_decl,
-                                this.lower_unsafety(unsafety),
-                                this.lower_constness(constness),
-                                abi,
-                                generics,
-                                body_id)
+                    let (generics, fn_decl) = this.add_in_band_defs(
+                        generics,
+                        fn_def_id,
+                        AnonymousLifetimeMode::PassThrough,
+                        |this| this.lower_fn_decl(decl, Some(fn_def_id), true),
+                    );
+
+                    hir::ItemFn(
+                        fn_decl,
+                        this.lower_unsafety(unsafety),
+                        this.lower_constness(constness),
+                        abi,
+                        generics,
+                        body_id,
+                    )
                 })
             }
             ItemKind::Mod(ref m) => hir::ItemMod(self.lower_mod(m)),
             ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(self.lower_foreign_mod(nm)),
             ItemKind::GlobalAsm(ref ga) => hir::ItemGlobalAsm(self.lower_global_asm(ga)),
-            ItemKind::Ty(ref t, ref generics) => {
-                hir::ItemTy(self.lower_ty(t, ImplTraitContext::Disallowed),
-                            self.lower_generics(generics))
-            }
-            ItemKind::Enum(ref enum_definition, ref generics) => {
-                hir::ItemEnum(hir::EnumDef {
-                                  variants: enum_definition.variants
-                                                           .iter()
-                                                           .map(|x| self.lower_variant(x))
-                                                           .collect(),
-                              },
-                              self.lower_generics(generics))
-            }
+            ItemKind::Ty(ref t, ref generics) => hir::ItemTy(
+                self.lower_ty(t, ImplTraitContext::Disallowed),
+                self.lower_generics(generics),
+            ),
+            ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemEnum(
+                hir::EnumDef {
+                    variants: enum_definition
+                        .variants
+                        .iter()
+                        .map(|x| self.lower_variant(x))
+                        .collect(),
+                },
+                self.lower_generics(generics),
+            ),
             ItemKind::Struct(ref struct_def, ref generics) => {
                 let struct_def = self.lower_variant_data(struct_def);
                 hir::ItemStruct(struct_def, self.lower_generics(generics))
@@ -1962,21 +2260,40 @@ impl<'a> LoweringContext<'a> {
                 let vdata = self.lower_variant_data(vdata);
                 hir::ItemUnion(vdata, self.lower_generics(generics))
             }
-            ItemKind::Impl(unsafety,
-                           polarity,
-                           defaultness,
-                           ref ast_generics,
-                           ref ifce,
-                           ref ty,
-                           ref impl_items) => {
-                let def_id = self.resolver.definitions().opt_local_def_id(id);
-                let (generics, (ifce, lowered_ty)) =
-                    self.add_in_band_defs(ast_generics, def_id, |this| {
-                        let ifce = ifce.as_ref().map(|trait_ref| {
+            ItemKind::Impl(
+                unsafety,
+                polarity,
+                defaultness,
+                ref ast_generics,
+                ref trait_ref,
+                ref ty,
+                ref impl_items,
+            ) => {
+                let def_id = self.resolver.definitions().local_def_id(id);
+
+                // Lower the "impl header" first. This ordering is important
+                // for in-band lifetimes! Consider `'a` here:
+                //
+                //     impl Foo<'a> for u32 {
+                //         fn method(&'a self) { .. }
+                //     }
+                //
+                // Because we start by lowering the `Foo<'a> for u32`
+                // part, we will add `'a` to the list of generics on
+                // the impl. When we then encounter it later in the
+                // method, it will not be considered an in-band
+                // lifetime to be added, but rather a reference to a
+                // parent lifetime.
+                let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs(
+                    ast_generics,
+                    def_id,
+                    AnonymousLifetimeMode::CreateParameter,
+                    |this| {
+                        let trait_ref = trait_ref.as_ref().map(|trait_ref| {
                             this.lower_trait_ref(trait_ref, ImplTraitContext::Disallowed)
                         });
 
-                        if let Some(ref trait_ref) = ifce {
+                        if let Some(ref trait_ref) = trait_ref {
                             if let Def::Trait(def_id) = trait_ref.path.def {
                                 this.trait_impls.entry(def_id).or_insert(vec![]).push(id);
                             }
@@ -1984,46 +2301,51 @@ impl<'a> LoweringContext<'a> {
 
                         let lowered_ty = this.lower_ty(ty, ImplTraitContext::Disallowed);
 
-                        (ifce, lowered_ty)
-                    });
+                        (trait_ref, lowered_ty)
+                    },
+                );
 
                 let new_impl_items = self.with_in_scope_lifetime_defs(
-                    &ast_generics.params
-                        .iter()
-                        .filter_map(|p| match *p {
-                            GenericParam::Lifetime(ref ld) => Some(ld.clone()),
-                            _ => None,
-                        })
-                        .collect::<Vec<_>>(),
+                    ast_generics.params.iter().filter_map(|p| match p {
+                        GenericParam::Lifetime(ld) => Some(ld),
+                        _ => None,
+                    }),
                     |this| {
-                        impl_items.iter()
+                        impl_items
+                            .iter()
                             .map(|item| this.lower_impl_item_ref(item))
                             .collect()
-                    }
+                    },
                 );
 
-
-                hir::ItemImpl(self.lower_unsafety(unsafety),
-                              self.lower_impl_polarity(polarity),
-                              self.lower_defaultness(defaultness, true /* [1] */),
-                              generics,
-                              ifce,
-                              lowered_ty,
-                              new_impl_items)
+                hir::ItemImpl(
+                    self.lower_unsafety(unsafety),
+                    self.lower_impl_polarity(polarity),
+                    self.lower_defaultness(defaultness, true /* [1] */),
+                    generics,
+                    trait_ref,
+                    lowered_ty,
+                    new_impl_items,
+                )
             }
             ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
                 let bounds = self.lower_bounds(bounds, ImplTraitContext::Disallowed);
-                let items = items.iter().map(|item| self.lower_trait_item_ref(item)).collect();
-                hir::ItemTrait(self.lower_is_auto(is_auto),
-                               self.lower_unsafety(unsafety),
-                               self.lower_generics(generics),
-                               bounds,
-                               items)
-            }
-            ItemKind::TraitAlias(ref generics, ref bounds) => {
-                hir::ItemTraitAlias(self.lower_generics(generics),
-                                    self.lower_bounds(bounds, ImplTraitContext::Disallowed))
+                let items = items
+                    .iter()
+                    .map(|item| self.lower_trait_item_ref(item))
+                    .collect();
+                hir::ItemTrait(
+                    self.lower_is_auto(is_auto),
+                    self.lower_unsafety(unsafety),
+                    self.lower_generics(generics),
+                    bounds,
+                    items,
+                )
             }
+            ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemTraitAlias(
+                self.lower_generics(generics),
+                self.lower_bounds(bounds, ImplTraitContext::Disallowed),
+            ),
             ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"),
         }
 
@@ -2031,14 +2353,15 @@ impl<'a> LoweringContext<'a> {
         //     not cause an assertion failure inside the `lower_defaultness` function
     }
 
-    fn lower_use_tree(&mut self,
-                       tree: &UseTree,
-                       prefix: &Path,
-                       id: NodeId,
-                       vis: &mut hir::Visibility,
-                       name: &mut Name,
-                       attrs: &hir::HirVec<Attribute>)
-                       -> hir::Item_ {
+    fn lower_use_tree(
+        &mut self,
+        tree: &UseTree,
+        prefix: &Path,
+        id: NodeId,
+        vis: &mut hir::Visibility,
+        name: &mut Name,
+        attrs: &hir::HirVec<Attribute>,
+    ) -> hir::Item_ {
         let path = &tree.prefix;
 
         match tree.kind {
@@ -2047,17 +2370,19 @@ impl<'a> LoweringContext<'a> {
 
                 // First apply the prefix to the path
                 let mut path = Path {
-                    segments: prefix.segments
+                    segments: prefix
+                        .segments
                         .iter()
                         .chain(path.segments.iter())
                         .cloned()
                         .collect(),
-                    span: path.span
+                    span: path.span,
                 };
 
                 // Correctly resolve `self` imports
-                if path.segments.len() > 1 &&
-                   path.segments.last().unwrap().identifier.name == keywords::SelfValue.name() {
+                if path.segments.len() > 1
+                    && path.segments.last().unwrap().identifier.name == keywords::SelfValue.name()
+                {
                     let _ = path.segments.pop();
                     if rename.is_none() {
                         *name = path.segments.last().unwrap().identifier.name;
@@ -2068,19 +2393,25 @@ impl<'a> LoweringContext<'a> {
                 hir::ItemUse(path, hir::UseKind::Single)
             }
             UseTreeKind::Glob => {
-                let path = P(self.lower_path(id, &Path {
-                    segments: prefix.segments
-                        .iter()
-                        .chain(path.segments.iter())
-                        .cloned()
-                        .collect(),
-                    span: path.span,
-                }, ParamMode::Explicit));
+                let path = P(self.lower_path(
+                    id,
+                    &Path {
+                        segments: prefix
+                            .segments
+                            .iter()
+                            .chain(path.segments.iter())
+                            .cloned()
+                            .collect(),
+                        span: path.span,
+                    },
+                    ParamMode::Explicit,
+                ));
                 hir::ItemUse(path, hir::UseKind::Glob)
             }
             UseTreeKind::Nested(ref trees) => {
                 let prefix = Path {
-                    segments: prefix.segments
+                    segments: prefix
+                        .segments
                         .iter()
                         .chain(path.segments.iter())
                         .cloned()
@@ -2098,16 +2429,15 @@ impl<'a> LoweringContext<'a> {
 
                     let mut vis = vis.clone();
                     let mut name = name.clone();
-                    let item = self.lower_use_tree(
-                        use_tree, &prefix, new_id, &mut vis, &mut name, &attrs,
-                    );
+                    let item =
+                        self.lower_use_tree(use_tree, &prefix, new_id, &mut vis, &mut name, &attrs);
 
                     self.with_hir_id_owner(new_id, |this| {
                         let vis = match vis {
                             hir::Visibility::Public => hir::Visibility::Public,
                             hir::Visibility::Crate => hir::Visibility::Crate,
                             hir::Visibility::Inherited => hir::Visibility::Inherited,
-                            hir::Visibility::Restricted { ref path, id: _  } => {
+                            hir::Visibility::Restricted { ref path, id: _ } => {
                                 hir::Visibility::Restricted {
                                     path: path.clone(),
                                     // We are allocating a new NodeId here
@@ -2116,15 +2446,18 @@ impl<'a> LoweringContext<'a> {
                             }
                         };
 
-                        this.items.insert(new_id, hir::Item {
-                            id: new_id,
-                            hir_id: new_hir_id,
-                            name: name,
-                            attrs: attrs.clone(),
-                            node: item,
-                            vis,
-                            span: use_tree.span,
-                        });
+                        this.items.insert(
+                            new_id,
+                            hir::Item {
+                                id: new_id,
+                                hir_id: new_hir_id,
+                                name: name,
+                                attrs: attrs.clone(),
+                                node: item,
+                                vis,
+                                span: use_tree.span,
+                            },
+                        );
                     });
                 }
 
@@ -2141,25 +2474,31 @@ impl<'a> LoweringContext<'a> {
     fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
         self.with_parent_def(i.id, |this| {
             let LoweredNodeId { node_id, hir_id } = this.lower_node_id(i.id);
-            let fn_def_id = this.resolver.definitions().opt_local_def_id(node_id);
+            let trait_item_def_id = this.resolver.definitions().local_def_id(node_id);
 
             let (generics, node) = match i.node {
-                TraitItemKind::Const(ref ty, ref default) => {
-                    (
-                        this.lower_generics(&i.generics),
-                        hir::TraitItemKind::Const(
-                            this.lower_ty(ty, ImplTraitContext::Disallowed),
-                            default.as_ref().map(|x| {
-                                this.lower_body(None, |this| this.lower_expr(x))
-                            }))
-                    )
-                }
+                TraitItemKind::Const(ref ty, ref default) => (
+                    this.lower_generics(&i.generics),
+                    hir::TraitItemKind::Const(
+                        this.lower_ty(ty, ImplTraitContext::Disallowed),
+                        default
+                            .as_ref()
+                            .map(|x| this.lower_body(None, |this| this.lower_expr(x))),
+                    ),
+                ),
                 TraitItemKind::Method(ref sig, None) => {
                     let names = this.lower_fn_args_to_names(&sig.decl);
-                    this.add_in_band_defs(&i.generics, fn_def_id, |this|
-                        hir::TraitItemKind::Method(
-                            this.lower_method_sig(sig, fn_def_id, false),
-                            hir::TraitMethod::Required(names)))
+                    this.add_in_band_defs(
+                        &i.generics,
+                        trait_item_def_id,
+                        AnonymousLifetimeMode::PassThrough,
+                        |this| {
+                            hir::TraitItemKind::Method(
+                                this.lower_method_sig(sig, trait_item_def_id, false),
+                                hir::TraitMethod::Required(names),
+                            )
+                        },
+                    )
                 }
                 TraitItemKind::Method(ref sig, Some(ref body)) => {
                     let body_id = this.lower_body(Some(&sig.decl), |this| {
@@ -2167,21 +2506,27 @@ impl<'a> LoweringContext<'a> {
                         this.expr_block(body, ThinVec::new())
                     });
 
-                    this.add_in_band_defs(&i.generics, fn_def_id, |this|
-                        hir::TraitItemKind::Method(
-                            this.lower_method_sig(sig, fn_def_id, false),
-                           hir::TraitMethod::Provided(body_id)))
-                }
-                TraitItemKind::Type(ref bounds, ref default) => {
-                    (
-                        this.lower_generics(&i.generics),
-                        hir::TraitItemKind::Type(
-                            this.lower_bounds(bounds, ImplTraitContext::Disallowed),
-                            default.as_ref().map(|x| {
-                                this.lower_ty(x, ImplTraitContext::Disallowed)
-                            }))
+                    this.add_in_band_defs(
+                        &i.generics,
+                        trait_item_def_id,
+                        AnonymousLifetimeMode::PassThrough,
+                        |this| {
+                            hir::TraitItemKind::Method(
+                                this.lower_method_sig(sig, trait_item_def_id, false),
+                                hir::TraitMethod::Provided(body_id),
+                            )
+                        },
                     )
                 }
+                TraitItemKind::Type(ref bounds, ref default) => (
+                    this.lower_generics(&i.generics),
+                    hir::TraitItemKind::Type(
+                        this.lower_bounds(bounds, ImplTraitContext::Disallowed),
+                        default
+                            .as_ref()
+                            .map(|x| this.lower_ty(x, ImplTraitContext::Disallowed)),
+                    ),
+                ),
                 TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
             };
 
@@ -2205,11 +2550,12 @@ impl<'a> LoweringContext<'a> {
             TraitItemKind::Type(_, ref default) => {
                 (hir::AssociatedItemKind::Type, default.is_some())
             }
-            TraitItemKind::Method(ref sig, ref default) => {
-                (hir::AssociatedItemKind::Method {
+            TraitItemKind::Method(ref sig, ref default) => (
+                hir::AssociatedItemKind::Method {
                     has_self: sig.decl.has_self(),
-                 }, default.is_some())
-            }
+                },
+                default.is_some(),
+            ),
             TraitItemKind::Macro(..) => unimplemented!(),
         };
         hir::TraitItemRef {
@@ -2224,7 +2570,7 @@ impl<'a> LoweringContext<'a> {
     fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
         self.with_parent_def(i.id, |this| {
             let LoweredNodeId { node_id, hir_id } = this.lower_node_id(i.id);
-            let fn_def_id = this.resolver.definitions().opt_local_def_id(node_id);
+            let impl_item_def_id = this.resolver.definitions().local_def_id(node_id);
 
             let (generics, node) = match i.node {
                 ImplItemKind::Const(ref ty, ref expr) => {
@@ -2233,8 +2579,8 @@ impl<'a> LoweringContext<'a> {
                         this.lower_generics(&i.generics),
                         hir::ImplItemKind::Const(
                             this.lower_ty(ty, ImplTraitContext::Disallowed),
-                            body_id
-                        )
+                            body_id,
+                        ),
                     )
                 }
                 ImplItemKind::Method(ref sig, ref body) => {
@@ -2244,15 +2590,25 @@ impl<'a> LoweringContext<'a> {
                     });
                     let impl_trait_return_allow = !this.is_in_trait_impl;
 
-                    this.add_in_band_defs(&i.generics, fn_def_id, |this|
-                        hir::ImplItemKind::Method(
-                            this.lower_method_sig(sig, fn_def_id, impl_trait_return_allow),
-                            body_id))
+                    this.add_in_band_defs(
+                        &i.generics,
+                        impl_item_def_id,
+                        AnonymousLifetimeMode::PassThrough,
+                        |this| {
+                            hir::ImplItemKind::Method(
+                                this.lower_method_sig(
+                                    sig,
+                                    impl_item_def_id,
+                                    impl_trait_return_allow,
+                                ),
+                                body_id,
+                            )
+                        },
+                    )
                 }
                 ImplItemKind::Type(ref ty) => (
                     this.lower_generics(&i.generics),
-                    hir::ImplItemKind::Type(
-                        this.lower_ty(ty, ImplTraitContext::Disallowed)),
+                    hir::ImplItemKind::Type(this.lower_ty(ty, ImplTraitContext::Disallowed)),
                 ),
                 ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
             };
@@ -2283,10 +2639,8 @@ impl<'a> LoweringContext<'a> {
             kind: match i.node {
                 ImplItemKind::Const(..) => hir::AssociatedItemKind::Const,
                 ImplItemKind::Type(..) => hir::AssociatedItemKind::Type,
-                ImplItemKind::Method(ref sig, _) => {
-                    hir::AssociatedItemKind::Method {
-                        has_self: sig.decl.has_self(),
-                    }
+                ImplItemKind::Method(ref sig, _) => hir::AssociatedItemKind::Method {
+                    has_self: sig.decl.has_self(),
                 },
                 ImplItemKind::Macro(..) => unimplemented!(),
             },
@@ -2317,12 +2671,10 @@ impl<'a> LoweringContext<'a> {
 
     fn lower_item_id_use_tree(&self, tree: &UseTree, vec: &mut SmallVector<hir::ItemId>) {
         match tree.kind {
-            UseTreeKind::Nested(ref nested_vec) => {
-                for &(ref nested, id) in nested_vec {
-                    vec.push(hir::ItemId { id, });
-                    self.lower_item_id_use_tree(nested, vec);
-                }
-            }
+            UseTreeKind::Nested(ref nested_vec) => for &(ref nested, id) in nested_vec {
+                vec.push(hir::ItemId { id });
+                self.lower_item_id_use_tree(nested, vec);
+            },
             UseTreeKind::Glob => {}
             UseTreeKind::Simple(..) => {}
         }
@@ -2375,25 +2727,25 @@ impl<'a> LoweringContext<'a> {
                 attrs: this.lower_attrs(&i.attrs),
                 node: match i.node {
                     ForeignItemKind::Fn(ref fdec, ref generics) => {
-                        // Disallow impl Trait in foreign items
-                        let (generics, (fn_dec, fn_args)) =
-                            this.add_in_band_defs(
-                                generics,
-                                Some(def_id),
-                                |this| (
+                        let (generics, (fn_dec, fn_args)) = this.add_in_band_defs(
+                            generics,
+                            def_id,
+                            AnonymousLifetimeMode::PassThrough,
+                            |this| {
+                                (
+                                    // Disallow impl Trait in foreign items
                                     this.lower_fn_decl(fdec, None, false),
-                                    this.lower_fn_args_to_names(fdec)
+                                    this.lower_fn_args_to_names(fdec),
                                 )
-                            );
+                            },
+                        );
 
                         hir::ForeignItemFn(fn_dec, fn_args, generics)
                     }
                     ForeignItemKind::Static(ref t, m) => {
                         hir::ForeignItemStatic(this.lower_ty(t, ImplTraitContext::Disallowed), m)
                     }
-                    ForeignItemKind::Ty => {
-                        hir::ForeignItemType
-                    }
+                    ForeignItemKind::Ty => hir::ForeignItemType,
                 },
                 vis: this.lower_visibility(&i.vis, None),
                 span: i.span,
@@ -2401,16 +2753,17 @@ impl<'a> LoweringContext<'a> {
         })
     }
 
-    fn lower_method_sig(&mut self,
-                        sig: &MethodSig,
-                        fn_def_id: Option<DefId>,
-                        impl_trait_return_allow: bool)
-                        -> hir::MethodSig {
+    fn lower_method_sig(
+        &mut self,
+        sig: &MethodSig,
+        fn_def_id: DefId,
+        impl_trait_return_allow: bool,
+    ) -> hir::MethodSig {
         hir::MethodSig {
             abi: sig.abi,
             unsafety: self.lower_unsafety(sig.unsafety),
             constness: self.lower_constness(sig.constness),
-            decl: self.lower_fn_decl(&sig.decl, fn_def_id, impl_trait_return_allow),
+            decl: self.lower_fn_decl(&sig.decl, Some(fn_def_id), impl_trait_return_allow),
         }
     }
 
@@ -2478,52 +2831,67 @@ impl<'a> LoweringContext<'a> {
                     def @ None | def @ Some(Def::Local(_)) => {
                         let canonical_id = match def {
                             Some(Def::Local(id)) => id,
-                            _ => p.id
+                            _ => p.id,
                         };
-                        hir::PatKind::Binding(self.lower_binding_mode(binding_mode),
-                                                canonical_id,
-                                                respan(pth1.span, pth1.node.name),
-                                                sub.as_ref().map(|x| self.lower_pat(x)))
+                        hir::PatKind::Binding(
+                            self.lower_binding_mode(binding_mode),
+                            canonical_id,
+                            respan(pth1.span, pth1.node.name),
+                            sub.as_ref().map(|x| self.lower_pat(x)),
+                        )
                     }
-                    Some(def) => {
-                        hir::PatKind::Path(hir::QPath::Resolved(None, P(hir::Path {
+                    Some(def) => hir::PatKind::Path(hir::QPath::Resolved(
+                        None,
+                        P(hir::Path {
                             span: pth1.span,
                             def,
-                            segments: hir_vec![
-                                hir::PathSegment::from_name(pth1.node.name)
-                            ],
-                        })))
-                    }
+                            segments: hir_vec![hir::PathSegment::from_name(pth1.node.name)],
+                        }),
+                    )),
                 }
             }
             PatKind::Lit(ref e) => hir::PatKind::Lit(P(self.lower_expr(e))),
             PatKind::TupleStruct(ref path, ref pats, ddpos) => {
-                let qpath = self.lower_qpath(p.id, &None, path, ParamMode::Optional,
-                                                ImplTraitContext::Disallowed);
-                hir::PatKind::TupleStruct(qpath,
-                                            pats.iter().map(|x| self.lower_pat(x)).collect(),
-                                            ddpos)
-            }
-            PatKind::Path(ref qself, ref path) => {
-                hir::PatKind::Path(self.lower_qpath(p.id, qself, path, ParamMode::Optional,
-                                                    ImplTraitContext::Disallowed))
+                let qpath = self.lower_qpath(
+                    p.id,
+                    &None,
+                    path,
+                    ParamMode::Optional,
+                    ImplTraitContext::Disallowed,
+                );
+                hir::PatKind::TupleStruct(
+                    qpath,
+                    pats.iter().map(|x| self.lower_pat(x)).collect(),
+                    ddpos,
+                )
             }
+            PatKind::Path(ref qself, ref path) => hir::PatKind::Path(self.lower_qpath(
+                p.id,
+                qself,
+                path,
+                ParamMode::Optional,
+                ImplTraitContext::Disallowed,
+            )),
             PatKind::Struct(ref path, ref fields, etc) => {
-                let qpath = self.lower_qpath(p.id, &None, path, ParamMode::Optional,
-                                                ImplTraitContext::Disallowed);
-
-                let fs = fields.iter()
-                                .map(|f| {
-                                    Spanned {
-                                        span: f.span,
-                                        node: hir::FieldPat {
-                                            name: self.lower_ident(f.node.ident),
-                                            pat: self.lower_pat(&f.node.pat),
-                                            is_shorthand: f.node.is_shorthand,
-                                        },
-                                    }
-                                })
-                                .collect();
+                let qpath = self.lower_qpath(
+                    p.id,
+                    &None,
+                    path,
+                    ParamMode::Optional,
+                    ImplTraitContext::Disallowed,
+                );
+
+                let fs = fields
+                    .iter()
+                    .map(|f| Spanned {
+                        span: f.span,
+                        node: hir::FieldPat {
+                            name: self.lower_ident(f.node.ident),
+                            pat: self.lower_pat(&f.node.pat),
+                            is_shorthand: f.node.is_shorthand,
+                        },
+                    })
+                    .collect();
                 hir::PatKind::Struct(qpath, fs, etc)
             }
             PatKind::Tuple(ref elts, ddpos) => {
@@ -2533,16 +2901,16 @@ impl<'a> LoweringContext<'a> {
             PatKind::Ref(ref inner, mutbl) => {
                 hir::PatKind::Ref(self.lower_pat(inner), self.lower_mutability(mutbl))
             }
-            PatKind::Range(ref e1, ref e2, ref end) => {
-                hir::PatKind::Range(P(self.lower_expr(e1)),
-                                    P(self.lower_expr(e2)),
-                                    self.lower_range_end(end))
-            }
-            PatKind::Slice(ref before, ref slice, ref after) => {
-                hir::PatKind::Slice(before.iter().map(|x| self.lower_pat(x)).collect(),
-                            slice.as_ref().map(|x| self.lower_pat(x)),
-                            after.iter().map(|x| self.lower_pat(x)).collect())
-            }
+            PatKind::Range(ref e1, ref e2, ref end) => hir::PatKind::Range(
+                P(self.lower_expr(e1)),
+                P(self.lower_expr(e2)),
+                self.lower_range_end(end),
+            ),
+            PatKind::Slice(ref before, ref slice, ref after) => hir::PatKind::Slice(
+                before.iter().map(|x| self.lower_pat(x)).collect(),
+                slice.as_ref().map(|x| self.lower_pat(x)),
+                after.iter().map(|x| self.lower_pat(x)).collect(),
+            ),
             PatKind::Paren(ref inner) => return self.lower_pat(inner),
             PatKind::Mac(_) => panic!("Shouldn't exist here"),
         };
@@ -2581,9 +2949,7 @@ impl<'a> LoweringContext<'a> {
             // }
             //
             // But for now there are type-inference issues doing that.
-            ExprKind::Box(ref inner) => {
-                hir::ExprBox(P(self.lower_expr(inner)))
-            }
+            ExprKind::Box(ref inner) => hir::ExprBox(P(self.lower_expr(inner))),
 
             // Desugar ExprBox: `in (PLACE) EXPR`
             ExprKind::InPlace(ref placer, ref value_expr) => {
@@ -2624,9 +2990,7 @@ impl<'a> LoweringContext<'a> {
                 };
 
                 // let placer = <placer_expr> ;
-                let (s1, placer_binding) = {
-                    mk_stmt_let(self, placer_ident, placer_expr)
-                };
+                let (s1, placer_binding) = { mk_stmt_let(self, placer_ident, placer_expr) };
 
                 // let mut place = Placer::make_place(placer);
                 let (s2, place_binding) = {
@@ -2645,11 +3009,13 @@ impl<'a> LoweringContext<'a> {
 
                 // pop_unsafe!(EXPR));
                 let pop_unsafe_expr = {
-                    self.signal_block_expr(hir_vec![],
-                                           value_expr,
-                                           e.span,
-                                           hir::PopUnsafeBlock(hir::CompilerGenerated),
-                                           ThinVec::new())
+                    self.signal_block_expr(
+                        hir_vec![],
+                        value_expr,
+                        e.span,
+                        hir::PopUnsafeBlock(hir::CompilerGenerated),
+                        ThinVec::new(),
+                    )
                 };
 
                 // push_unsafe!({
@@ -2658,19 +3024,21 @@ impl<'a> LoweringContext<'a> {
                 // })
                 let expr = {
                     let ptr = self.expr_ident(e.span, p_ptr_ident, p_ptr_binding);
-                    let call_move_val_init =
-                        hir::StmtSemi(
-                            make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
-                            self.next_id().node_id);
+                    let call_move_val_init = hir::StmtSemi(
+                        make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
+                        self.next_id().node_id,
+                    );
                     let call_move_val_init = respan(e.span, call_move_val_init);
 
                     let place = self.expr_ident(e.span, place_ident, place_binding);
                     let call = make_call(self, &inplace_finalize, hir_vec![place]);
-                    P(self.signal_block_expr(hir_vec![call_move_val_init],
-                                             call,
-                                             e.span,
-                                             hir::PushUnsafeBlock(hir::CompilerGenerated),
-                                             ThinVec::new()))
+                    P(self.signal_block_expr(
+                        hir_vec![call_move_val_init],
+                        call,
+                        e.span,
+                        hir::PushUnsafeBlock(hir::CompilerGenerated),
+                        ThinVec::new(),
+                    ))
                 };
 
                 let block = self.block_all(e.span, hir_vec![s1, s2, s3], Some(expr));
@@ -2693,9 +3061,14 @@ impl<'a> LoweringContext<'a> {
                 hir::ExprCall(f, args.iter().map(|x| self.lower_expr(x)).collect())
             }
             ExprKind::MethodCall(ref seg, ref args) => {
-                let hir_seg = self.lower_path_segment(e.span, seg, ParamMode::Optional, 0,
-                                                      ParenthesizedGenericArgs::Err,
-                                                      ImplTraitContext::Disallowed);
+                let hir_seg = self.lower_path_segment(
+                    e.span,
+                    seg,
+                    ParamMode::Optional,
+                    0,
+                    ParenthesizedGenericArgs::Err,
+                    ImplTraitContext::Disallowed,
+                );
                 let args = args.iter().map(|x| self.lower_expr(x)).collect();
                 hir::ExprMethodCall(hir_seg, seg.span, args)
             }
@@ -2733,10 +3106,7 @@ impl<'a> LoweringContext<'a> {
                             // wrap the if-let expr in a block
                             let span = els.span;
                             let els = P(self.lower_expr(els));
-                            let LoweredNodeId {
-                                node_id,
-                                hir_id,
-                            } = self.next_id();
+                            let LoweredNodeId { node_id, hir_id } = self.next_id();
                             let blk = P(hir::Block {
                                 stmts: hir_vec![],
                                 expr: Some(els),
@@ -2758,28 +3128,28 @@ impl<'a> LoweringContext<'a> {
 
                 hir::ExprIf(P(self.lower_expr(cond)), P(then_expr), else_opt)
             }
-            ExprKind::While(ref cond, ref body, opt_label) => {
-                self.with_loop_scope(e.id, |this|
-                    hir::ExprWhile(
-                        this.with_loop_condition_scope(|this| P(this.lower_expr(cond))),
-                        this.lower_block(body, false),
-                        this.lower_label(opt_label)))
-            }
-            ExprKind::Loop(ref body, opt_label) => {
-                self.with_loop_scope(e.id, |this|
-                    hir::ExprLoop(this.lower_block(body, false),
-                                  this.lower_label(opt_label),
-                                  hir::LoopSource::Loop))
-            }
+            ExprKind::While(ref cond, ref body, opt_label) => self.with_loop_scope(e.id, |this| {
+                hir::ExprWhile(
+                    this.with_loop_condition_scope(|this| P(this.lower_expr(cond))),
+                    this.lower_block(body, false),
+                    this.lower_label(opt_label),
+                )
+            }),
+            ExprKind::Loop(ref body, opt_label) => self.with_loop_scope(e.id, |this| {
+                hir::ExprLoop(
+                    this.lower_block(body, false),
+                    this.lower_label(opt_label),
+                    hir::LoopSource::Loop,
+                )
+            }),
             ExprKind::Catch(ref body) => {
-                self.with_catch_scope(body.id, |this|
-                    hir::ExprBlock(this.lower_block(body, true)))
-            }
-            ExprKind::Match(ref expr, ref arms) => {
-                hir::ExprMatch(P(self.lower_expr(expr)),
-                               arms.iter().map(|x| self.lower_arm(x)).collect(),
-                               hir::MatchSource::Normal)
+                self.with_catch_scope(body.id, |this| hir::ExprBlock(this.lower_block(body, true)))
             }
+            ExprKind::Match(ref expr, ref arms) => hir::ExprMatch(
+                P(self.lower_expr(expr)),
+                arms.iter().map(|x| self.lower_arm(x)).collect(),
+                hir::MatchSource::Normal,
+            ),
             ExprKind::Closure(capture_clause, movability, ref decl, ref body, fn_decl_span) => {
                 self.with_new_scopes(|this| {
                     this.with_parent_def(e.id, |this| {
@@ -2791,8 +3161,12 @@ impl<'a> LoweringContext<'a> {
                         });
                         let generator_option = if is_generator {
                             if !decl.inputs.is_empty() {
-                                span_err!(this.sess, fn_decl_span, E0628,
-                                        "generators cannot have explicit arguments");
+                                span_err!(
+                                    this.sess,
+                                    fn_decl_span,
+                                    E0628,
+                                    "generators cannot have explicit arguments"
+                                );
                                 this.sess.abort_if_errors();
                             }
                             Some(match movability {
@@ -2801,16 +3175,22 @@ impl<'a> LoweringContext<'a> {
                             })
                         } else {
                             if movability == Movability::Static {
-                                span_err!(this.sess, fn_decl_span, E0906,
-                                        "closures cannot be static");
+                                span_err!(
+                                    this.sess,
+                                    fn_decl_span,
+                                    E0906,
+                                    "closures cannot be static"
+                                );
                             }
                             None
                         };
-                        hir::ExprClosure(this.lower_capture_clause(capture_clause),
-                                         this.lower_fn_decl(decl, None, false),
-                                         body_id,
-                                         fn_decl_span,
-                                         generator_option)
+                        hir::ExprClosure(
+                            this.lower_capture_clause(capture_clause),
+                            this.lower_fn_decl(decl, None, false),
+                            body_id,
+                            fn_decl_span,
+                            generator_option,
+                        )
                     })
                 })
             }
@@ -2818,18 +3198,16 @@ impl<'a> LoweringContext<'a> {
             ExprKind::Assign(ref el, ref er) => {
                 hir::ExprAssign(P(self.lower_expr(el)), P(self.lower_expr(er)))
             }
-            ExprKind::AssignOp(op, ref el, ref er) => {
-                hir::ExprAssignOp(self.lower_binop(op),
-                                  P(self.lower_expr(el)),
-                                  P(self.lower_expr(er)))
-            }
-            ExprKind::Field(ref el, ident) => {
-                hir::ExprField(P(self.lower_expr(el)),
-                               respan(ident.span, self.lower_ident(ident.node)))
-            }
-            ExprKind::TupField(ref el, ident) => {
-                hir::ExprTupField(P(self.lower_expr(el)), ident)
-            }
+            ExprKind::AssignOp(op, ref el, ref er) => hir::ExprAssignOp(
+                self.lower_binop(op),
+                P(self.lower_expr(el)),
+                P(self.lower_expr(er)),
+            ),
+            ExprKind::Field(ref el, ident) => hir::ExprField(
+                P(self.lower_expr(el)),
+                respan(ident.span, self.lower_ident(ident.node)),
+            ),
+            ExprKind::TupField(ref el, ident) => hir::ExprTupField(P(self.lower_expr(el)), ident),
             ExprKind::Index(ref el, ref er) => {
                 hir::ExprIndex(P(self.lower_expr(el)), P(self.lower_expr(er)))
             }
@@ -2843,25 +3221,27 @@ impl<'a> LoweringContext<'a> {
                     (&Some(..), &Some(..), HalfOpen) => "Range",
                     (&None, &Some(..), Closed) => "RangeToInclusive",
                     (&Some(..), &Some(..), Closed) => "RangeInclusive",
-                    (_, &None, Closed) =>
-                        self.diagnostic().span_fatal(
-                            e.span, "inclusive range with no end").raise(),
+                    (_, &None, Closed) => self.diagnostic()
+                        .span_fatal(e.span, "inclusive range with no end")
+                        .raise(),
                 };
 
-                let fields =
-                    e1.iter().map(|e| ("start", e)).chain(e2.iter().map(|e| ("end", e)))
+                let fields = e1.iter()
+                    .map(|e| ("start", e))
+                    .chain(e2.iter().map(|e| ("end", e)))
                     .map(|(s, e)| {
                         let expr = P(self.lower_expr(&e));
                         let unstable_span =
                             self.allow_internal_unstable(CompilerDesugaringKind::DotFill, e.span);
                         self.field(Symbol::intern(s), expr, unstable_span)
-                    }).collect::<P<[hir::Field]>>();
+                    })
+                    .collect::<P<[hir::Field]>>();
 
                 let is_unit = fields.is_empty();
                 let unstable_span =
                     self.allow_internal_unstable(CompilerDesugaringKind::DotFill, e.span);
-                let struct_path =
-                    iter::once("ops").chain(iter::once(path))
+                let struct_path = iter::once("ops")
+                    .chain(iter::once(path))
                     .collect::<Vec<_>>();
                 let struct_path = self.std_path(unstable_span, &struct_path, is_unit);
                 let struct_path = hir::QPath::Resolved(None, P(struct_path));
@@ -2880,46 +3260,53 @@ impl<'a> LoweringContext<'a> {
                     attrs: e.attrs.clone(),
                 };
             }
-            ExprKind::Path(ref qself, ref path) => {
-                hir::ExprPath(self.lower_qpath(e.id, qself, path, ParamMode::Optional,
-                                               ImplTraitContext::Disallowed))
-            }
+            ExprKind::Path(ref qself, ref path) => hir::ExprPath(self.lower_qpath(
+                e.id,
+                qself,
+                path,
+                ParamMode::Optional,
+                ImplTraitContext::Disallowed,
+            )),
             ExprKind::Break(opt_label, ref opt_expr) => {
                 let destination = if self.is_in_loop_condition && opt_label.is_none() {
                     hir::Destination {
                         label: None,
                         target_id: hir::ScopeTarget::Loop(
-                                Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into()),
+                            Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into(),
+                        ),
                     }
                 } else {
                     self.lower_loop_destination(opt_label.map(|label| (e.id, label)))
                 };
                 hir::ExprBreak(
-                        destination,
-                        opt_expr.as_ref().map(|x| P(self.lower_expr(x))))
-            }
-            ExprKind::Continue(opt_label) =>
-                hir::ExprAgain(
-                    if self.is_in_loop_condition && opt_label.is_none() {
-                        hir::Destination {
-                            label: None,
-                            target_id: hir::ScopeTarget::Loop(Err(
-                                hir::LoopIdError::UnlabeledCfInWhileCondition).into()),
-                        }
-                    } else {
-                        self.lower_loop_destination(opt_label.map(|label| (e.id, label)))
-                    }),
+                    destination,
+                    opt_expr.as_ref().map(|x| P(self.lower_expr(x))),
+                )
+            }
+            ExprKind::Continue(opt_label) => {
+                hir::ExprAgain(if self.is_in_loop_condition && opt_label.is_none() {
+                    hir::Destination {
+                        label: None,
+                        target_id: hir::ScopeTarget::Loop(
+                            Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into(),
+                        ),
+                    }
+                } else {
+                    self.lower_loop_destination(opt_label.map(|label| (e.id, label)))
+                })
+            }
             ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| P(self.lower_expr(x)))),
             ExprKind::InlineAsm(ref asm) => {
                 let hir_asm = hir::InlineAsm {
                     inputs: asm.inputs.iter().map(|&(ref c, _)| c.clone()).collect(),
-                    outputs: asm.outputs.iter().map(|out| {
-                        hir::InlineAsmOutput {
+                    outputs: asm.outputs
+                        .iter()
+                        .map(|out| hir::InlineAsmOutput {
                             constraint: out.constraint.clone(),
                             is_rw: out.is_rw,
                             is_indirect: out.is_indirect,
-                        }
-                    }).collect(),
+                        })
+                        .collect(),
                     asm: asm.asm.clone(),
                     asm_str_style: asm.asm_str_style,
                     clobbers: asm.clobbers.clone().into(),
@@ -2928,18 +3315,27 @@ impl<'a> LoweringContext<'a> {
                     dialect: asm.dialect,
                     ctxt: asm.ctxt,
                 };
-                let outputs =
-                    asm.outputs.iter().map(|out| self.lower_expr(&out.expr)).collect();
-                let inputs =
-                    asm.inputs.iter().map(|&(_, ref input)| self.lower_expr(input)).collect();
+                let outputs = asm.outputs
+                    .iter()
+                    .map(|out| self.lower_expr(&out.expr))
+                    .collect();
+                let inputs = asm.inputs
+                    .iter()
+                    .map(|&(_, ref input)| self.lower_expr(input))
+                    .collect();
                 hir::ExprInlineAsm(P(hir_asm), outputs, inputs)
             }
-            ExprKind::Struct(ref path, ref fields, ref maybe_expr) => {
-                hir::ExprStruct(self.lower_qpath(e.id, &None, path, ParamMode::Optional,
-                                                 ImplTraitContext::Disallowed),
-                                fields.iter().map(|x| self.lower_field(x)).collect(),
-                                maybe_expr.as_ref().map(|x| P(self.lower_expr(x))))
-            }
+            ExprKind::Struct(ref path, ref fields, ref maybe_expr) => hir::ExprStruct(
+                self.lower_qpath(
+                    e.id,
+                    &None,
+                    path,
+                    ParamMode::Optional,
+                    ImplTraitContext::Disallowed,
+                ),
+                fields.iter().map(|x| self.lower_field(x)).collect(),
+                maybe_expr.as_ref().map(|x| P(self.lower_expr(x))),
+            ),
             ExprKind::Paren(ref ex) => {
                 let mut ex = self.lower_expr(ex);
                 // include parens in span, but only if it is a super-span.
@@ -2955,9 +3351,10 @@ impl<'a> LoweringContext<'a> {
 
             ExprKind::Yield(ref opt_expr) => {
                 self.is_generator = true;
-                let expr = opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| {
-                    self.expr(e.span, hir::ExprTup(hir_vec![]), ThinVec::new())
-                });
+                let expr = opt_expr
+                    .as_ref()
+                    .map(|x| self.lower_expr(x))
+                    .unwrap_or_else(|| self.expr(e.span, hir::ExprTup(hir_vec![]), ThinVec::new()));
                 hir::ExprYield(P(expr))
             }
 
@@ -3002,7 +3399,8 @@ impl<'a> LoweringContext<'a> {
                     arms.into(),
                     hir::MatchSource::IfLetDesugar {
                         contains_else_clause,
-                    })
+                    },
+                )
             }
 
             // Desugar ExprWhileLet
@@ -3019,11 +3417,13 @@ impl<'a> LoweringContext<'a> {
 
                 // Note that the block AND the condition are evaluated in the loop scope.
                 // This is done to allow `break` from inside the condition of the loop.
-                let (body, break_expr, sub_expr) = self.with_loop_scope(e.id, |this| (
-                    this.lower_block(body, false),
-                    this.expr_break(e.span, ThinVec::new()),
-                    this.with_loop_condition_scope(|this| P(this.lower_expr(sub_expr))),
-                ));
+                let (body, break_expr, sub_expr) = self.with_loop_scope(e.id, |this| {
+                    (
+                        this.lower_block(body, false),
+                        this.expr_break(e.span, ThinVec::new()),
+                        this.with_loop_condition_scope(|this| P(this.lower_expr(sub_expr))),
+                    )
+                });
 
                 // `<pat> => <body>`
                 let pat_arm = {
@@ -3040,16 +3440,19 @@ impl<'a> LoweringContext<'a> {
 
                 // `match <sub_expr> { ... }`
                 let arms = hir_vec![pat_arm, break_arm];
-                let match_expr = self.expr(sub_expr.span,
-                                           hir::ExprMatch(sub_expr,
-                                                          arms,
-                                                          hir::MatchSource::WhileLetDesugar),
-                                           ThinVec::new());
+                let match_expr = self.expr(
+                    sub_expr.span,
+                    hir::ExprMatch(sub_expr, arms, hir::MatchSource::WhileLetDesugar),
+                    ThinVec::new(),
+                );
 
                 // `[opt_ident]: loop { ... }`
                 let loop_block = P(self.block_expr(P(match_expr)));
-                let loop_expr = hir::ExprLoop(loop_block, self.lower_label(opt_label),
-                                              hir::LoopSource::WhileLet);
+                let loop_expr = hir::ExprLoop(
+                    loop_block,
+                    self.lower_label(opt_label),
+                    hir::LoopSource::WhileLet,
+                );
                 // add attributes to the outer returned expr node
                 loop_expr
             }
@@ -3083,9 +3486,11 @@ impl<'a> LoweringContext<'a> {
                 let iter = self.str_to_ident("iter");
 
                 let next_ident = self.str_to_ident("__next");
-                let next_pat = self.pat_ident_binding_mode(pat.span,
-                                                           next_ident,
-                                                           hir::BindingAnnotation::Mutable);
+                let next_pat = self.pat_ident_binding_mode(
+                    pat.span,
+                    next_ident,
+                    hir::BindingAnnotation::Mutable,
+                );
 
                 // `::std::option::Option::Some(val) => next = val`
                 let pat_arm = {
@@ -3093,25 +3498,26 @@ impl<'a> LoweringContext<'a> {
                     let val_pat = self.pat_ident(pat.span, val_ident);
                     let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat.id));
                     let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat.id));
-                    let assign = P(self.expr(pat.span,
-                                             hir::ExprAssign(next_expr, val_expr),
-                                             ThinVec::new()));
+                    let assign = P(self.expr(
+                        pat.span,
+                        hir::ExprAssign(next_expr, val_expr),
+                        ThinVec::new(),
+                    ));
                     let some_pat = self.pat_some(pat.span, val_pat);
                     self.arm(hir_vec![some_pat], assign)
                 };
 
                 // `::std::option::Option::None => break`
                 let break_arm = {
-                    let break_expr = self.with_loop_scope(e.id, |this|
-                        this.expr_break(e.span, ThinVec::new()));
+                    let break_expr =
+                        self.with_loop_scope(e.id, |this| this.expr_break(e.span, ThinVec::new()));
                     let pat = self.pat_none(e.span);
                     self.arm(hir_vec![pat], break_expr)
                 };
 
                 // `mut iter`
-                let iter_pat = self.pat_ident_binding_mode(head_sp,
-                                                           iter,
-                                                           hir::BindingAnnotation::Mutable);
+                let iter_pat =
+                    self.pat_ident_binding_mode(head_sp, iter, hir::BindingAnnotation::Mutable);
 
                 // `match ::std::iter::Iterator::next(&mut iter) { ... }`
                 let match_expr = {
@@ -3119,46 +3525,48 @@ impl<'a> LoweringContext<'a> {
                     let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter);
                     let next_path = &["iter", "Iterator", "next"];
                     let next_path = P(self.expr_std_path(head_sp, next_path, ThinVec::new()));
-                    let next_expr = P(self.expr_call(head_sp, next_path,
-                                      hir_vec![ref_mut_iter]));
+                    let next_expr = P(self.expr_call(head_sp, next_path, hir_vec![ref_mut_iter]));
                     let arms = hir_vec![pat_arm, break_arm];
 
-                    P(self.expr(head_sp,
-                                hir::ExprMatch(next_expr, arms,
-                                               hir::MatchSource::ForLoopDesugar),
-                                ThinVec::new()))
+                    P(self.expr(
+                        head_sp,
+                        hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar),
+                        ThinVec::new(),
+                    ))
                 };
                 let match_stmt = respan(head_sp, hir::StmtExpr(match_expr, self.next_id().node_id));
 
                 let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat.id));
 
                 // `let mut __next`
-                let next_let = self.stmt_let_pat(head_sp,
-                    None,
-                    next_pat,
-                    hir::LocalSource::ForLoopDesugar);
+                let next_let =
+                    self.stmt_let_pat(head_sp, None, next_pat, hir::LocalSource::ForLoopDesugar);
 
                 // `let <pat> = __next`
                 let pat = self.lower_pat(pat);
-                let pat_let = self.stmt_let_pat(head_sp,
+                let pat_let = self.stmt_let_pat(
+                    head_sp,
                     Some(next_expr),
                     pat,
-                    hir::LocalSource::ForLoopDesugar);
+                    hir::LocalSource::ForLoopDesugar,
+                );
 
                 let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
                 let body_expr = P(self.expr_block(body_block, ThinVec::new()));
                 let body_stmt = respan(body.span, hir::StmtExpr(body_expr, self.next_id().node_id));
 
-                let loop_block = P(self.block_all(e.span,
-                                                  hir_vec![next_let,
-                                                           match_stmt,
-                                                           pat_let,
-                                                           body_stmt],
-                                                  None));
+                let loop_block = P(self.block_all(
+                    e.span,
+                    hir_vec![next_let, match_stmt, pat_let, body_stmt],
+                    None,
+                ));
 
                 // `[opt_ident]: loop { ... }`
-                let loop_expr = hir::ExprLoop(loop_block, self.lower_label(opt_label),
-                                              hir::LoopSource::ForLoop);
+                let loop_expr = hir::ExprLoop(
+                    loop_block,
+                    self.lower_label(opt_label),
+                    hir::LoopSource::ForLoop,
+                );
                 let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
                 let loop_expr = P(hir::Expr {
                     id: node_id,
@@ -3174,15 +3582,16 @@ impl<'a> LoweringContext<'a> {
                 // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
                 let into_iter_expr = {
                     let into_iter_path = &["iter", "IntoIterator", "into_iter"];
-                    let into_iter = P(self.expr_std_path(head_sp, into_iter_path,
-                                                         ThinVec::new()));
+                    let into_iter = P(self.expr_std_path(head_sp, into_iter_path, ThinVec::new()));
                     P(self.expr_call(head_sp, into_iter, hir_vec![head]))
                 };
 
-                let match_expr = P(self.expr_match(head_sp,
-                                                   into_iter_expr,
-                                                   hir_vec![iter_arm],
-                                                   hir::MatchSource::ForLoopDesugar));
+                let match_expr = P(self.expr_match(
+                    head_sp,
+                    into_iter_expr,
+                    hir_vec![iter_arm],
+                    hir::MatchSource::ForLoopDesugar,
+                ));
 
                 // `{ let _result = ...; _result }`
                 // underscore prevents an unused_variables lint if the head diverges
@@ -3242,10 +3651,12 @@ impl<'a> LoweringContext<'a> {
                 let ok_arm = {
                     let val_ident = self.str_to_ident("val");
                     let val_pat = self.pat_ident(e.span, val_ident);
-                    let val_expr = P(self.expr_ident_with_attrs(e.span,
-                                                                val_ident,
-                                                                val_pat.id,
-                                                                ThinVec::from(attrs.clone())));
+                    let val_expr = P(self.expr_ident_with_attrs(
+                        e.span,
+                        val_ident,
+                        val_pat.id,
+                        ThinVec::from(attrs.clone()),
+                    ));
                     let ok_pat = self.pat_ok(e.span, val_pat);
 
                     self.arm(hir_vec![ok_pat], val_expr)
@@ -3265,8 +3676,7 @@ impl<'a> LoweringContext<'a> {
                     };
                     let from_err_expr = {
                         let path = &["ops", "Try", "from_error"];
-                        let from_err = P(self.expr_std_path(unstable_span, path,
-                                                            ThinVec::new()));
+                        let from_err = P(self.expr_std_path(unstable_span, path, ThinVec::new()));
                         P(self.expr_call(e.span, from_err, hir_vec![from_expr]))
                     };
 
@@ -3280,23 +3690,23 @@ impl<'a> LoweringContext<'a> {
                                     label: None,
                                     target_id: hir::ScopeTarget::Block(catch_node),
                                 },
-                                Some(from_err_expr)
+                                Some(from_err_expr),
                             ),
-                            thin_attrs))
+                            thin_attrs,
+                        ))
                     } else {
-                        P(self.expr(e.span,
-                                    hir::Expr_::ExprRet(Some(from_err_expr)),
-                                    thin_attrs))
+                        P(self.expr(e.span, hir::Expr_::ExprRet(Some(from_err_expr)), thin_attrs))
                     };
 
-
                     let err_pat = self.pat_err(e.span, err_local);
                     self.arm(hir_vec![err_pat], ret_expr)
                 };
 
-                hir::ExprMatch(discr,
-                               hir_vec![err_arm, ok_arm],
-                               hir::MatchSource::TryDesugar)
+                hir::ExprMatch(
+                    discr,
+                    hir_vec![err_arm, ok_arm],
+                    hir::MatchSource::TryDesugar,
+                )
             }
 
             ExprKind::Mac(_) => panic!("Shouldn't exist here"),
@@ -3316,39 +3726,42 @@ impl<'a> LoweringContext<'a> {
     fn lower_stmt(&mut self, s: &Stmt) -> SmallVector<hir::Stmt> {
         SmallVector::one(match s.node {
             StmtKind::Local(ref l) => Spanned {
-                node: hir::StmtDecl(P(Spanned {
-                    node: hir::DeclLocal(self.lower_local(l)),
-                    span: s.span,
-                }), self.lower_node_id(s.id).node_id),
+                node: hir::StmtDecl(
+                    P(Spanned {
+                        node: hir::DeclLocal(self.lower_local(l)),
+                        span: s.span,
+                    }),
+                    self.lower_node_id(s.id).node_id,
+                ),
                 span: s.span,
             },
             StmtKind::Item(ref it) => {
                 // Can only use the ID once.
                 let mut id = Some(s.id);
-                return self.lower_item_id(it).into_iter().map(|item_id| Spanned {
-                    node: hir::StmtDecl(P(Spanned {
-                        node: hir::DeclItem(item_id),
+                return self.lower_item_id(it)
+                    .into_iter()
+                    .map(|item_id| Spanned {
+                        node: hir::StmtDecl(
+                            P(Spanned {
+                                node: hir::DeclItem(item_id),
+                                span: s.span,
+                            }),
+                            id.take()
+                                .map(|id| self.lower_node_id(id).node_id)
+                                .unwrap_or_else(|| self.next_id().node_id),
+                        ),
                         span: s.span,
-                    }), id.take()
-                          .map(|id| self.lower_node_id(id).node_id)
-                          .unwrap_or_else(|| self.next_id().node_id)),
-                    span: s.span,
-                }).collect();
-            }
-            StmtKind::Expr(ref e) => {
-                Spanned {
-                    node: hir::StmtExpr(P(self.lower_expr(e)),
-                                          self.lower_node_id(s.id).node_id),
-                    span: s.span,
-                }
-            }
-            StmtKind::Semi(ref e) => {
-                Spanned {
-                    node: hir::StmtSemi(P(self.lower_expr(e)),
-                                          self.lower_node_id(s.id).node_id),
-                    span: s.span,
-                }
+                    })
+                    .collect();
             }
+            StmtKind::Expr(ref e) => Spanned {
+                node: hir::StmtExpr(P(self.lower_expr(e)), self.lower_node_id(s.id).node_id),
+                span: s.span,
+            },
+            StmtKind::Semi(ref e) => Spanned {
+                node: hir::StmtSemi(P(self.lower_expr(e)), self.lower_node_id(s.id).node_id),
+                span: s.span,
+            },
             StmtKind::Mac(..) => panic!("Shouldn't exist here"),
         })
     }
@@ -3365,30 +3778,31 @@ impl<'a> LoweringContext<'a> {
     /// lowered. This can happen during `lower_impl_item_ref()` where we need to
     /// lower a `Visibility` value although we haven't lowered the owning
     /// `ImplItem` in question yet.
-    fn lower_visibility(&mut self,
-                        v: &Visibility,
-                        explicit_owner: Option<NodeId>)
-                        -> hir::Visibility {
+    fn lower_visibility(
+        &mut self,
+        v: &Visibility,
+        explicit_owner: Option<NodeId>,
+    ) -> hir::Visibility {
         match v.node {
             VisibilityKind::Public => hir::Public,
             VisibilityKind::Crate(..) => hir::Visibility::Crate,
-            VisibilityKind::Restricted { ref path, id, .. } => {
-                hir::Visibility::Restricted {
-                    path: P(self.lower_path(id, path, ParamMode::Explicit)),
-                    id: if let Some(owner) = explicit_owner {
-                        self.lower_node_id_with_owner(id, owner).node_id
-                    } else {
-                        self.lower_node_id(id).node_id
-                    }
-                }
-            }
+            VisibilityKind::Restricted { ref path, id, .. } => hir::Visibility::Restricted {
+                path: P(self.lower_path(id, path, ParamMode::Explicit)),
+                id: if let Some(owner) = explicit_owner {
+                    self.lower_node_id_with_owner(id, owner).node_id
+                } else {
+                    self.lower_node_id(id).node_id
+                },
+            },
             VisibilityKind::Inherited => hir::Inherited,
         }
     }
 
     fn lower_defaultness(&mut self, d: Defaultness, has_value: bool) -> hir::Defaultness {
         match d {
-            Defaultness::Default => hir::Defaultness::Default { has_value: has_value },
+            Defaultness::Default => hir::Defaultness::Default {
+                has_value: has_value,
+            },
             Defaultness::Final => {
                 assert!(has_value);
                 hir::Defaultness::Final
@@ -3405,8 +3819,7 @@ impl<'a> LoweringContext<'a> {
 
     fn lower_binding_mode(&mut self, b: &BindingMode) -> hir::BindingAnnotation {
         match *b {
-            BindingMode::ByValue(Mutability::Immutable) =>
-                hir::BindingAnnotation::Unannotated,
+            BindingMode::ByValue(Mutability::Immutable) => hir::BindingAnnotation::Unannotated,
             BindingMode::ByRef(Mutability::Immutable) => hir::BindingAnnotation::Ref,
             BindingMode::ByValue(Mutability::Mutable) => hir::BindingAnnotation::Mutable,
             BindingMode::ByRef(Mutability::Mutable) => hir::BindingAnnotation::RefMut,
@@ -3447,10 +3860,7 @@ impl<'a> LoweringContext<'a> {
 
     fn field(&mut self, name: Name, expr: P<hir::Expr>, span: Span) -> hir::Field {
         hir::Field {
-            name: Spanned {
-                node: name,
-                span,
-            },
+            name: Spanned { node: name, span },
             span,
             expr,
             is_shorthand: false,
@@ -3462,8 +3872,12 @@ impl<'a> LoweringContext<'a> {
         P(self.expr(span, expr_break, attrs))
     }
 
-    fn expr_call(&mut self, span: Span, e: P<hir::Expr>, args: hir::HirVec<hir::Expr>)
-                 -> hir::Expr {
+    fn expr_call(
+        &mut self,
+        span: Span,
+        e: P<hir::Expr>,
+        args: hir::HirVec<hir::Expr>,
+    ) -> hir::Expr {
         self.expr(span, hir::ExprCall(e, args), ThinVec::new())
     }
 
@@ -3471,15 +3885,21 @@ impl<'a> LoweringContext<'a> {
         self.expr_ident_with_attrs(span, id, binding, ThinVec::new())
     }
 
-    fn expr_ident_with_attrs(&mut self, span: Span,
-                                        id: Name,
-                                        binding: NodeId,
-                                        attrs: ThinVec<Attribute>) -> hir::Expr {
-        let expr_path = hir::ExprPath(hir::QPath::Resolved(None, P(hir::Path {
-            span,
-            def: Def::Local(binding),
-            segments: hir_vec![hir::PathSegment::from_name(id)],
-        })));
+    fn expr_ident_with_attrs(
+        &mut self,
+        span: Span,
+        id: Name,
+        binding: NodeId,
+        attrs: ThinVec<Attribute>,
+    ) -> hir::Expr {
+        let expr_path = hir::ExprPath(hir::QPath::Resolved(
+            None,
+            P(hir::Path {
+                span,
+                def: Def::Local(binding),
+                segments: hir_vec![hir::PathSegment::from_name(id)],
+            }),
+        ));
 
         self.expr(span, expr_path, attrs)
     }
@@ -3488,21 +3908,27 @@ impl<'a> LoweringContext<'a> {
         self.expr(span, hir::ExprAddrOf(hir::MutMutable, e), ThinVec::new())
     }
 
-    fn expr_std_path(&mut self,
-                     span: Span,
-                     components: &[&str],
-                     attrs: ThinVec<Attribute>)
-                     -> hir::Expr {
+    fn expr_std_path(
+        &mut self,
+        span: Span,
+        components: &[&str],
+        attrs: ThinVec<Attribute>,
+    ) -> hir::Expr {
         let path = self.std_path(span, components, true);
-        self.expr(span, hir::ExprPath(hir::QPath::Resolved(None, P(path))), attrs)
+        self.expr(
+            span,
+            hir::ExprPath(hir::QPath::Resolved(None, P(path))),
+            attrs,
+        )
     }
 
-    fn expr_match(&mut self,
-                  span: Span,
-                  arg: P<hir::Expr>,
-                  arms: hir::HirVec<hir::Arm>,
-                  source: hir::MatchSource)
-                  -> hir::Expr {
+    fn expr_match(
+        &mut self,
+        span: Span,
+        arg: P<hir::Expr>,
+        arms: hir::HirVec<hir::Arm>,
+        source: hir::MatchSource,
+    ) -> hir::Expr {
         self.expr(span, hir::ExprMatch(arg, arms, source), ThinVec::new())
     }
 
@@ -3525,12 +3951,13 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn stmt_let_pat(&mut self,
-                    sp: Span,
-                    ex: Option<P<hir::Expr>>,
-                    pat: P<hir::Pat>,
-                    source: hir::LocalSource)
-                    -> hir::Stmt {
+    fn stmt_let_pat(
+        &mut self,
+        sp: Span,
+        ex: Option<P<hir::Expr>>,
+        pat: P<hir::Pat>,
+        source: hir::LocalSource,
+    ) -> hir::Stmt {
         let LoweredNodeId { node_id, hir_id } = self.next_id();
 
         let local = P(hir::Local {
@@ -3547,23 +3974,35 @@ impl<'a> LoweringContext<'a> {
         respan(sp, hir::StmtDecl(P(decl), self.next_id().node_id))
     }
 
-    fn stmt_let(&mut self, sp: Span, mutbl: bool, ident: Name, ex: P<hir::Expr>)
-                -> (hir::Stmt, NodeId) {
+    fn stmt_let(
+        &mut self,
+        sp: Span,
+        mutbl: bool,
+        ident: Name,
+        ex: P<hir::Expr>,
+    ) -> (hir::Stmt, NodeId) {
         let pat = if mutbl {
             self.pat_ident_binding_mode(sp, ident, hir::BindingAnnotation::Mutable)
         } else {
             self.pat_ident(sp, ident)
         };
         let pat_id = pat.id;
-        (self.stmt_let_pat(sp, Some(ex), pat, hir::LocalSource::Normal), pat_id)
+        (
+            self.stmt_let_pat(sp, Some(ex), pat, hir::LocalSource::Normal),
+            pat_id,
+        )
     }
 
     fn block_expr(&mut self, expr: P<hir::Expr>) -> hir::Block {
         self.block_all(expr.span, hir::HirVec::new(), Some(expr))
     }
 
-    fn block_all(&mut self, span: Span, stmts: hir::HirVec<hir::Stmt>, expr: Option<P<hir::Expr>>)
-                 -> hir::Block {
+    fn block_all(
+        &mut self,
+        span: Span,
+        stmts: hir::HirVec<hir::Stmt>,
+        expr: Option<P<hir::Expr>>,
+    ) -> hir::Block {
         let LoweredNodeId { node_id, hir_id } = self.next_id();
 
         hir::Block {
@@ -3594,11 +4033,12 @@ impl<'a> LoweringContext<'a> {
         self.pat_std_enum(span, &["option", "Option", "None"], hir_vec![])
     }
 
-    fn pat_std_enum(&mut self,
-                    span: Span,
-                    components: &[&str],
-                    subpats: hir::HirVec<P<hir::Pat>>)
-                    -> P<hir::Pat> {
+    fn pat_std_enum(
+        &mut self,
+        span: Span,
+        components: &[&str],
+        subpats: hir::HirVec<P<hir::Pat>>,
+    ) -> P<hir::Pat> {
         let path = self.std_path(span, components, true);
         let qpath = hir::QPath::Resolved(None, P(path));
         let pt = if subpats.is_empty() {
@@ -3613,20 +4053,18 @@ impl<'a> LoweringContext<'a> {
         self.pat_ident_binding_mode(span, name, hir::BindingAnnotation::Unannotated)
     }
 
-    fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingAnnotation)
-                              -> P<hir::Pat> {
+    fn pat_ident_binding_mode(
+        &mut self,
+        span: Span,
+        name: Name,
+        bm: hir::BindingAnnotation,
+    ) -> P<hir::Pat> {
         let LoweredNodeId { node_id, hir_id } = self.next_id();
 
         P(hir::Pat {
             id: node_id,
             hir_id,
-            node: hir::PatKind::Binding(bm,
-                                        node_id,
-                                        Spanned {
-                                            span,
-                                            node: name,
-                                        },
-                                        None),
+            node: hir::PatKind::Binding(bm, node_id, Spanned { span, node: name }, None),
             span,
         })
     }
@@ -3649,16 +4087,18 @@ impl<'a> LoweringContext<'a> {
     /// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
     /// The path is also resolved according to `is_value`.
     fn std_path(&mut self, span: Span, components: &[&str], is_value: bool) -> hir::Path {
-        self.resolver.resolve_str_path(span, self.crate_root, components, is_value)
+        self.resolver
+            .resolve_str_path(span, self.crate_root, components, is_value)
     }
 
-    fn signal_block_expr(&mut self,
-                         stmts: hir::HirVec<hir::Stmt>,
-                         expr: P<hir::Expr>,
-                         span: Span,
-                         rule: hir::BlockCheckMode,
-                         attrs: ThinVec<Attribute>)
-                         -> hir::Expr {
+    fn signal_block_expr(
+        &mut self,
+        stmts: hir::HirVec<hir::Stmt>,
+        expr: P<hir::Expr>,
+        span: Span,
+        rule: hir::BlockCheckMode,
+        attrs: ThinVec<Attribute>,
+    ) -> hir::Expr {
         let LoweredNodeId { node_id, hir_id } = self.next_id();
 
         let block = P(hir::Block {
@@ -3692,17 +4132,93 @@ impl<'a> LoweringContext<'a> {
                     // The original ID is taken by the `PolyTraitRef`,
                     // so the `Ty` itself needs a different one.
                     id = self.next_id();
-                    hir::TyTraitObject(hir_vec![principal], self.elided_lifetime(span))
+                    hir::TyTraitObject(hir_vec![principal], self.elided_dyn_bound(span))
                 } else {
                     hir::TyPath(hir::QPath::Resolved(None, path))
                 }
             }
-            _ => hir::TyPath(qpath)
+            _ => hir::TyPath(qpath),
         };
-        P(hir::Ty { id: id.node_id, hir_id: id.hir_id, node, span })
+        P(hir::Ty {
+            id: id.node_id,
+            hir_id: id.hir_id,
+            node,
+            span,
+        })
+    }
+
+    /// Invoked to create the lifetime argument for a type `&T`
+    /// with no explicit lifetime.
+    fn elided_ref_lifetime(&mut self, span: Span) -> hir::Lifetime {
+        match self.anonymous_lifetime_mode {
+            // Intercept when we are in an impl header and introduce an in-band lifetime.
+            // Hence `impl Foo for &u32` becomes `impl<'f> Foo for &'f u32` for some fresh
+            // `'f`.
+            AnonymousLifetimeMode::CreateParameter => {
+                let fresh_name = self.collect_fresh_in_band_lifetime(span);
+                hir::Lifetime {
+                    id: self.next_id().node_id,
+                    span,
+                    name: fresh_name,
+                }
+            }
+
+            AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),
+        }
     }
 
-    fn elided_lifetime(&mut self, span: Span) -> hir::Lifetime {
+    /// Invoked to create the lifetime argument(s) for a path like
+    /// `std::cell::Ref<T>`; note that implicit lifetimes in these
+    /// sorts of cases are deprecated. This may therefore report a warning or an
+    /// error, depending on the mode.
+    fn elided_path_lifetimes(&mut self, span: Span, count: usize) -> P<[hir::Lifetime]> {
+        match self.anonymous_lifetime_mode {
+            // NB. We intentionally ignore the create-parameter mode here
+            // and instead "pass through" to resolve-lifetimes, which will then
+            // report an error. This is because we don't want to support
+            // impl elision for deprecated forms like
+            //
+            //     impl Foo for std::cell::Ref<u32> // note lack of '_
+            AnonymousLifetimeMode::CreateParameter => {}
+
+            // This is the normal case.
+            AnonymousLifetimeMode::PassThrough => {}
+        }
+
+        (0..count)
+            .map(|_| self.new_implicit_lifetime(span))
+            .collect()
+    }
+
+    /// Invoked to create the lifetime argument(s) for an elided trait object
+    /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
+    /// when the bound is written, even if it is written with `'_` like in
+    /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
+    fn elided_dyn_bound(&mut self, span: Span) -> hir::Lifetime {
+        match self.anonymous_lifetime_mode {
+            // NB. We intentionally ignore the create-parameter mode here.
+            // and instead "pass through" to resolve-lifetimes, which will apply
+            // the object-lifetime-defaulting rules. Elided object lifetime defaults
+            // do not act like other elided lifetimes. In other words, given this:
+            //
+            //     impl Foo for Box<dyn Debug>
+            //
+            // we do not introduce a fresh `'_` to serve as the bound, but instead
+            // ultimately translate to the equivalent of:
+            //
+            //     impl Foo for Box<dyn Debug + 'static>
+            //
+            // `resolve_lifetime` has the code to make that happen.
+            AnonymousLifetimeMode::CreateParameter => {}
+
+            // This is the normal case.
+            AnonymousLifetimeMode::PassThrough => {}
+        }
+
+        self.new_implicit_lifetime(span)
+    }
+
+    fn new_implicit_lifetime(&mut self, span: Span) -> hir::Lifetime {
         hir::Lifetime {
             id: self.next_id().node_id,
             span,
@@ -3713,9 +4229,11 @@ impl<'a> LoweringContext<'a> {
     fn maybe_lint_bare_trait(&self, span: Span, id: NodeId, is_global: bool) {
         if self.sess.features_untracked().dyn_trait {
             self.sess.buffer_lint_with_diagnostic(
-                builtin::BARE_TRAIT_OBJECT, id, span,
+                builtin::BARE_TRAIT_OBJECT,
+                id,
+                span,
                 "trait objects without an explicit `dyn` are deprecated",
-                builtin::BuiltinLintDiagnostics::BareTraitObject(span, is_global)
+                builtin::BuiltinLintDiagnostics::BareTraitObject(span, is_global),
             )
         }
     }
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 12b472a7285..be8cceb6118 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -203,9 +203,31 @@ pub struct Lifetime {
 
 #[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
 pub enum LifetimeName {
+    /// User typed nothing. e.g. the lifetime in `&u32`.
     Implicit,
+
+    /// User typed `'_`.
     Underscore,
+
+    /// Synthetic name generated when user elided a lifetime in an impl header,
+    /// e.g. the lifetimes in cases like these:
+    ///
+    ///     impl Foo for &u32
+    ///     impl Foo<'_> for u32
+    ///
+    /// in that case, we rewrite to
+    ///
+    ///     impl<'f> Foo for &'f u32
+    ///     impl<'f> Foo<'f> for u32
+    ///
+    /// where `'f` is something like `Fresh(0)`. The indices are
+    /// unique per impl, but not necessarily continuous.
+    Fresh(usize),
+
+    /// User wrote `'static`
     Static,
+
+    /// Some user-given name like `'x`
     Name(Name),
 }
 
@@ -214,7 +236,7 @@ impl LifetimeName {
         use self::LifetimeName::*;
         match *self {
             Implicit => keywords::Invalid.name(),
-            Underscore => keywords::UnderscoreLifetime.name(),
+            Fresh(_) | Underscore => keywords::UnderscoreLifetime.name(),
             Static => keywords::StaticLifetime.name(),
             Name(name) => name,
         }
@@ -235,7 +257,13 @@ impl Lifetime {
         use self::LifetimeName::*;
         match self.name {
             Implicit | Underscore => true,
-            Static | Name(_) => false,
+
+            // It might seem surprising that `Fresh(_)` counts as
+            // *not* elided -- but this is because, as far as the code
+            // in the compiler is concerned -- `Fresh(_)` variants act
+            // equivalently to "some fresh name". They correspond to
+            // early-bound regions on an impl, in other words.
+            Fresh(_) | Static | Name(_) => false,
         }
     }
 
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index 774b1442b71..c3b3e10201f 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -145,6 +145,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItemId {
 impl_stable_hash_for!(enum hir::LifetimeName {
     Implicit,
     Underscore,
+    Fresh(index),
     Static,
     Name(name)
 });
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 0aa750aba06..ceda72dcd7a 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -31,6 +31,7 @@ use syntax::ptr::P;
 use syntax_pos::Span;
 use errors::DiagnosticBuilder;
 use util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap, NodeSet};
+use session::Session;
 use std::slice;
 use rustc::lint;
 
@@ -468,11 +469,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         match item.node {
             hir::ItemFn(ref decl, _, _, _, ref generics, _) => {
-                self.visit_early_late(None,
-                                      decl,
-                                      generics,
-                                      |this| {
-                                          intravisit::walk_item(this, item);
+                self.visit_early_late(None, decl, generics, |this| {
+                    intravisit::walk_item(this, item);
                 });
             }
 
@@ -505,7 +503,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 } else {
                     0
                 };
-                let lifetimes = generics.lifetimes()
+                let lifetimes = generics
+                    .lifetimes()
                     .map(|def| Region::early(&self.tcx.hir, &mut index, def))
                     .collect();
                 let next_early_index = index + generics.ty_params().count() as u32;
@@ -526,12 +525,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem) {
         match item.node {
             hir::ForeignItemFn(ref decl, _, ref generics) => {
-                self.visit_early_late(None,
-                                      decl,
-                                      generics,
-                                      |this| {
-                                          intravisit::walk_foreign_item(this, item);
-                                      })
+                self.visit_early_late(None, decl, generics, |this| {
+                    intravisit::walk_foreign_item(this, item);
+                })
             }
             hir::ForeignItemStatic(..) => {
                 intravisit::walk_foreign_item(self, item);
@@ -586,7 +582,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                         // cc #48468
                         self.resolve_elided_lifetimes(slice::from_ref(lifetime), false)
                     }
-                    LifetimeName::Static | LifetimeName::Name(_) => {
+                    LifetimeName::Fresh(_) | LifetimeName::Static | LifetimeName::Name(_) => {
                         // If the user wrote an explicit name, use that.
                         self.visit_lifetime(lifetime);
                     }
@@ -670,7 +666,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 if let Some(elision_region) = elision {
                     let scope = Scope::Elision {
                         elide: Elide::Exact(elision_region),
-                        s: self.scope
+                        s: self.scope,
                     };
                     self.with(scope, |_old_scope, this| {
                         let scope = Scope::Binder {
@@ -716,12 +712,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                     &trait_item.generics,
                     |this| intravisit::walk_trait_item(this, trait_item),
                 );
-            },
+            }
             Type(ref bounds, ref ty) => {
                 let generics = &trait_item.generics;
                 let mut index = self.next_early_index();
                 debug!("visit_ty: index = {}", index);
-                let lifetimes = generics.lifetimes()
+                let lifetimes = generics
+                    .lifetimes()
                     .map(|lt_def| Region::early(&self.tcx.hir, &mut index, lt_def))
                     .collect();
 
@@ -741,12 +738,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                         this.visit_ty(ty);
                     }
                 });
-            },
+            }
             Const(_, _) => {
                 // Only methods and types support generics.
                 assert!(trait_item.generics.params.is_empty());
                 intravisit::walk_trait_item(self, trait_item);
-            },
+            }
         }
     }
 
@@ -761,12 +758,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                     &impl_item.generics,
                     |this| intravisit::walk_impl_item(this, impl_item),
                 )
-            },
+            }
             Type(ref ty) => {
                 let generics = &impl_item.generics;
                 let mut index = self.next_early_index();
                 debug!("visit_ty: index = {}", index);
-                let lifetimes = generics.lifetimes()
+                let lifetimes = generics
+                    .lifetimes()
                     .map(|lt_def| Region::early(&self.tcx.hir, &mut index, lt_def))
                     .collect();
 
@@ -781,12 +779,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                     this.visit_generics(generics);
                     this.visit_ty(ty);
                 });
-            },
+            }
             Const(_, _) => {
                 // Only methods and types support generics.
                 assert!(impl_item.generics.params.is_empty());
                 intravisit::walk_impl_item(self, impl_item);
-            },
+            }
         }
     }
 
@@ -822,7 +820,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
         check_mixed_explicit_and_in_band_defs(
             self.tcx,
-            &generics.lifetimes().cloned().collect::<Vec<_>>()
+            &generics.lifetimes().cloned().collect::<Vec<_>>(),
         );
         for ty_param in generics.ty_params() {
             walk_list!(self, visit_ty_param_bound, &ty_param.bounds);
@@ -842,7 +840,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                         self.trait_ref_hack = true;
                         let next_early_index = self.next_early_index();
                         let scope = Scope::Binder {
-                            lifetimes: bound_generic_params.lifetimes()
+                            lifetimes: bound_generic_params
+                                .lifetimes()
                                 .map(|def| Region::late(&self.tcx.hir, def))
                                 .collect(),
                             s: self.scope,
@@ -890,8 +889,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     ) {
         debug!("visit_poly_trait_ref trait_ref={:?}", trait_ref);
 
-        if !self.trait_ref_hack ||
-            trait_ref.bound_generic_params.iter().any(|p| p.is_lifetime_param())
+        if !self.trait_ref_hack
+            || trait_ref
+                .bound_generic_params
+                .iter()
+                .any(|p| p.is_lifetime_param())
         {
             if self.trait_ref_hack {
                 span_err!(
@@ -903,7 +905,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
             }
             let next_early_index = self.next_early_index();
             let scope = Scope::Binder {
-                lifetimes: trait_ref.bound_generic_params
+                lifetimes: trait_ref
+                    .bound_generic_params
                     .lifetimes()
                     .map(|def| Region::late(&self.tcx.hir, def))
                     .collect(),
@@ -1144,7 +1147,8 @@ fn compute_object_lifetime_defaults(
                         .map(|set| match *set {
                             Set1::Empty => "BaseDefault".to_string(),
                             Set1::One(Region::Static) => "'static".to_string(),
-                            Set1::One(Region::EarlyBound(i, _, _)) => generics.lifetimes()
+                            Set1::One(Region::EarlyBound(i, _, _)) => generics
+                                .lifetimes()
                                 .nth(i as usize)
                                 .unwrap()
                                 .lifetime
@@ -1182,7 +1186,8 @@ fn object_lifetime_defaults_for_item(
         }
     }
 
-    generics.ty_params()
+    generics
+        .ty_params()
         .map(|param| {
             let mut set = Set1::Empty;
 
@@ -1278,17 +1283,21 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                     if let hir::map::NodeLifetime(hir_lifetime) = this.tcx.hir.get(node_id) {
                         let span = hir_lifetime.span;
                         let id = hir_lifetime.id;
-                        debug!("id ={:?} span = {:?} hir_lifetime = {:?}",
-                            node_id,
-                            span,
-                            hir_lifetime);
+                        debug!(
+                            "id ={:?} span = {:?} hir_lifetime = {:?}",
+                            node_id, span, hir_lifetime
+                        );
 
                         this.tcx
-                            .struct_span_lint_node(lint::builtin::SINGLE_USE_LIFETIME,
-                                                   id,
-                                                   span,
-                                                   &format!("lifetime name `{}` only used once",
-                                                   hir_lifetime.name.name()))
+                            .struct_span_lint_node(
+                                lint::builtin::SINGLE_USE_LIFETIME,
+                                id,
+                                span,
+                                &format!(
+                                    "lifetime name `{}` only used once",
+                                    hir_lifetime.name.name()
+                                ),
+                            )
                             .emit();
                     }
                 }
@@ -1379,8 +1388,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                     next_early_index,
                     abstract_type_parent,
                     ..
-                } if (!only_abstract_type_parent || abstract_type_parent)
-                => return next_early_index,
+                } if (!only_abstract_type_parent || abstract_type_parent) =>
+                {
+                    return next_early_index
+                }
 
                 Scope::Binder { s, .. }
                 | Scope::Body { s, .. }
@@ -1698,8 +1709,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
 
             // Foreign functions, `fn(...) -> R` and `Trait(...) -> R` (both types and bounds).
-            hir::map::NodeForeignItem(_) | hir::map::NodeTy(_) | hir::map::NodeTraitRef(_) =>
-                None,
+            hir::map::NodeForeignItem(_) | hir::map::NodeTy(_) | hir::map::NodeTraitRef(_) => None,
             // Everything else (only closures?) doesn't
             // actually enjoy elision in return types.
             _ => {
@@ -1894,7 +1904,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                     lint::builtin::ELIDED_LIFETIME_IN_PATH,
                     id,
                     span,
-                    &format!("hidden lifetime parameters are deprecated, try `Foo<'_>`"))
+                    &format!("hidden lifetime parameters are deprecated, try `Foo<'_>`"),
+                )
                 .emit();
         }
         let error = loop {
@@ -1933,25 +1944,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
         };
 
-        let mut err = struct_span_err!(
-            self.tcx.sess,
-            span,
-            E0106,
-            "missing lifetime specifier{}",
-            if lifetime_refs.len() > 1 { "s" } else { "" }
-        );
-        let msg = if lifetime_refs.len() > 1 {
-            format!("expected {} lifetime parameters", lifetime_refs.len())
-        } else {
-            format!("expected lifetime parameter")
-        };
-        err.span_label(span, msg);
+        let mut err = report_missing_lifetime_specifiers(self.tcx.sess, span, lifetime_refs.len());
 
         if let Some(params) = error {
             if lifetime_refs.len() == 1 {
                 self.report_elision_failure(&mut err, params);
             }
         }
+
         err.emit();
     }
 
@@ -2086,7 +2086,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                         );
                         err.emit();
                     }
-                    hir::LifetimeName::Implicit | hir::LifetimeName::Name(_) => {}
+                    hir::LifetimeName::Fresh(_) | hir::LifetimeName::Implicit |
+                    hir::LifetimeName::Name(_) => {}
                 }
             }
 
@@ -2138,7 +2139,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                             ))
                             .emit();
                     }
-                    hir::LifetimeName::Implicit | hir::LifetimeName::Name(_) => {
+                    hir::LifetimeName::Fresh(_) | hir::LifetimeName::Implicit |
+                    hir::LifetimeName::Name(_) => {
                         self.resolve_lifetime_ref(bound);
                     }
                 }
@@ -2146,9 +2148,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         }
     }
 
-    fn check_lifetime_def_for_shadowing(&self,
-                                        mut old_scope: ScopeRef,
-                                        lifetime: &'tcx hir::Lifetime) {
+    fn check_lifetime_def_for_shadowing(
+        &self,
+        mut old_scope: ScopeRef,
+        lifetime: &'tcx hir::Lifetime,
+    ) {
         for &(label, label_span) in &self.labels_in_fn {
             // FIXME (#24278): non-hygienic comparison
             if lifetime.name.name() == label {
@@ -2216,14 +2220,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         self.map.defs.insert(lifetime_ref.id, def);
 
         match def {
-            Region::LateBoundAnon(..) |
-            Region::Static => {
+            Region::LateBoundAnon(..) | Region::Static => {
                 // These are anonymous lifetimes or lifetimes that are not declared.
             }
 
-            Region::Free(_, def_id) |
-            Region::LateBound(_, def_id, _) |
-            Region::EarlyBound(_, def_id, _) => {
+            Region::Free(_, def_id)
+            | Region::LateBound(_, def_id, _)
+            | Region::EarlyBound(_, def_id, _) => {
                 // A lifetime declared by the user.
                 if !self.lifetime_uses.contains_key(&def_id) {
                     self.lifetime_uses
@@ -2255,8 +2258,7 @@ fn insert_late_bound_lifetimes(
 ) {
     debug!(
         "insert_late_bound_lifetimes(decl={:?}, generics={:?})",
-        decl,
-        generics
+        decl, generics
     );
 
     let mut constrained_by_input = ConstrainedCollector {
@@ -2335,8 +2337,7 @@ fn insert_late_bound_lifetimes(
         debug!(
             "insert_late_bound_lifetimes: \
              lifetime {:?} with id {:?} is late-bound",
-            lifetime.lifetime.name,
-            lifetime.lifetime.id
+            lifetime.lifetime.name, lifetime.lifetime.id
         );
 
         let inserted = map.late_bound.insert(lifetime.lifetime.id);
@@ -2403,3 +2404,27 @@ fn insert_late_bound_lifetimes(
         }
     }
 }
+
+pub fn report_missing_lifetime_specifiers(
+    sess: &Session,
+    span: Span,
+    count: usize,
+) -> DiagnosticBuilder<'_> {
+    let mut err = struct_span_err!(
+        sess,
+        span,
+        E0106,
+        "missing lifetime specifier{}",
+        if count > 1 { "s" } else { "" }
+    );
+
+    let msg = if count > 1 {
+        format!("expected {} lifetime parameters", count)
+    } else {
+        format!("expected lifetime parameter")
+    };
+
+    err.span_label(span, msg);
+
+    err
+}
diff --git a/src/test/ui/feature-gate-in_band_lifetimes-impl.rs b/src/test/ui/feature-gate-in_band_lifetimes-impl.rs
new file mode 100644
index 00000000000..a02b3e80009
--- /dev/null
+++ b/src/test/ui/feature-gate-in_band_lifetimes-impl.rs
@@ -0,0 +1,22 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(warnings)]
+#![feature(underscore_lifetimes)]
+
+trait MyTrait<'a> { }
+
+impl<'a> MyTrait<'a> for &u32 { }
+//~^ ERROR missing lifetime specifier
+
+impl<'a> MyTrait<'_> for &'a f32 { }
+//~^ ERROR missing lifetime specifier
+
+fn main() {}
diff --git a/src/test/ui/feature-gate-in_band_lifetimes-impl.stderr b/src/test/ui/feature-gate-in_band_lifetimes-impl.stderr
new file mode 100644
index 00000000000..e32a06c3ce4
--- /dev/null
+++ b/src/test/ui/feature-gate-in_band_lifetimes-impl.stderr
@@ -0,0 +1,15 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/feature-gate-in_band_lifetimes-impl.rs:16:26
+   |
+LL | impl<'a> MyTrait<'a> for &u32 { }
+   |                          ^ expected lifetime parameter
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/feature-gate-in_band_lifetimes-impl.rs:19:18
+   |
+LL | impl<'a> MyTrait<'_> for &'a f32 { }
+   |                  ^^ expected lifetime parameter
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/in-band-lifetimes/impl/assoc-type.rs b/src/test/ui/in-band-lifetimes/impl/assoc-type.rs
new file mode 100644
index 00000000000..54f38b2e729
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/assoc-type.rs
@@ -0,0 +1,38 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we do not yet support elision in associated types, even
+// when there is just one name we could take from the impl header.
+
+#![allow(warnings)]
+
+#![feature(in_band_lifetimes)]
+#![feature(underscore_lifetimes)]
+
+trait MyTrait {
+    type Output;
+}
+
+impl MyTrait for &i32 {
+    type Output = &i32;
+    //~^ ERROR missing lifetime specifier
+}
+
+impl MyTrait for &u32 {
+    type Output = &'_ i32;
+    //~^ ERROR missing lifetime specifier
+}
+
+// This is what you have to do:
+impl MyTrait for &'a f32 {
+    type Output = &'a f32;
+}
+
+fn main() { }
diff --git a/src/test/ui/in-band-lifetimes/impl/assoc-type.stderr b/src/test/ui/in-band-lifetimes/impl/assoc-type.stderr
new file mode 100644
index 00000000000..909b86daef0
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/assoc-type.stderr
@@ -0,0 +1,15 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/assoc-type.rs:24:19
+   |
+LL |     type Output = &i32;
+   |                   ^ expected lifetime parameter
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/assoc-type.rs:29:20
+   |
+LL |     type Output = &'_ i32;
+   |                    ^^ expected lifetime parameter
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/in-band-lifetimes/impl/dyn-trait.rs b/src/test/ui/in-band-lifetimes/impl/dyn-trait.rs
new file mode 100644
index 00000000000..e839248b0e3
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/dyn-trait.rs
@@ -0,0 +1,45 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that `impl MyTrait<'_> for &i32` is equivalent to `impl<'a,
+// 'b> MyTrait<'a> for &'b i32`.
+
+#![allow(warnings)]
+
+#![feature(dyn_trait)]
+#![feature(in_band_lifetimes)]
+#![feature(underscore_lifetimes)]
+
+use std::fmt::Debug;
+
+// Equivalent to `Box<dyn Debug + 'static>`:
+trait StaticTrait { }
+impl StaticTrait for Box<dyn Debug> { }
+
+// Equivalent to `Box<dyn Debug + 'static>`:
+trait NotStaticTrait { }
+impl NotStaticTrait for Box<dyn Debug + '_> { }
+
+fn static_val<T: StaticTrait>(_: T) {
+}
+
+fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
+    static_val(x); //~ ERROR cannot infer
+}
+
+fn not_static_val<T: NotStaticTrait>(_: T) {
+}
+
+fn with_dyn_debug_not_static<'a>(x: Box<dyn Debug + 'a>) {
+    not_static_val(x); // OK
+}
+
+fn main() {
+}
diff --git a/src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr b/src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr
new file mode 100644
index 00000000000..0054ca3d1a5
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr
@@ -0,0 +1,22 @@
+error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+  --> $DIR/dyn-trait.rs:34:16
+   |
+LL |     static_val(x); //~ ERROR cannot infer
+   |                ^
+   |
+note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 33:1...
+  --> $DIR/dyn-trait.rs:33:1
+   |
+LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: ...so that the expression is assignable:
+           expected std::boxed::Box<std::fmt::Debug>
+              found std::boxed::Box<std::fmt::Debug + 'a>
+   = note: but, the lifetime must be valid for the static lifetime...
+   = note: ...so that the types are compatible:
+           expected StaticTrait
+              found StaticTrait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/in-band-lifetimes/impl/path-elided.rs b/src/test/ui/in-band-lifetimes/impl/path-elided.rs
new file mode 100644
index 00000000000..fa1b4523889
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/path-elided.rs
@@ -0,0 +1,23 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+#![allow(warnings)]
+
+#![feature(in_band_lifetimes)]
+#![feature(underscore_lifetimes)]
+
+trait MyTrait { }
+
+struct Foo<'a> { x: &'a u32 }
+
+impl MyTrait for Foo {
+    //~^ ERROR missing lifetime specifier
+}
+
+fn main() {}
diff --git a/src/test/ui/in-band-lifetimes/impl/path-elided.stderr b/src/test/ui/in-band-lifetimes/impl/path-elided.stderr
new file mode 100644
index 00000000000..19e69c61a03
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/path-elided.stderr
@@ -0,0 +1,9 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/path-elided.rs:19:18
+   |
+LL | impl MyTrait for Foo {
+   |                  ^^^ expected lifetime parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/in-band-lifetimes/impl/path-underscore.rs b/src/test/ui/in-band-lifetimes/impl/path-underscore.rs
new file mode 100644
index 00000000000..56f2d93d9e0
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/path-underscore.rs
@@ -0,0 +1,47 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that `impl MyTrait for Foo<'_>` works.
+
+// run-pass
+
+#![allow(warnings)]
+
+#![feature(in_band_lifetimes)]
+#![feature(underscore_lifetimes)]
+
+trait MyTrait { }
+
+struct Foo<'a> { x: &'a u32 }
+
+impl MyTrait for Foo<'_> {
+}
+
+fn impls_my_trait<T: MyTrait>() { }
+
+fn impls_my_trait_val<T: MyTrait>(_: T) {
+    impls_my_trait::<T>();
+}
+
+fn random_where_clause()
+where for<'a> Foo<'a>: MyTrait { }
+
+fn main() {
+    let x = 22;
+    let f = Foo { x: &x };
+
+    // This type is `Foo<'x>` for a local lifetime `'x`; so the impl
+    // must apply to any lifetime to apply to this.
+    impls_my_trait_val(f);
+
+    impls_my_trait::<Foo<'static>>();
+
+    random_where_clause();
+}
diff --git a/src/test/ui/in-band-lifetimes/impl/ref-underscore.rs b/src/test/ui/in-band-lifetimes/impl/ref-underscore.rs
new file mode 100644
index 00000000000..1b1035abeba
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/ref-underscore.rs
@@ -0,0 +1,43 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that `impl MyTrait for &i32` works and is equivalent to any lifetime.
+
+// run-pass
+
+#![allow(warnings)]
+
+#![feature(in_band_lifetimes)]
+#![feature(underscore_lifetimes)]
+
+trait MyTrait { }
+
+impl MyTrait for &i32 {
+}
+
+fn impls_my_trait<T: MyTrait>() { }
+
+fn impls_my_trait_val<T: MyTrait>(_: T) {
+    impls_my_trait::<T>();
+}
+
+fn random_where_clause()
+where for<'a> &'a i32: MyTrait { }
+
+fn main() {
+    let x = 22;
+    let f = &x;
+
+    impls_my_trait_val(f);
+
+    impls_my_trait::<&'static i32>();
+
+    random_where_clause();
+}
diff --git a/src/test/ui/in-band-lifetimes/impl/trait-elided.rs b/src/test/ui/in-band-lifetimes/impl/trait-elided.rs
new file mode 100644
index 00000000000..7594d66e078
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/trait-elided.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+#![allow(warnings)]
+
+#![feature(in_band_lifetimes)]
+#![feature(underscore_lifetimes)]
+
+trait MyTrait<'a> { }
+
+impl MyTrait for u32 {
+    //~^ ERROR missing lifetime specifier
+}
+
+fn main() {}
diff --git a/src/test/ui/in-band-lifetimes/impl/trait-elided.stderr b/src/test/ui/in-band-lifetimes/impl/trait-elided.stderr
new file mode 100644
index 00000000000..bb301882868
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/trait-elided.stderr
@@ -0,0 +1,9 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/trait-elided.rs:17:6
+   |
+LL | impl MyTrait for u32 {
+   |      ^^^^^^^ expected lifetime parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/in-band-lifetimes/impl/trait-underscore.rs b/src/test/ui/in-band-lifetimes/impl/trait-underscore.rs
new file mode 100644
index 00000000000..077e33c1efd
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/trait-underscore.rs
@@ -0,0 +1,48 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that `impl MyTrait<'_> for &i32` is equivalent to `impl<'a,
+// 'b> MyTrait<'a> for &'b i32`.
+//
+// run-pass
+
+#![allow(warnings)]
+
+#![feature(in_band_lifetimes)]
+#![feature(underscore_lifetimes)]
+
+trait MyTrait<'a> { }
+
+// This is equivalent to `MyTrait<'a> for &'b i32`, which is proven by
+// the code below.
+impl MyTrait<'_> for &i32 {
+}
+
+// When called, T will be `&'x i32` for some `'x`, so since we can
+// prove that `&'x i32: for<'a> MyTrait<'a>, then we know that the
+// lifetime parameter above is disconnected.
+fn impls_my_trait<T: for<'a> MyTrait<'a>>() { }
+
+fn impls_my_trait_val<T: for<'a> MyTrait<'a>>(_: T) {
+    impls_my_trait::<T>();
+}
+
+fn random_where_clause()
+where for<'a, 'b> &'a i32: MyTrait<'b> { }
+
+fn main() {
+    let x = 22;
+    let f = &x;
+    impls_my_trait_val(f);
+
+    impls_my_trait::<&'static i32>();
+
+    random_where_clause();
+}
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs
new file mode 100644
index 00000000000..d10541ad33b
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs
@@ -0,0 +1,26 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Check that the `'_` in `dyn Trait + '_` acts like ordinary elision,
+// and not like an object lifetime default.
+//
+// cc #48468
+
+#![feature(dyn_trait)]
+#![feature(underscore_lifetimes)]
+
+use std::fmt::Debug;
+
+struct Foo {
+    x: Box<dyn Debug + '_>, //~ ERROR missing lifetime specifier
+    //~^ ERROR E0228
+}
+
+fn main() { }
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr
new file mode 100644
index 00000000000..a88ecb18dd6
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr
@@ -0,0 +1,16 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/dyn-trait-underscore-in-struct.rs:22:24
+   |
+LL |     x: Box<dyn Debug + '_>, //~ ERROR missing lifetime specifier
+   |                        ^^ expected lifetime parameter
+
+error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
+  --> $DIR/dyn-trait-underscore-in-struct.rs:22:12
+   |
+LL |     x: Box<dyn Debug + '_>, //~ ERROR missing lifetime specifier
+   |            ^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0106, E0228.
+For more information about an error, try `rustc --explain E0106`.