about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-12-27 01:40:41 +0000
committerbors <bors@rust-lang.org>2019-12-27 01:40:41 +0000
commita04c789f699a3470edd8cc76d016c68e99cfe4db (patch)
tree0c45a0f6a3102b12e22a8241371d8ded116c5848
parent3e0a1c09108b52e41113520c7fa516480a8b67f9 (diff)
parentfb100e5ddcb09e5738231a49a1e709a157bdc027 (diff)
downloadrust-a04c789f699a3470edd8cc76d016c68e99cfe4db.tar.gz
rust-a04c789f699a3470edd8cc76d016c68e99cfe4db.zip
Auto merge of #66936 - cjgillot:hirene-expr, r=Zoxc
Allocate HIR on an arena 2/4 -- Expr & Pat

This is the second PR in the series started by #66931

This time, commits don't really make sense on their own.
They are mostly split by type of compile error.

The additional diff is here: https://github.com/cjgillot/rust/compare/hirene-preamble...hirene-expr
-rw-r--r--src/librustc/arena.rs13
-rw-r--r--src/librustc/hir/check_attr.rs8
-rw-r--r--src/librustc/hir/intravisit.rs60
-rw-r--r--src/librustc/hir/lowering.rs188
-rw-r--r--src/librustc/hir/lowering/expr.rs457
-rw-r--r--src/librustc/hir/lowering/item.rs53
-rw-r--r--src/librustc/hir/map/blocks.rs4
-rw-r--r--src/librustc/hir/map/collector.rs14
-rw-r--r--src/librustc/hir/map/mod.rs16
-rw-r--r--src/librustc/hir/mod.rs193
-rw-r--r--src/librustc/hir/pat_util.rs4
-rw-r--r--src/librustc/hir/print.rs75
-rw-r--r--src/librustc/hir/upvars.rs4
-rw-r--r--src/librustc/ich/impls_hir.rs2
-rw-r--r--src/librustc/infer/error_reporting/need_type_info.rs16
-rw-r--r--src/librustc/infer/error_reporting/nice_region_error/util.rs2
-rw-r--r--src/librustc/lint/context.rs14
-rw-r--r--src/librustc/lint/mod.rs26
-rw-r--r--src/librustc/middle/reachable.rs2
-rw-r--r--src/librustc/middle/region.rs40
-rw-r--r--src/librustc/middle/resolve_lifetime.rs4
-rw-r--r--src/librustc/traits/error_reporting.rs25
-rw-r--r--src/librustc/ty/context.rs16
-rw-r--r--src/librustc_lint/array_into_iter.rs2
-rw-r--r--src/librustc_lint/builtin.rs16
-rw-r--r--src/librustc_lint/nonstandard_style.rs4
-rw-r--r--src/librustc_lint/types.rs18
-rw-r--r--src/librustc_lint/unused.rs8
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs4
-rw-r--r--src/librustc_mir/build/block.rs2
-rw-r--r--src/librustc_mir/build/mod.rs15
-rw-r--r--src/librustc_mir/hair/cx/block.rs9
-rw-r--r--src/librustc_mir/hair/cx/expr.rs25
-rw-r--r--src/librustc_mir/hair/cx/mod.rs2
-rw-r--r--src/librustc_mir/hair/cx/to_ref.rs7
-rw-r--r--src/librustc_mir/hair/mod.rs4
-rw-r--r--src/librustc_mir/hair/pattern/check_match.rs38
-rw-r--r--src/librustc_mir/hair/pattern/mod.rs23
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs2
-rw-r--r--src/librustc_passes/check_const.rs4
-rw-r--r--src/librustc_passes/dead.rs17
-rw-r--r--src/librustc_passes/hir_stats.rs14
-rw-r--r--src/librustc_passes/intrinsicck.rs2
-rw-r--r--src/librustc_passes/liveness.rs65
-rw-r--r--src/librustc_passes/loops.rs2
-rw-r--r--src/librustc_privacy/lib.rs22
-rw-r--r--src/librustc_typeck/astconv.rs2
-rw-r--r--src/librustc_typeck/check/_match.rs24
-rw-r--r--src/librustc_typeck/check/callee.rs34
-rw-r--r--src/librustc_typeck/check/cast.rs4
-rw-r--r--src/librustc_typeck/check/closure.rs4
-rw-r--r--src/librustc_typeck/check/coercion.rs32
-rw-r--r--src/librustc_typeck/check/demand.rs28
-rw-r--r--src/librustc_typeck/check/expr.rs133
-rw-r--r--src/librustc_typeck/check/generator_interior.rs8
-rw-r--r--src/librustc_typeck/check/method/confirm.rs16
-rw-r--r--src/librustc_typeck/check/method/mod.rs6
-rw-r--r--src/librustc_typeck/check/method/suggest.rs6
-rw-r--r--src/librustc_typeck/check/mod.rs76
-rw-r--r--src/librustc_typeck/check/op.rs28
-rw-r--r--src/librustc_typeck/check/pat.rs76
-rw-r--r--src/librustc_typeck/check/regionck.rs49
-rw-r--r--src/librustc_typeck/check/upvar.rs2
-rw-r--r--src/librustc_typeck/check/writeback.rs16
-rw-r--r--src/librustc_typeck/collect.rs2
-rw-r--r--src/librustc_typeck/expr_use_visitor.rs45
-rw-r--r--src/librustc_typeck/mem_categorization.rs52
67 files changed, 1189 insertions, 995 deletions
diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index 3d5bd313f88..f604a66aebc 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -125,14 +125,25 @@ macro_rules! arena_types {
 
             // HIR types
             [few] hir_forest: rustc::hir::map::Forest<$tcx>,
+            [] arm: rustc::hir::Arm<$tcx>,
             [] attribute: syntax::ast::Attribute,
+            [] block: rustc::hir::Block<$tcx>,
             [few] global_asm: rustc::hir::GlobalAsm,
+            [] expr: rustc::hir::Expr<$tcx>,
+            [] field: rustc::hir::Field<$tcx>,
+            [] field_pat: rustc::hir::FieldPat<$tcx>,
             [] fn_decl: rustc::hir::FnDecl,
             [] foreign_item: rustc::hir::ForeignItem<$tcx>,
             [] impl_item_ref: rustc::hir::ImplItemRef,
+            [] inline_asm: rustc::hir::InlineAsm<$tcx>,
+            [] local: rustc::hir::Local<$tcx>,
             [few] macro_def: rustc::hir::MacroDef<$tcx>,
-            [] param: rustc::hir::Param,
+            [] param: rustc::hir::Param<$tcx>,
+            [] pat: rustc::hir::Pat<$tcx>,
             [] path: rustc::hir::Path,
+            [] path_segment: rustc::hir::PathSegment,
+            [] qpath: rustc::hir::QPath,
+            [] stmt: rustc::hir::Stmt<$tcx>,
             [] struct_field: rustc::hir::StructField<$tcx>,
             [] trait_item_ref: rustc::hir::TraitItemRef,
             [] ty: rustc::hir::Ty,
diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs
index 5918ff03d58..511244ca516 100644
--- a/src/librustc/hir/check_attr.rs
+++ b/src/librustc/hir/check_attr.rs
@@ -458,7 +458,7 @@ impl CheckAttrVisitor<'tcx> {
             .emit();
     }
 
-    fn check_stmt_attributes(&self, stmt: &hir::Stmt) {
+    fn check_stmt_attributes(&self, stmt: &hir::Stmt<'_>) {
         // When checking statements ignore expressions, they will be checked later
         if let hir::StmtKind::Local(ref l) = stmt.kind {
             for attr in l.attrs.iter() {
@@ -477,7 +477,7 @@ impl CheckAttrVisitor<'tcx> {
         }
     }
 
-    fn check_expr_attributes(&self, expr: &hir::Expr) {
+    fn check_expr_attributes(&self, expr: &hir::Expr<'_>) {
         let target = match expr.kind {
             hir::ExprKind::Closure(..) => Target::Closure,
             _ => Target::Expression,
@@ -537,12 +537,12 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
         intravisit::walk_impl_item(self, impl_item)
     }
 
-    fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt) {
+    fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) {
         self.check_stmt_attributes(stmt);
         intravisit::walk_stmt(self, stmt)
     }
 
-    fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         self.check_expr_attributes(expr);
         intravisit::walk_expr(self, expr)
     }
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index a7a8673d49e..659bfc4e63c 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -212,7 +212,7 @@ pub trait Visitor<'v>: Sized {
         }
     }
 
-    fn visit_param(&mut self, param: &'v Param) {
+    fn visit_param(&mut self, param: &'v Param<'v>) {
         walk_param(self, param)
     }
 
@@ -253,25 +253,25 @@ pub trait Visitor<'v>: Sized {
     fn visit_foreign_item(&mut self, i: &'v ForeignItem<'v>) {
         walk_foreign_item(self, i)
     }
-    fn visit_local(&mut self, l: &'v Local) {
+    fn visit_local(&mut self, l: &'v Local<'v>) {
         walk_local(self, l)
     }
-    fn visit_block(&mut self, b: &'v Block) {
+    fn visit_block(&mut self, b: &'v Block<'v>) {
         walk_block(self, b)
     }
-    fn visit_stmt(&mut self, s: &'v Stmt) {
+    fn visit_stmt(&mut self, s: &'v Stmt<'v>) {
         walk_stmt(self, s)
     }
-    fn visit_arm(&mut self, a: &'v Arm) {
+    fn visit_arm(&mut self, a: &'v Arm<'v>) {
         walk_arm(self, a)
     }
-    fn visit_pat(&mut self, p: &'v Pat) {
+    fn visit_pat(&mut self, p: &'v Pat<'v>) {
         walk_pat(self, p)
     }
     fn visit_anon_const(&mut self, c: &'v AnonConst) {
         walk_anon_const(self, c)
     }
-    fn visit_expr(&mut self, ex: &'v Expr) {
+    fn visit_expr(&mut self, ex: &'v Expr<'v>) {
         walk_expr(self, ex)
     }
     fn visit_ty(&mut self, t: &'v Ty) {
@@ -409,7 +409,7 @@ pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body<'v>) {
     visitor.visit_expr(&body.value);
 }
 
-pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
+pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local<'v>) {
     // Intentionally visiting the expr first - the initialization expr
     // dominates the local's definition.
     walk_list!(visitor, visit_expr, &local.init);
@@ -462,10 +462,10 @@ where
     visitor.visit_path(&trait_ref.path, trait_ref.hir_ref_id)
 }
 
-pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param) {
+pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) {
     visitor.visit_id(param.hir_id);
     visitor.visit_pat(&param.pat);
-    walk_list!(visitor, visit_attribute, &param.attrs);
+    walk_list!(visitor, visit_attribute, param.attrs);
 }
 
 pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
@@ -684,17 +684,17 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V, type_binding
     }
 }
 
-pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
+pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
     visitor.visit_id(pattern.hir_id);
     match pattern.kind {
-        PatKind::TupleStruct(ref qpath, ref children, _) => {
+        PatKind::TupleStruct(ref qpath, children, _) => {
             visitor.visit_qpath(qpath, pattern.hir_id, pattern.span);
             walk_list!(visitor, visit_pat, children);
         }
         PatKind::Path(ref qpath) => {
             visitor.visit_qpath(qpath, pattern.hir_id, pattern.span);
         }
-        PatKind::Struct(ref qpath, ref fields, _) => {
+        PatKind::Struct(ref qpath, fields, _) => {
             visitor.visit_qpath(qpath, pattern.hir_id, pattern.span);
             for field in fields {
                 visitor.visit_id(field.hir_id);
@@ -702,8 +702,8 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
                 visitor.visit_pat(&field.pat)
             }
         }
-        PatKind::Or(ref pats) => walk_list!(visitor, visit_pat, pats),
-        PatKind::Tuple(ref tuple_elements, _) => {
+        PatKind::Or(pats) => walk_list!(visitor, visit_pat, pats),
+        PatKind::Tuple(tuple_elements, _) => {
             walk_list!(visitor, visit_pat, tuple_elements);
         }
         PatKind::Box(ref subpattern) | PatKind::Ref(ref subpattern, _) => {
@@ -719,7 +719,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
             visitor.visit_expr(upper_bound)
         }
         PatKind::Wild => (),
-        PatKind::Slice(ref prepatterns, ref slice_pattern, ref postpatterns) => {
+        PatKind::Slice(prepatterns, ref slice_pattern, postpatterns) => {
             walk_list!(visitor, visit_pat, prepatterns);
             walk_list!(visitor, visit_pat, slice_pattern);
             walk_list!(visitor, visit_pat, postpatterns);
@@ -955,13 +955,13 @@ pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v
     walk_list!(visitor, visit_attribute, struct_field.attrs);
 }
 
-pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) {
+pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block<'v>) {
     visitor.visit_id(block.hir_id);
-    walk_list!(visitor, visit_stmt, &block.stmts);
+    walk_list!(visitor, visit_stmt, block.stmts);
     walk_list!(visitor, visit_expr, &block.expr);
 }
 
-pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) {
+pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt<'v>) {
     visitor.visit_id(statement.hir_id);
     match statement.kind {
         StmtKind::Local(ref local) => visitor.visit_local(local),
@@ -977,19 +977,19 @@ pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonCo
     visitor.visit_nested_body(constant.body);
 }
 
-pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
+pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) {
     visitor.visit_id(expression.hir_id);
     walk_list!(visitor, visit_attribute, expression.attrs.iter());
     match expression.kind {
         ExprKind::Box(ref subexpression) => visitor.visit_expr(subexpression),
-        ExprKind::Array(ref subexpressions) => {
+        ExprKind::Array(subexpressions) => {
             walk_list!(visitor, visit_expr, subexpressions);
         }
         ExprKind::Repeat(ref element, ref count) => {
             visitor.visit_expr(element);
             visitor.visit_anon_const(count)
         }
-        ExprKind::Struct(ref qpath, ref fields, ref optional_base) => {
+        ExprKind::Struct(ref qpath, fields, ref optional_base) => {
             visitor.visit_qpath(qpath, expression.hir_id, expression.span);
             for field in fields {
                 visitor.visit_id(field.hir_id);
@@ -998,14 +998,14 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
             }
             walk_list!(visitor, visit_expr, optional_base);
         }
-        ExprKind::Tup(ref subexpressions) => {
+        ExprKind::Tup(subexpressions) => {
             walk_list!(visitor, visit_expr, subexpressions);
         }
-        ExprKind::Call(ref callee_expression, ref arguments) => {
+        ExprKind::Call(ref callee_expression, arguments) => {
             visitor.visit_expr(callee_expression);
             walk_list!(visitor, visit_expr, arguments);
         }
-        ExprKind::MethodCall(ref segment, _, ref arguments) => {
+        ExprKind::MethodCall(ref segment, _, arguments) => {
             visitor.visit_path_segment(expression.span, segment);
             walk_list!(visitor, visit_expr, arguments);
         }
@@ -1027,7 +1027,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
             walk_list!(visitor, visit_label, opt_label);
             visitor.visit_block(block);
         }
-        ExprKind::Match(ref subexpression, ref arms, _) => {
+        ExprKind::Match(ref subexpression, arms, _) => {
             visitor.visit_expr(subexpression);
             walk_list!(visitor, visit_arm, arms);
         }
@@ -1077,8 +1077,8 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
             walk_list!(visitor, visit_expr, optional_expression);
         }
         ExprKind::InlineAsm(ref asm) => {
-            walk_list!(visitor, visit_expr, &asm.outputs_exprs);
-            walk_list!(visitor, visit_expr, &asm.inputs_exprs);
+            walk_list!(visitor, visit_expr, asm.outputs_exprs);
+            walk_list!(visitor, visit_expr, asm.inputs_exprs);
         }
         ExprKind::Yield(ref subexpression, _) => {
             visitor.visit_expr(subexpression);
@@ -1087,7 +1087,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
     }
 }
 
-pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
+pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) {
     visitor.visit_id(arm.hir_id);
     visitor.visit_pat(&arm.pat);
     if let Some(ref g) = arm.guard {
@@ -1096,7 +1096,7 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
         }
     }
     visitor.visit_expr(&arm.body);
-    walk_list!(visitor, visit_attribute, &arm.attrs);
+    walk_list!(visitor, visit_attribute, arm.attrs);
 }
 
 pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) {
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index f6db451d57e..ed84bd118f7 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -32,9 +32,6 @@
 //! get confused if the spans from leaf AST nodes occur in multiple places
 //! in the HIR, especially for multiple identifiers.
 
-mod expr;
-mod item;
-
 use crate::arena::Arena;
 use crate::dep_graph::DepGraph;
 use crate::hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
@@ -76,6 +73,18 @@ use syntax_pos::Span;
 
 use rustc_error_codes::*;
 
+macro_rules! arena_vec {
+    () => (
+        &[]
+    );
+    ($this:expr; $($x:expr),*) => (
+        $this.arena.alloc_from_iter(vec![$($x),*])
+    );
+}
+
+mod expr;
+mod item;
+
 const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
 
 pub struct LoweringContext<'a, 'hir: 'a> {
@@ -921,7 +930,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
     fn with_new_scopes<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut LoweringContext<'_, '_>) -> T,
+        F: FnOnce(&mut Self) -> T,
     {
         let was_in_loop_condition = self.is_in_loop_condition;
         self.is_in_loop_condition = false;
@@ -2022,7 +2031,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         })
     }
 
-    fn lower_local(&mut self, l: &Local) -> (hir::Local, SmallVec<[NodeId; 1]>) {
+    fn lower_local(&mut self, l: &Local) -> (hir::Local<'hir>, SmallVec<[NodeId; 1]>) {
         let mut ids = SmallVec::<[NodeId; 1]>::new();
         if self.sess.features_untracked().impl_trait_in_bindings {
             if let Some(ref ty) = l.ty {
@@ -2031,21 +2040,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             }
         }
         let parent_def_id = DefId::local(self.current_hir_id_owner.last().unwrap().0);
+        let ty = l.ty.as_ref().map(|t| {
+            self.lower_ty(
+                t,
+                if self.sess.features_untracked().impl_trait_in_bindings {
+                    ImplTraitContext::OpaqueTy(Some(parent_def_id))
+                } else {
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
+                },
+            )
+        });
+        let ty = ty.map(|ty| &*self.arena.alloc(ty.into_inner()));
+        let init = l.init.as_ref().map(|e| self.lower_expr(e));
         (
             hir::Local {
                 hir_id: self.lower_node_id(l.id),
-                ty: l.ty.as_ref().map(|t| {
-                    self.lower_ty(
-                        t,
-                        if self.sess.features_untracked().impl_trait_in_bindings {
-                            ImplTraitContext::OpaqueTy(Some(parent_def_id))
-                        } else {
-                            ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
-                        },
-                    )
-                }),
+                ty,
                 pat: self.lower_pat(&l.pat),
-                init: l.init.as_ref().map(|e| P(self.lower_expr(e))),
+                init,
                 span: l.span,
                 attrs: l.attrs.clone(),
                 source: hir::LocalSource::Normal,
@@ -2586,14 +2598,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         bounds.iter().map(|bound| self.lower_param_bound(bound, itctx.reborrow())).collect()
     }
 
-    fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P<hir::Block> {
+    fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> &'hir hir::Block<'hir> {
+        self.arena.alloc(self.lower_block_noalloc(b, targeted_by_break))
+    }
+
+    fn lower_block_noalloc(&mut self, b: &Block, targeted_by_break: bool) -> hir::Block<'hir> {
         let mut stmts = vec![];
-        let mut expr = None;
+        let mut expr: Option<&'hir _> = None;
 
         for (index, stmt) in b.stmts.iter().enumerate() {
             if index == b.stmts.len() - 1 {
                 if let StmtKind::Expr(ref e) = stmt.kind {
-                    expr = Some(P(self.lower_expr(e)));
+                    expr = Some(self.lower_expr(e));
                 } else {
                     stmts.extend(self.lower_stmt(stmt));
                 }
@@ -2602,24 +2618,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             }
         }
 
-        P(hir::Block {
+        hir::Block {
             hir_id: self.lower_node_id(b.id),
-            stmts: stmts.into(),
+            stmts: self.arena.alloc_from_iter(stmts),
             expr,
             rules: self.lower_block_check_mode(&b.rules),
             span: b.span,
             targeted_by_break,
-        })
+        }
     }
 
     /// Lowers a block directly to an expression, presuming that it
     /// has no attributes and is not targeted by a `break`.
-    fn lower_block_expr(&mut self, b: &Block) -> hir::Expr {
+    fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
         let block = self.lower_block(b, false);
         self.expr_block(block, AttrVec::new())
     }
 
-    fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
+    fn lower_pat(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> {
         let node = match p.kind {
             PatKind::Wild => hir::PatKind::Wild,
             PatKind::Ident(ref binding_mode, ident, ref sub) => {
@@ -2627,7 +2643,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 let node = self.lower_pat_ident(p, binding_mode, ident, lower_sub);
                 node
             }
-            PatKind::Lit(ref e) => hir::PatKind::Lit(P(self.lower_expr(e))),
+            PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)),
             PatKind::TupleStruct(ref path, ref pats) => {
                 let qpath = self.lower_qpath(
                     p.id,
@@ -2640,7 +2656,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 hir::PatKind::TupleStruct(qpath, pats, ddpos)
             }
             PatKind::Or(ref pats) => {
-                hir::PatKind::Or(pats.iter().map(|x| self.lower_pat(x)).collect())
+                hir::PatKind::Or(self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat(x))))
             }
             PatKind::Path(ref qself, ref path) => {
                 let qpath = self.lower_qpath(
@@ -2661,16 +2677,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     ImplTraitContext::disallowed(),
                 );
 
-                let fs = fields
-                    .iter()
-                    .map(|f| hir::FieldPat {
-                        hir_id: self.next_id(),
-                        ident: f.ident,
-                        pat: self.lower_pat(&f.pat),
-                        is_shorthand: f.is_shorthand,
-                        span: f.span,
-                    })
-                    .collect();
+                let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::FieldPat {
+                    hir_id: self.next_id(),
+                    ident: f.ident,
+                    pat: self.lower_pat(&f.pat),
+                    is_shorthand: f.is_shorthand,
+                    span: f.span,
+                }));
                 hir::PatKind::Struct(qpath, fs, etc)
             }
             PatKind::Tuple(ref pats) => {
@@ -2680,8 +2693,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)),
             PatKind::Ref(ref inner, mutbl) => hir::PatKind::Ref(self.lower_pat(inner), mutbl),
             PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => hir::PatKind::Range(
-                P(self.lower_expr(e1)),
-                P(self.lower_expr(e2)),
+                self.lower_expr(e1),
+                self.lower_expr(e2),
                 self.lower_range_end(end),
             ),
             PatKind::Slice(ref pats) => self.lower_pat_slice(pats),
@@ -2700,7 +2713,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         &mut self,
         pats: &[AstP<Pat>],
         ctx: &str,
-    ) -> (HirVec<P<hir::Pat>>, Option<usize>) {
+    ) -> (&'hir [&'hir hir::Pat<'hir>], Option<usize>) {
         let mut elems = Vec::with_capacity(pats.len());
         let mut rest = None;
 
@@ -2728,7 +2741,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             }
         }
 
-        (elems.into(), rest.map(|(ddpos, _)| ddpos))
+        (self.arena.alloc_from_iter(elems), rest.map(|(ddpos, _)| ddpos))
     }
 
     /// Lower a slice pattern of form `[pat_0, ..., pat_n]` into
@@ -2737,7 +2750,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     /// When encountering `($binding_mode $ident @)? ..` (`slice`),
     /// this is interpreted as a sub-slice pattern semantically.
     /// Patterns that follow, which are not like `slice` -- or an error occurs, are in `after`.
-    fn lower_pat_slice(&mut self, pats: &[AstP<Pat>]) -> hir::PatKind {
+    fn lower_pat_slice(&mut self, pats: &[AstP<Pat>]) -> hir::PatKind<'hir> {
         let mut before = Vec::new();
         let mut after = Vec::new();
         let mut slice = None;
@@ -2788,7 +2801,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             }
         }
 
-        hir::PatKind::Slice(before.into(), slice, after.into())
+        hir::PatKind::Slice(
+            self.arena.alloc_from_iter(before),
+            slice,
+            self.arena.alloc_from_iter(after),
+        )
     }
 
     fn lower_pat_ident(
@@ -2796,8 +2813,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         p: &Pat,
         binding_mode: &BindingMode,
         ident: Ident,
-        lower_sub: impl FnOnce(&mut Self) -> Option<P<hir::Pat>>,
-    ) -> hir::PatKind {
+        lower_sub: impl FnOnce(&mut Self) -> Option<&'hir hir::Pat<'hir>>,
+    ) -> hir::PatKind<'hir> {
         match self.resolver.get_partial_res(p.id).map(|d| d.base_res()) {
             // `None` can occur in body-less function signatures
             res @ None | res @ Some(Res::Local(_)) => {
@@ -2824,13 +2841,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }
     }
 
-    fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> P<hir::Pat> {
+    fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> {
         self.pat_with_node_id_of(p, hir::PatKind::Wild)
     }
 
     /// Construct a `Pat` with the `HirId` of `p.id` lowered.
-    fn pat_with_node_id_of(&mut self, p: &Pat, kind: hir::PatKind) -> P<hir::Pat> {
-        P(hir::Pat { hir_id: self.lower_node_id(p.id), kind, span: p.span })
+    fn pat_with_node_id_of(&mut self, p: &Pat, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
+        self.arena.alloc(hir::Pat { hir_id: self.lower_node_id(p.id), kind, span: p.span })
     }
 
     /// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern.
@@ -2843,7 +2860,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     }
 
     /// Used to ban the `..` pattern in places it shouldn't be semantically.
-    fn ban_illegal_rest_pat(&self, sp: Span) -> hir::PatKind {
+    fn ban_illegal_rest_pat(&self, sp: Span) -> hir::PatKind<'hir> {
         self.diagnostic()
             .struct_span_err(sp, "`..` patterns are not allowed here")
             .note("only allowed in tuple, tuple struct, and slice patterns")
@@ -2869,11 +2886,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         })
     }
 
-    fn lower_stmt(&mut self, s: &Stmt) -> SmallVec<[hir::Stmt; 1]> {
+    fn lower_stmt(&mut self, s: &Stmt) -> SmallVec<[hir::Stmt<'hir>; 1]> {
         let kind = match s.kind {
             StmtKind::Local(ref l) => {
                 let (l, item_ids) = self.lower_local(l);
-                let mut ids: SmallVec<[hir::Stmt; 1]> = item_ids
+                let mut ids: SmallVec<[hir::Stmt<'hir>; 1]> = item_ids
                     .into_iter()
                     .map(|item_id| {
                         let item_id = hir::ItemId { id: self.lower_node_id(item_id) };
@@ -2883,7 +2900,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 ids.push({
                     hir::Stmt {
                         hir_id: self.lower_node_id(s.id),
-                        kind: hir::StmtKind::Local(P(l)),
+                        kind: hir::StmtKind::Local(self.arena.alloc(l)),
                         span: s.span,
                     }
                 });
@@ -2905,8 +2922,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     })
                     .collect();
             }
-            StmtKind::Expr(ref e) => hir::StmtKind::Expr(P(self.lower_expr(e))),
-            StmtKind::Semi(ref e) => hir::StmtKind::Semi(P(self.lower_expr(e))),
+            StmtKind::Expr(ref e) => hir::StmtKind::Expr(self.lower_expr(e)),
+            StmtKind::Semi(ref e) => hir::StmtKind::Semi(self.lower_expr(e)),
             StmtKind::Mac(..) => panic!("shouldn't exist here"),
         };
         smallvec![hir::Stmt { hir_id: self.lower_node_id(s.id), kind, span: s.span }]
@@ -2944,74 +2961,75 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
     // Helper methods for building HIR.
 
-    fn stmt(&mut self, span: Span, kind: hir::StmtKind) -> hir::Stmt {
+    fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
         hir::Stmt { span, kind, hir_id: self.next_id() }
     }
 
-    fn stmt_expr(&mut self, span: Span, expr: hir::Expr) -> hir::Stmt {
-        self.stmt(span, hir::StmtKind::Expr(P(expr)))
+    fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
+        self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
     }
 
     fn stmt_let_pat(
         &mut self,
         attrs: AttrVec,
         span: Span,
-        init: Option<P<hir::Expr>>,
-        pat: P<hir::Pat>,
+        init: Option<&'hir hir::Expr<'hir>>,
+        pat: &'hir hir::Pat<'hir>,
         source: hir::LocalSource,
-    ) -> hir::Stmt {
+    ) -> hir::Stmt<'hir> {
         let local = hir::Local { attrs, hir_id: self.next_id(), init, pat, source, span, ty: None };
-        self.stmt(span, hir::StmtKind::Local(P(local)))
+        self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
     }
 
-    fn block_expr(&mut self, expr: P<hir::Expr>) -> hir::Block {
-        self.block_all(expr.span, hir::HirVec::new(), Some(expr))
+    fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
+        self.block_all(expr.span, &[], Some(expr))
     }
 
     fn block_all(
         &mut self,
         span: Span,
-        stmts: hir::HirVec<hir::Stmt>,
-        expr: Option<P<hir::Expr>>,
-    ) -> hir::Block {
-        hir::Block {
+        stmts: &'hir [hir::Stmt<'hir>],
+        expr: Option<&'hir hir::Expr<'hir>>,
+    ) -> &'hir hir::Block<'hir> {
+        let blk = hir::Block {
             stmts,
             expr,
             hir_id: self.next_id(),
             rules: hir::DefaultBlock,
             span,
             targeted_by_break: false,
-        }
+        };
+        self.arena.alloc(blk)
     }
 
     /// Constructs a `true` or `false` literal pattern.
-    fn pat_bool(&mut self, span: Span, val: bool) -> P<hir::Pat> {
+    fn pat_bool(&mut self, span: Span, val: bool) -> &'hir hir::Pat<'hir> {
         let expr = self.expr_bool(span, val);
-        self.pat(span, hir::PatKind::Lit(P(expr)))
+        self.pat(span, hir::PatKind::Lit(expr))
     }
 
-    fn pat_ok(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
-        self.pat_std_enum(span, &[sym::result, sym::Result, sym::Ok], hir_vec![pat])
+    fn pat_ok(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
+        self.pat_std_enum(span, &[sym::result, sym::Result, sym::Ok], arena_vec![self; pat])
     }
 
-    fn pat_err(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
-        self.pat_std_enum(span, &[sym::result, sym::Result, sym::Err], hir_vec![pat])
+    fn pat_err(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
+        self.pat_std_enum(span, &[sym::result, sym::Result, sym::Err], arena_vec![self; pat])
     }
 
-    fn pat_some(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
-        self.pat_std_enum(span, &[sym::option, sym::Option, sym::Some], hir_vec![pat])
+    fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
+        self.pat_std_enum(span, &[sym::option, sym::Option, sym::Some], arena_vec![self; pat])
     }
 
-    fn pat_none(&mut self, span: Span) -> P<hir::Pat> {
-        self.pat_std_enum(span, &[sym::option, sym::Option, sym::None], hir_vec![])
+    fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
+        self.pat_std_enum(span, &[sym::option, sym::Option, sym::None], &[])
     }
 
     fn pat_std_enum(
         &mut self,
         span: Span,
         components: &[Symbol],
-        subpats: hir::HirVec<P<hir::Pat>>,
-    ) -> P<hir::Pat> {
+        subpats: &'hir [&'hir hir::Pat<'hir>],
+    ) -> &'hir hir::Pat<'hir> {
         let path = self.std_path(span, components, None, true);
         let qpath = hir::QPath::Resolved(None, P(path));
         let pt = if subpats.is_empty() {
@@ -3022,7 +3040,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         self.pat(span, pt)
     }
 
-    fn pat_ident(&mut self, span: Span, ident: Ident) -> (P<hir::Pat>, hir::HirId) {
+    fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, hir::HirId) {
         self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::Unannotated)
     }
 
@@ -3031,11 +3049,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         span: Span,
         ident: Ident,
         bm: hir::BindingAnnotation,
-    ) -> (P<hir::Pat>, hir::HirId) {
+    ) -> (&'hir hir::Pat<'hir>, hir::HirId) {
         let hir_id = self.next_id();
 
         (
-            P(hir::Pat {
+            self.arena.alloc(hir::Pat {
                 hir_id,
                 kind: hir::PatKind::Binding(bm, hir_id, ident.with_span_pos(span), None),
                 span,
@@ -3044,12 +3062,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         )
     }
 
-    fn pat_wild(&mut self, span: Span) -> P<hir::Pat> {
+    fn pat_wild(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
         self.pat(span, hir::PatKind::Wild)
     }
 
-    fn pat(&mut self, span: Span, kind: hir::PatKind) -> P<hir::Pat> {
-        P(hir::Pat { hir_id: self.next_id(), kind, span })
+    fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
+        self.arena.alloc(hir::Pat { hir_id: self.next_id(), kind, span })
     }
 
     /// Given a suffix `["b", "c", "d"]`, returns path `::std::b::c::d` when
diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index 8311b9168e4..8a9614c6cb2 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -1,7 +1,7 @@
 use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
+use crate::hir;
 use crate::hir::def::Res;
 use crate::hir::ptr::P;
-use crate::hir::{self, HirVec};
 
 use rustc_data_structures::thin_vec::ThinVec;
 
@@ -13,27 +13,31 @@ use syntax::symbol::{sym, Symbol};
 
 use rustc_error_codes::*;
 
-impl LoweringContext<'_, '_> {
-    fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> HirVec<hir::Expr> {
-        exprs.iter().map(|x| self.lower_expr(x)).collect()
+impl<'hir> LoweringContext<'_, 'hir> {
+    fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] {
+        self.arena.alloc_from_iter(exprs.iter().map(|x| self.lower_expr_mut(x)))
     }
 
-    pub(super) fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
+    pub(super) fn lower_expr(&mut self, e: &Expr) -> &'hir hir::Expr<'hir> {
+        self.arena.alloc(self.lower_expr_mut(e))
+    }
+
+    pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
         let kind = match e.kind {
-            ExprKind::Box(ref inner) => hir::ExprKind::Box(P(self.lower_expr(inner))),
+            ExprKind::Box(ref inner) => hir::ExprKind::Box(self.lower_expr(inner)),
             ExprKind::Array(ref exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
             ExprKind::Repeat(ref expr, ref count) => {
-                let expr = P(self.lower_expr(expr));
+                let expr = self.lower_expr(expr);
                 let count = self.lower_anon_const(count);
                 hir::ExprKind::Repeat(expr, count)
             }
             ExprKind::Tup(ref elts) => hir::ExprKind::Tup(self.lower_exprs(elts)),
             ExprKind::Call(ref f, ref args) => {
-                let f = P(self.lower_expr(f));
+                let f = self.lower_expr(f);
                 hir::ExprKind::Call(f, self.lower_exprs(args))
             }
             ExprKind::MethodCall(ref seg, ref args) => {
-                let hir_seg = P(self.lower_path_segment(
+                let hir_seg = self.arena.alloc(self.lower_path_segment(
                     e.span,
                     seg,
                     ParamMode::Optional,
@@ -47,26 +51,28 @@ impl LoweringContext<'_, '_> {
             }
             ExprKind::Binary(binop, ref lhs, ref rhs) => {
                 let binop = self.lower_binop(binop);
-                let lhs = P(self.lower_expr(lhs));
-                let rhs = P(self.lower_expr(rhs));
+                let lhs = self.lower_expr(lhs);
+                let rhs = self.lower_expr(rhs);
                 hir::ExprKind::Binary(binop, lhs, rhs)
             }
             ExprKind::Unary(op, ref ohs) => {
                 let op = self.lower_unop(op);
-                let ohs = P(self.lower_expr(ohs));
+                let ohs = self.lower_expr(ohs);
                 hir::ExprKind::Unary(op, ohs)
             }
             ExprKind::Lit(ref l) => hir::ExprKind::Lit(respan(l.span, l.kind.clone())),
             ExprKind::Cast(ref expr, ref ty) => {
-                let expr = P(self.lower_expr(expr));
-                hir::ExprKind::Cast(expr, self.lower_ty(ty, ImplTraitContext::disallowed()))
+                let expr = self.lower_expr(expr);
+                let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
+                hir::ExprKind::Cast(expr, self.arena.alloc(ty.into_inner()))
             }
             ExprKind::Type(ref expr, ref ty) => {
-                let expr = P(self.lower_expr(expr));
-                hir::ExprKind::Type(expr, self.lower_ty(ty, ImplTraitContext::disallowed()))
+                let expr = self.lower_expr(expr);
+                let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
+                hir::ExprKind::Type(expr, self.arena.alloc(ty.into_inner()))
             }
             ExprKind::AddrOf(k, m, ref ohs) => {
-                let ohs = P(self.lower_expr(ohs));
+                let ohs = self.lower_expr(ohs);
                 hir::ExprKind::AddrOf(k, m, ohs)
             }
             ExprKind::Let(ref pat, ref scrutinee) => self.lower_expr_let(e.span, pat, scrutinee),
@@ -85,8 +91,8 @@ impl LoweringContext<'_, '_> {
             }),
             ExprKind::TryBlock(ref body) => self.lower_expr_try_block(body),
             ExprKind::Match(ref expr, ref arms) => hir::ExprKind::Match(
-                P(self.lower_expr(expr)),
-                arms.iter().map(|x| self.lower_arm(x)).collect(),
+                self.lower_expr(expr),
+                self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))),
                 hir::MatchSource::Normal,
             ),
             ExprKind::Async(capture_clause, closure_node_id, ref block) => self.make_async_expr(
@@ -123,16 +129,16 @@ impl LoweringContext<'_, '_> {
                 self.lower_label(opt_label),
             ),
             ExprKind::Assign(ref el, ref er, span) => {
-                hir::ExprKind::Assign(P(self.lower_expr(el)), P(self.lower_expr(er)), span)
+                hir::ExprKind::Assign(self.lower_expr(el), self.lower_expr(er), span)
             }
             ExprKind::AssignOp(op, ref el, ref er) => hir::ExprKind::AssignOp(
                 self.lower_binop(op),
-                P(self.lower_expr(el)),
-                P(self.lower_expr(er)),
+                self.lower_expr(el),
+                self.lower_expr(er),
             ),
-            ExprKind::Field(ref el, ident) => hir::ExprKind::Field(P(self.lower_expr(el)), ident),
+            ExprKind::Field(ref el, ident) => hir::ExprKind::Field(self.lower_expr(el), ident),
             ExprKind::Index(ref el, ref er) => {
-                hir::ExprKind::Index(P(self.lower_expr(el)), P(self.lower_expr(er)))
+                hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er))
             }
             ExprKind::Range(Some(ref e1), Some(ref e2), RangeLimits::Closed) => {
                 self.lower_expr_range_closed(e.span, e1, e2)
@@ -150,28 +156,34 @@ impl LoweringContext<'_, '_> {
                 );
                 hir::ExprKind::Path(qpath)
             }
-            ExprKind::Break(opt_label, ref opt_expr) => hir::ExprKind::Break(
-                self.lower_jump_destination(e.id, opt_label),
-                opt_expr.as_ref().map(|x| P(self.lower_expr(x))),
-            ),
+            ExprKind::Break(opt_label, ref opt_expr) => {
+                let opt_expr = opt_expr.as_ref().map(|x| self.lower_expr(x));
+                hir::ExprKind::Break(self.lower_jump_destination(e.id, opt_label), opt_expr)
+            }
             ExprKind::Continue(opt_label) => {
                 hir::ExprKind::Continue(self.lower_jump_destination(e.id, opt_label))
             }
-            ExprKind::Ret(ref e) => hir::ExprKind::Ret(e.as_ref().map(|x| P(self.lower_expr(x)))),
+            ExprKind::Ret(ref e) => {
+                let e = e.as_ref().map(|x| self.lower_expr(x));
+                hir::ExprKind::Ret(e)
+            }
             ExprKind::InlineAsm(ref asm) => self.lower_expr_asm(asm),
-            ExprKind::Struct(ref path, ref fields, ref maybe_expr) => hir::ExprKind::Struct(
-                P(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) => {
+                let maybe_expr = maybe_expr.as_ref().map(|x| self.lower_expr(x));
+                hir::ExprKind::Struct(
+                    self.arena.alloc(self.lower_qpath(
+                        e.id,
+                        &None,
+                        path,
+                        ParamMode::Optional,
+                        ImplTraitContext::disallowed(),
+                    )),
+                    self.arena.alloc_from_iter(fields.iter().map(|x| self.lower_field(x))),
+                    maybe_expr,
+                )
+            }
             ExprKind::Paren(ref ex) => {
-                let mut ex = self.lower_expr(ex);
+                let mut ex = self.lower_expr_mut(ex);
                 // Include parens in span, but only if it is a super-span.
                 if e.span.contains(ex.span) {
                     ex.span = e.span;
@@ -237,7 +249,7 @@ impl LoweringContext<'_, '_> {
     /// ```rust
     /// match scrutinee { pats => true, _ => false }
     /// ```
-    fn lower_expr_let(&mut self, span: Span, pat: &Pat, scrutinee: &Expr) -> hir::ExprKind {
+    fn lower_expr_let(&mut self, span: Span, pat: &Pat, scrutinee: &Expr) -> hir::ExprKind<'hir> {
         // If we got here, the `let` expression is not allowed.
 
         if self.sess.opts.unstable_features.is_nightly_build() {
@@ -266,16 +278,16 @@ impl LoweringContext<'_, '_> {
         let then_arm = {
             let pat = self.lower_pat(pat);
             let expr = self.expr_bool(span, true);
-            self.arm(pat, P(expr))
+            self.arm(pat, expr)
         };
         let else_arm = {
             let pat = self.pat_wild(span);
             let expr = self.expr_bool(span, false);
-            self.arm(pat, P(expr))
+            self.arm(pat, expr)
         };
         hir::ExprKind::Match(
-            P(scrutinee),
-            vec![then_arm, else_arm].into(),
+            scrutinee,
+            arena_vec![self; then_arm, else_arm],
             hir::MatchSource::Normal,
         )
     }
@@ -286,7 +298,7 @@ impl LoweringContext<'_, '_> {
         cond: &Expr,
         then: &Block,
         else_opt: Option<&Expr>,
-    ) -> hir::ExprKind {
+    ) -> hir::ExprKind<'hir> {
         // FIXME(#53667): handle lowering of && and parens.
 
         // `_ => else_block` where `else_block` is `{}` if there's `None`:
@@ -295,7 +307,7 @@ impl LoweringContext<'_, '_> {
             None => (self.expr_block_empty(span), false),
             Some(els) => (self.lower_expr(els), true),
         };
-        let else_arm = self.arm(else_pat, P(else_expr));
+        let else_arm = self.arm(else_pat, else_expr);
 
         // Handle then + scrutinee:
         let then_expr = self.lower_block_expr(then);
@@ -315,14 +327,14 @@ impl LoweringContext<'_, '_> {
                 // Wrap in a construct equivalent to `{ let _t = $cond; _t }`
                 // to preserve drop semantics since `if cond { ... }` does not
                 // let temporaries live outside of `cond`.
-                let cond = self.expr_drop_temps(span_block, P(cond), ThinVec::new());
+                let cond = self.expr_drop_temps(span_block, cond, ThinVec::new());
                 let pat = self.pat_bool(span, true);
                 (pat, cond, hir::MatchSource::IfDesugar { contains_else_clause })
             }
         };
-        let then_arm = self.arm(then_pat, P(then_expr));
+        let then_arm = self.arm(then_pat, self.arena.alloc(then_expr));
 
-        hir::ExprKind::Match(P(scrutinee), vec![then_arm, else_arm].into(), desugar)
+        hir::ExprKind::Match(scrutinee, arena_vec![self; then_arm, else_arm], desugar)
     }
 
     fn lower_expr_while_in_loop_scope(
@@ -331,7 +343,7 @@ impl LoweringContext<'_, '_> {
         cond: &Expr,
         body: &Block,
         opt_label: Option<Label>,
-    ) -> hir::ExprKind {
+    ) -> hir::ExprKind<'hir> {
         // FIXME(#53667): handle lowering of && and parens.
 
         // Note that the block AND the condition are evaluated in the loop scope.
@@ -379,28 +391,36 @@ impl LoweringContext<'_, '_> {
                 // Wrap in a construct equivalent to `{ let _t = $cond; _t }`
                 // to preserve drop semantics since `while cond { ... }` does not
                 // let temporaries live outside of `cond`.
-                let cond = self.expr_drop_temps(span_block, P(cond), ThinVec::new());
+                let cond = self.expr_drop_temps(span_block, cond, ThinVec::new());
                 // `true => <then>`:
                 let pat = self.pat_bool(span, true);
                 (pat, cond, hir::MatchSource::WhileDesugar, hir::LoopSource::While)
             }
         };
-        let then_arm = self.arm(then_pat, P(then_expr));
+        let then_arm = self.arm(then_pat, self.arena.alloc(then_expr));
 
         // `match <scrutinee> { ... }`
-        let match_expr =
-            self.expr_match(scrutinee.span, P(scrutinee), hir_vec![then_arm, else_arm], desugar);
+        let match_expr = self.expr_match(
+            scrutinee.span,
+            scrutinee,
+            arena_vec![self; then_arm, else_arm],
+            desugar,
+        );
 
         // `[opt_ident]: loop { ... }`
-        hir::ExprKind::Loop(P(self.block_expr(P(match_expr))), self.lower_label(opt_label), source)
+        hir::ExprKind::Loop(
+            self.block_expr(self.arena.alloc(match_expr)),
+            self.lower_label(opt_label),
+            source,
+        )
     }
 
     /// Desugar `try { <stmts>; <expr> }` into `{ <stmts>; ::std::ops::Try::from_ok(<expr>) }`,
     /// `try { <stmts>; }` into `{ <stmts>; ::std::ops::Try::from_ok(()) }`
     /// and save the block id to use it as a break target for desugaring of the `?` operator.
-    fn lower_expr_try_block(&mut self, body: &Block) -> hir::ExprKind {
+    fn lower_expr_try_block(&mut self, body: &Block) -> hir::ExprKind<'hir> {
         self.with_catch_scope(body.id, |this| {
-            let mut block = this.lower_block(body, true).into_inner();
+            let mut block = this.lower_block_noalloc(body, true);
 
             let try_span = this.mark_span_with_reason(
                 DesugaringKind::TryBlock,
@@ -409,10 +429,10 @@ impl LoweringContext<'_, '_> {
             );
 
             // Final expression of the block (if present) or `()` with span at the end of block
-            let tail_expr = block.expr.take().map_or_else(
-                || this.expr_unit(this.sess.source_map().end_point(try_span)),
-                |x: P<hir::Expr>| x.into_inner(),
-            );
+            let tail_expr = block
+                .expr
+                .take()
+                .unwrap_or_else(|| this.expr_unit(this.sess.source_map().end_point(try_span)));
 
             let ok_wrapped_span =
                 this.mark_span_with_reason(DesugaringKind::TryBlock, tail_expr.span, None);
@@ -425,7 +445,7 @@ impl LoweringContext<'_, '_> {
                 ok_wrapped_span,
             ));
 
-            hir::ExprKind::Block(P(block), None)
+            hir::ExprKind::Block(this.arena.alloc(block), None)
         })
     }
 
@@ -433,24 +453,25 @@ impl LoweringContext<'_, '_> {
         &mut self,
         method: Symbol,
         method_span: Span,
-        expr: hir::Expr,
+        expr: &'hir hir::Expr<'hir>,
         overall_span: Span,
-    ) -> P<hir::Expr> {
+    ) -> &'hir hir::Expr<'hir> {
         let path = &[sym::ops, sym::Try, method];
-        let constructor = P(self.expr_std_path(method_span, path, None, ThinVec::new()));
-        P(self.expr_call(overall_span, constructor, hir_vec![expr]))
+        let constructor =
+            self.arena.alloc(self.expr_std_path(method_span, path, None, ThinVec::new()));
+        self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
     }
 
-    fn lower_arm(&mut self, arm: &Arm) -> hir::Arm {
+    fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> {
         hir::Arm {
             hir_id: self.next_id(),
-            attrs: self.lower_attrs(&arm.attrs),
+            attrs: self.lower_attrs_arena(&arm.attrs),
             pat: self.lower_pat(&arm.pat),
             guard: match arm.guard {
-                Some(ref x) => Some(hir::Guard::If(P(self.lower_expr(x)))),
+                Some(ref x) => Some(hir::Guard::If(self.lower_expr(x))),
                 _ => None,
             },
-            body: P(self.lower_expr(&arm.body)),
+            body: self.lower_expr(&arm.body),
             span: arm.span,
         }
     }
@@ -462,14 +483,16 @@ impl LoweringContext<'_, '_> {
         ret_ty: Option<AstP<Ty>>,
         span: Span,
         async_gen_kind: hir::AsyncGeneratorKind,
-        body: impl FnOnce(&mut LoweringContext<'_, '_>) -> hir::Expr,
-    ) -> hir::ExprKind {
+        body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
+    ) -> hir::ExprKind<'hir> {
         let output = match ret_ty {
             Some(ty) => FunctionRetTy::Ty(ty),
             None => FunctionRetTy::Default(span),
         };
         let ast_decl = FnDecl { inputs: vec![], output };
-        let decl = self.lower_fn_decl(&ast_decl, None, /* impl trait allowed */ false, None);
+        let decl = self.arena.alloc(
+            self.lower_fn_decl(&ast_decl, None, /* impl trait allowed */ false, None).into_inner(),
+        );
         let body_id = self.lower_fn_body(&ast_decl, |this| {
             this.generator_kind = Some(hir::GeneratorKind::Async(async_gen_kind));
             body(this)
@@ -501,7 +524,7 @@ impl LoweringContext<'_, '_> {
         );
 
         // `future::from_generator(generator)`:
-        hir::ExprKind::Call(P(gen_future), hir_vec![generator])
+        hir::ExprKind::Call(self.arena.alloc(gen_future), arena_vec![self; generator])
     }
 
     /// Desugar `<expr>.await` into:
@@ -518,7 +541,7 @@ impl LoweringContext<'_, '_> {
     ///     }
     /// }
     /// ```
-    fn lower_expr_await(&mut self, await_span: Span, expr: &Expr) -> hir::ExprKind {
+    fn lower_expr_await(&mut self, await_span: Span, expr: &Expr) -> hir::ExprKind<'hir> {
         match self.generator_kind {
             Some(hir::GeneratorKind::Async(_)) => {}
             Some(hir::GeneratorKind::Gen) | None => {
@@ -550,7 +573,7 @@ impl LoweringContext<'_, '_> {
         //     ::std::pin::Pin::new_unchecked(&mut pinned)
         // })`
         let poll_expr = {
-            let pinned = P(self.expr_ident(span, pinned_ident, pinned_pat_hid));
+            let pinned = self.expr_ident(span, pinned_ident, pinned_pat_hid);
             let ref_mut_pinned = self.expr_mut_addr_of(span, pinned);
             let pin_ty_id = self.next_id();
             let new_unchecked_expr_kind = self.expr_call_std_assoc_fn(
@@ -558,15 +581,16 @@ impl LoweringContext<'_, '_> {
                 span,
                 &[sym::pin, sym::Pin],
                 "new_unchecked",
-                hir_vec![ref_mut_pinned],
+                arena_vec![self; ref_mut_pinned],
             );
-            let new_unchecked = P(self.expr(span, new_unchecked_expr_kind, ThinVec::new()));
+            let new_unchecked =
+                self.arena.alloc(self.expr(span, new_unchecked_expr_kind, ThinVec::new()));
             let unsafe_expr = self.expr_unsafe(new_unchecked);
-            P(self.expr_call_std_path(
+            self.expr_call_std_path(
                 gen_future_span,
                 &[sym::future, sym::poll_with_tls_context],
-                hir_vec![unsafe_expr],
-            ))
+                arena_vec![self; unsafe_expr],
+            )
         };
 
         // `::std::task::Poll::Ready(result) => break result`
@@ -575,22 +599,24 @@ impl LoweringContext<'_, '_> {
         let ready_arm = {
             let x_ident = Ident::with_dummy_span(sym::result);
             let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident);
-            let x_expr = P(self.expr_ident(span, x_ident, x_pat_hid));
-            let ready_pat =
-                self.pat_std_enum(span, &[sym::task, sym::Poll, sym::Ready], hir_vec![x_pat]);
-            let break_x = self.with_loop_scope(loop_node_id, |this| {
+            let x_expr = self.expr_ident(span, x_ident, x_pat_hid);
+            let ready_pat = self.pat_std_enum(
+                span,
+                &[sym::task, sym::Poll, sym::Ready],
+                arena_vec![self; x_pat],
+            );
+            let break_x = self.with_loop_scope(loop_node_id, move |this| {
                 let expr_break =
                     hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
-                P(this.expr(await_span, expr_break, ThinVec::new()))
+                this.arena.alloc(this.expr(await_span, expr_break, ThinVec::new()))
             });
             self.arm(ready_pat, break_x)
         };
 
         // `::std::task::Poll::Pending => {}`
         let pending_arm = {
-            let pending_pat =
-                self.pat_std_enum(span, &[sym::task, sym::Poll, sym::Pending], hir_vec![]);
-            let empty_block = P(self.expr_block_empty(span));
+            let pending_pat = self.pat_std_enum(span, &[sym::task, sym::Poll, sym::Pending], &[]);
+            let empty_block = self.expr_block_empty(span);
             self.arm(pending_pat, empty_block)
         };
 
@@ -598,7 +624,7 @@ impl LoweringContext<'_, '_> {
             let match_expr = self.expr_match(
                 span,
                 poll_expr,
-                hir_vec![ready_arm, pending_arm],
+                arena_vec![self; ready_arm, pending_arm],
                 hir::MatchSource::AwaitDesugar,
             );
             self.stmt_expr(span, match_expr)
@@ -608,16 +634,16 @@ impl LoweringContext<'_, '_> {
             let unit = self.expr_unit(span);
             let yield_expr = self.expr(
                 span,
-                hir::ExprKind::Yield(P(unit), hir::YieldSource::Await),
+                hir::ExprKind::Yield(unit, hir::YieldSource::Await),
                 ThinVec::new(),
             );
             self.stmt_expr(span, yield_expr)
         };
 
-        let loop_block = P(self.block_all(span, hir_vec![inner_match_stmt, yield_stmt], None));
+        let loop_block = self.block_all(span, arena_vec![self; inner_match_stmt, yield_stmt], None);
 
         // loop { .. }
-        let loop_expr = P(hir::Expr {
+        let loop_expr = self.arena.alloc(hir::Expr {
             hir_id: loop_hir_id,
             kind: hir::ExprKind::Loop(loop_block, None, hir::LoopSource::Loop),
             span,
@@ -630,8 +656,8 @@ impl LoweringContext<'_, '_> {
         // match <expr> {
         //     mut pinned => loop { .. }
         // }
-        let expr = P(self.lower_expr(expr));
-        hir::ExprKind::Match(expr, hir_vec![pinned_arm], hir::MatchSource::AwaitDesugar)
+        let expr = self.lower_expr(expr);
+        hir::ExprKind::Match(expr, arena_vec![self; pinned_arm], hir::MatchSource::AwaitDesugar)
     }
 
     fn lower_expr_closure(
@@ -641,16 +667,17 @@ impl LoweringContext<'_, '_> {
         decl: &FnDecl,
         body: &Expr,
         fn_decl_span: Span,
-    ) -> hir::ExprKind {
+    ) -> hir::ExprKind<'hir> {
         // Lower outside new scope to preserve `is_in_loop_condition`.
         let fn_decl = self.lower_fn_decl(decl, None, false, None);
+        let fn_decl = self.arena.alloc(fn_decl.into_inner());
 
-        self.with_new_scopes(|this| {
+        self.with_new_scopes(move |this| {
             let prev = this.current_item;
             this.current_item = Some(fn_decl_span);
             let mut generator_kind = None;
             let body_id = this.lower_fn_body(decl, |this| {
-                let e = this.lower_expr(body);
+                let e = this.lower_expr_mut(body);
                 generator_kind = this.generator_kind;
                 e
             });
@@ -699,15 +726,16 @@ impl LoweringContext<'_, '_> {
         decl: &FnDecl,
         body: &Expr,
         fn_decl_span: Span,
-    ) -> hir::ExprKind {
+    ) -> hir::ExprKind<'hir> {
         let outer_decl =
             FnDecl { inputs: decl.inputs.clone(), output: FunctionRetTy::Default(fn_decl_span) };
         // We need to lower the declaration outside the new scope, because we
         // have to conserve the state of being inside a loop condition for the
         // closure argument types.
         let fn_decl = self.lower_fn_decl(&outer_decl, None, false, None);
+        let fn_decl = self.arena.alloc(fn_decl.into_inner());
 
-        self.with_new_scopes(|this| {
+        self.with_new_scopes(move |this| {
             // FIXME(cramertj): allow `async` non-`move` closures with arguments.
             if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() {
                 struct_span_err!(
@@ -734,7 +762,7 @@ impl LoweringContext<'_, '_> {
                     async_ret_ty,
                     body.span,
                     hir::AsyncGeneratorKind::Closure,
-                    |this| this.with_new_scopes(|this| this.lower_expr(body)),
+                    |this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
                 );
                 this.expr(fn_decl_span, async_body, ThinVec::new())
             });
@@ -743,16 +771,16 @@ impl LoweringContext<'_, '_> {
     }
 
     /// Desugar `<start>..=<end>` into `std::ops::RangeInclusive::new(<start>, <end>)`.
-    fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::ExprKind {
+    fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::ExprKind<'hir> {
         let id = self.next_id();
-        let e1 = self.lower_expr(e1);
-        let e2 = self.lower_expr(e2);
+        let e1 = self.lower_expr_mut(e1);
+        let e2 = self.lower_expr_mut(e2);
         self.expr_call_std_assoc_fn(
             id,
             span,
             &[sym::ops, sym::RangeInclusive],
             "new",
-            hir_vec![e1, e2],
+            arena_vec![self; e1, e2],
         )
     }
 
@@ -762,7 +790,7 @@ impl LoweringContext<'_, '_> {
         e1: Option<&Expr>,
         e2: Option<&Expr>,
         lims: RangeLimits,
-    ) -> hir::ExprKind {
+    ) -> hir::ExprKind<'hir> {
         use syntax::ast::RangeLimits::*;
 
         let path = match (e1, e2, lims) {
@@ -777,16 +805,13 @@ impl LoweringContext<'_, '_> {
             }
         };
 
-        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 fields = self.arena.alloc_from_iter(
+            e1.iter().map(|e| ("start", e)).chain(e2.iter().map(|e| ("end", e))).map(|(s, e)| {
+                let expr = self.lower_expr(&e);
                 let ident = Ident::new(Symbol::intern(s), e.span);
                 self.field(ident, expr, e.span)
-            })
-            .collect::<P<[hir::Field]>>();
+            }),
+        );
 
         let is_unit = fields.is_empty();
         let struct_path = [sym::ops, path];
@@ -796,7 +821,7 @@ impl LoweringContext<'_, '_> {
         if is_unit {
             hir::ExprKind::Path(struct_path)
         } else {
-            hir::ExprKind::Struct(P(struct_path), fields, None)
+            hir::ExprKind::Struct(self.arena.alloc(struct_path), fields, None)
         }
     }
 
@@ -837,7 +862,7 @@ impl LoweringContext<'_, '_> {
 
     fn with_catch_scope<T, F>(&mut self, catch_id: NodeId, f: F) -> T
     where
-        F: FnOnce(&mut LoweringContext<'_, '_>) -> T,
+        F: FnOnce(&mut Self) -> T,
     {
         let len = self.catch_scopes.len();
         self.catch_scopes.push(catch_id);
@@ -856,7 +881,7 @@ impl LoweringContext<'_, '_> {
 
     fn with_loop_scope<T, F>(&mut self, loop_id: NodeId, f: F) -> T
     where
-        F: FnOnce(&mut LoweringContext<'_, '_>) -> T,
+        F: FnOnce(&mut Self) -> 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;
@@ -881,7 +906,7 @@ impl LoweringContext<'_, '_> {
 
     fn with_loop_condition_scope<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut LoweringContext<'_, '_>) -> T,
+        F: FnOnce(&mut Self) -> T,
     {
         let was_in_loop_condition = self.is_in_loop_condition;
         self.is_in_loop_condition = true;
@@ -893,7 +918,7 @@ impl LoweringContext<'_, '_> {
         result
     }
 
-    fn lower_expr_asm(&mut self, asm: &InlineAsm) -> hir::ExprKind {
+    fn lower_expr_asm(&mut self, asm: &InlineAsm) -> hir::ExprKind<'hir> {
         let inner = hir::InlineAsmInner {
             inputs: asm.inputs.iter().map(|&(ref c, _)| c.clone()).collect(),
             outputs: asm
@@ -915,23 +940,27 @@ impl LoweringContext<'_, '_> {
         };
         let hir_asm = hir::InlineAsm {
             inner,
-            inputs_exprs: asm.inputs.iter().map(|&(_, ref input)| self.lower_expr(input)).collect(),
-            outputs_exprs: asm.outputs.iter().map(|out| self.lower_expr(&out.expr)).collect(),
+            inputs_exprs: self.arena.alloc_from_iter(
+                asm.inputs.iter().map(|&(_, ref input)| self.lower_expr_mut(input)),
+            ),
+            outputs_exprs: self
+                .arena
+                .alloc_from_iter(asm.outputs.iter().map(|out| self.lower_expr_mut(&out.expr))),
         };
-        hir::ExprKind::InlineAsm(P(hir_asm))
+        hir::ExprKind::InlineAsm(self.arena.alloc(hir_asm))
     }
 
-    fn lower_field(&mut self, f: &Field) -> hir::Field {
+    fn lower_field(&mut self, f: &Field) -> hir::Field<'hir> {
         hir::Field {
             hir_id: self.next_id(),
             ident: f.ident,
-            expr: P(self.lower_expr(&f.expr)),
+            expr: self.lower_expr(&f.expr),
             span: f.span,
             is_shorthand: f.is_shorthand,
         }
     }
 
-    fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind {
+    fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind<'hir> {
         match self.generator_kind {
             Some(hir::GeneratorKind::Gen) => {}
             Some(hir::GeneratorKind::Async(_)) => {
@@ -944,7 +973,7 @@ impl LoweringContext<'_, '_> {
         let expr =
             opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span));
 
-        hir::ExprKind::Yield(P(expr), hir::YieldSource::Yield)
+        hir::ExprKind::Yield(expr, hir::YieldSource::Yield)
     }
 
     /// Desugar `ExprForLoop` from: `[opt_ident]: for <pat> in <head> <body>` into:
@@ -973,9 +1002,9 @@ impl LoweringContext<'_, '_> {
         head: &Expr,
         body: &Block,
         opt_label: Option<Label>,
-    ) -> hir::Expr {
+    ) -> hir::Expr<'hir> {
         // expand <head>
-        let mut head = self.lower_expr(head);
+        let mut head = self.lower_expr_mut(head);
         let desugared_span = self.mark_span_with_reason(DesugaringKind::ForLoop, head.span, None);
         head.span = desugared_span;
 
@@ -992,9 +1021,9 @@ impl LoweringContext<'_, '_> {
         let pat_arm = {
             let val_ident = Ident::with_dummy_span(sym::val);
             let (val_pat, val_pat_hid) = self.pat_ident(pat.span, val_ident);
-            let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat_hid));
-            let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat_hid));
-            let assign = P(self.expr(
+            let val_expr = self.expr_ident(pat.span, val_ident, val_pat_hid);
+            let next_expr = self.expr_ident(pat.span, next_ident, next_pat_hid);
+            let assign = self.arena.alloc(self.expr(
                 pat.span,
                 hir::ExprKind::Assign(next_expr, val_expr, pat.span),
                 ThinVec::new(),
@@ -1017,18 +1046,18 @@ impl LoweringContext<'_, '_> {
 
         // `match ::std::iter::Iterator::next(&mut iter) { ... }`
         let match_expr = {
-            let iter = P(self.expr_ident(desugared_span, iter, iter_pat_nid));
+            let iter = self.expr_ident(desugared_span, iter, iter_pat_nid);
             let ref_mut_iter = self.expr_mut_addr_of(desugared_span, iter);
             let next_path = &[sym::iter, sym::Iterator, sym::next];
             let next_expr =
-                P(self.expr_call_std_path(desugared_span, next_path, hir_vec![ref_mut_iter]));
-            let arms = hir_vec![pat_arm, break_arm];
+                self.expr_call_std_path(desugared_span, next_path, arena_vec![self; ref_mut_iter]);
+            let arms = arena_vec![self; pat_arm, break_arm];
 
             self.expr_match(desugared_span, next_expr, arms, hir::MatchSource::ForLoopDesugar)
         };
         let match_stmt = self.stmt_expr(desugared_span, match_expr);
 
-        let next_expr = P(self.expr_ident(desugared_span, next_ident, next_pat_hid));
+        let next_expr = self.expr_ident(desugared_span, next_ident, next_pat_hid);
 
         // `let mut __next`
         let next_let = self.stmt_let_pat(
@@ -1053,13 +1082,16 @@ impl LoweringContext<'_, '_> {
         let body_expr = self.expr_block(body_block, ThinVec::new());
         let body_stmt = self.stmt_expr(body.span, body_expr);
 
-        let loop_block =
-            P(self.block_all(e.span, hir_vec![next_let, match_stmt, pat_let, body_stmt], None));
+        let loop_block = self.block_all(
+            e.span,
+            arena_vec![self; next_let, match_stmt, pat_let, body_stmt],
+            None,
+        );
 
         // `[opt_ident]: loop { ... }`
         let kind =
             hir::ExprKind::Loop(loop_block, self.lower_label(opt_label), hir::LoopSource::ForLoop);
-        let loop_expr = P(hir::Expr {
+        let loop_expr = self.arena.alloc(hir::Expr {
             hir_id: self.lower_node_id(e.id),
             kind,
             span: e.span,
@@ -1072,13 +1104,13 @@ impl LoweringContext<'_, '_> {
         // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
         let into_iter_expr = {
             let into_iter_path = &[sym::iter, sym::IntoIterator, sym::into_iter];
-            P(self.expr_call_std_path(desugared_span, into_iter_path, hir_vec![head]))
+            self.expr_call_std_path(desugared_span, into_iter_path, arena_vec![self; head])
         };
 
-        let match_expr = P(self.expr_match(
+        let match_expr = self.arena.alloc(self.expr_match(
             desugared_span,
             into_iter_expr,
-            hir_vec![iter_arm],
+            arena_vec![self; iter_arm],
             hir::MatchSource::ForLoopDesugar,
         ));
 
@@ -1088,7 +1120,7 @@ impl LoweringContext<'_, '_> {
         // surrounding scope of the `match` since the `match` is not a terminating scope.
         //
         // Also, add the attributes to the outer returned expr node.
-        self.expr_drop_temps(desugared_span, match_expr, e.attrs.clone())
+        self.expr_drop_temps_mut(desugared_span, match_expr, e.attrs.clone())
     }
 
     /// Desugar `ExprKind::Try` from: `<expr>?` into:
@@ -1102,7 +1134,7 @@ impl LoweringContext<'_, '_> {
     ///                 return Try::from_error(From::from(err)),
     /// }
     /// ```
-    fn lower_expr_try(&mut self, span: Span, sub_expr: &Expr) -> hir::ExprKind {
+    fn lower_expr_try(&mut self, span: Span, sub_expr: &Expr) -> hir::ExprKind<'hir> {
         let unstable_span = self.mark_span_with_reason(
             DesugaringKind::QuestionMark,
             span,
@@ -1118,10 +1150,10 @@ impl LoweringContext<'_, '_> {
         // `Try::into_result(<expr>)`
         let scrutinee = {
             // expand <expr>
-            let sub_expr = self.lower_expr(sub_expr);
+            let sub_expr = self.lower_expr_mut(sub_expr);
 
             let path = &[sym::ops, sym::Try, sym::into_result];
-            P(self.expr_call_std_path(unstable_span, path, hir_vec![sub_expr]))
+            self.expr_call_std_path(unstable_span, path, arena_vec![self; sub_expr])
         };
 
         // `#[allow(unreachable_code)]`
@@ -1141,7 +1173,7 @@ impl LoweringContext<'_, '_> {
         let ok_arm = {
             let val_ident = Ident::with_dummy_span(sym::val);
             let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident);
-            let val_expr = P(self.expr_ident_with_attrs(
+            let val_expr = self.arena.alloc(self.expr_ident_with_attrs(
                 span,
                 val_ident,
                 val_pat_nid,
@@ -1158,8 +1190,8 @@ impl LoweringContext<'_, '_> {
             let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident);
             let from_expr = {
                 let from_path = &[sym::convert, sym::From, sym::from];
-                let err_expr = self.expr_ident(try_span, err_ident, err_local_nid);
-                self.expr_call_std_path(try_span, from_path, hir_vec![err_expr])
+                let err_expr = self.expr_ident_mut(try_span, err_ident, err_local_nid);
+                self.expr_call_std_path(try_span, from_path, arena_vec![self; err_expr])
             };
             let from_err_expr =
                 self.wrap_in_try_constructor(sym::from_error, unstable_span, from_expr, try_span);
@@ -1167,7 +1199,7 @@ impl LoweringContext<'_, '_> {
             let catch_scope = self.catch_scopes.last().map(|x| *x);
             let ret_expr = if let Some(catch_node) = catch_scope {
                 let target_id = Ok(self.lower_node_id(catch_node));
-                P(self.expr(
+                self.arena.alloc(self.expr(
                     try_span,
                     hir::ExprKind::Break(
                         hir::Destination { label: None, target_id },
@@ -1176,14 +1208,22 @@ impl LoweringContext<'_, '_> {
                     thin_attrs,
                 ))
             } else {
-                P(self.expr(try_span, hir::ExprKind::Ret(Some(from_err_expr)), thin_attrs))
+                self.arena.alloc(self.expr(
+                    try_span,
+                    hir::ExprKind::Ret(Some(from_err_expr)),
+                    thin_attrs,
+                ))
             };
 
             let err_pat = self.pat_err(try_span, err_local);
             self.arm(err_pat, ret_expr)
         };
 
-        hir::ExprKind::Match(scrutinee, hir_vec![err_arm, ok_arm], hir::MatchSource::TryDesugar)
+        hir::ExprKind::Match(
+            scrutinee,
+            arena_vec![self; err_arm, ok_arm],
+            hir::MatchSource::TryDesugar,
+        )
     }
 
     // =========================================================================
@@ -1191,9 +1231,9 @@ impl LoweringContext<'_, '_> {
     // =========================================================================
 
     /// Constructs a `true` or `false` literal expression.
-    pub(super) fn expr_bool(&mut self, span: Span, val: bool) -> hir::Expr {
+    pub(super) fn expr_bool(&mut self, span: Span, val: bool) -> &'hir hir::Expr<'hir> {
         let lit = Spanned { span, node: LitKind::Bool(val) };
-        self.expr(span, hir::ExprKind::Lit(lit), ThinVec::new())
+        self.arena.alloc(self.expr(span, hir::ExprKind::Lit(lit), ThinVec::new()))
     }
 
     /// Wrap the given `expr` in a terminating scope using `hir::ExprKind::DropTemps`.
@@ -1205,28 +1245,37 @@ impl LoweringContext<'_, '_> {
     pub(super) fn expr_drop_temps(
         &mut self,
         span: Span,
-        expr: P<hir::Expr>,
+        expr: &'hir hir::Expr<'hir>,
+        attrs: AttrVec,
+    ) -> &'hir hir::Expr<'hir> {
+        self.arena.alloc(self.expr_drop_temps_mut(span, expr, attrs))
+    }
+
+    pub(super) fn expr_drop_temps_mut(
+        &mut self,
+        span: Span,
+        expr: &'hir hir::Expr<'hir>,
         attrs: AttrVec,
-    ) -> hir::Expr {
+    ) -> hir::Expr<'hir> {
         self.expr(span, hir::ExprKind::DropTemps(expr), attrs)
     }
 
     fn expr_match(
         &mut self,
         span: Span,
-        arg: P<hir::Expr>,
-        arms: hir::HirVec<hir::Arm>,
+        arg: &'hir hir::Expr<'hir>,
+        arms: &'hir [hir::Arm<'hir>],
         source: hir::MatchSource,
-    ) -> hir::Expr {
+    ) -> hir::Expr<'hir> {
         self.expr(span, hir::ExprKind::Match(arg, arms, source), ThinVec::new())
     }
 
-    fn expr_break(&mut self, span: Span, attrs: AttrVec) -> P<hir::Expr> {
+    fn expr_break(&mut self, span: Span, attrs: AttrVec) -> &'hir hir::Expr<'hir> {
         let expr_break = hir::ExprKind::Break(self.lower_loop_destination(None), None);
-        P(self.expr(span, expr_break, attrs))
+        self.arena.alloc(self.expr(span, expr_break, attrs))
     }
 
-    fn expr_mut_addr_of(&mut self, span: Span, e: P<hir::Expr>) -> hir::Expr {
+    fn expr_mut_addr_of(&mut self, span: Span, e: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> {
         self.expr(
             span,
             hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e),
@@ -1234,21 +1283,17 @@ impl LoweringContext<'_, '_> {
         )
     }
 
-    fn expr_unit(&mut self, sp: Span) -> hir::Expr {
-        self.expr_tuple(sp, hir_vec![])
-    }
-
-    fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<hir::Expr>) -> hir::Expr {
-        self.expr(sp, hir::ExprKind::Tup(exprs), ThinVec::new())
+    fn expr_unit(&mut self, sp: Span) -> &'hir hir::Expr<'hir> {
+        self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), ThinVec::new()))
     }
 
     fn expr_call(
         &mut self,
         span: Span,
-        e: P<hir::Expr>,
-        args: hir::HirVec<hir::Expr>,
-    ) -> hir::Expr {
-        self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new())
+        e: &'hir hir::Expr<'hir>,
+        args: &'hir [hir::Expr<'hir>],
+    ) -> &'hir hir::Expr<'hir> {
+        self.arena.alloc(self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new()))
     }
 
     // Note: associated functions must use `expr_call_std_path`.
@@ -1256,9 +1301,10 @@ impl LoweringContext<'_, '_> {
         &mut self,
         span: Span,
         path_components: &[Symbol],
-        args: hir::HirVec<hir::Expr>,
-    ) -> hir::Expr {
-        let path = P(self.expr_std_path(span, path_components, None, ThinVec::new()));
+        args: &'hir [hir::Expr<'hir>],
+    ) -> &'hir hir::Expr<'hir> {
+        let path =
+            self.arena.alloc(self.expr_std_path(span, path_components, None, ThinVec::new()));
         self.expr_call(span, path, args)
     }
 
@@ -1277,13 +1323,14 @@ impl LoweringContext<'_, '_> {
         span: Span,
         ty_path_components: &[Symbol],
         assoc_fn_name: &str,
-        args: hir::HirVec<hir::Expr>,
-    ) -> hir::ExprKind {
+        args: &'hir [hir::Expr<'hir>],
+    ) -> hir::ExprKind<'hir> {
         let ty_path = P(self.std_path(span, ty_path_components, None, false));
         let ty = P(self.ty_path(ty_path_id, span, hir::QPath::Resolved(None, ty_path)));
         let fn_seg = P(hir::PathSegment::from_ident(Ident::from_str(assoc_fn_name)));
         let fn_path = hir::QPath::TypeRelative(ty, fn_seg);
-        let fn_expr = P(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new()));
+        let fn_expr =
+            self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new()));
         hir::ExprKind::Call(fn_expr, args)
     }
 
@@ -1293,12 +1340,26 @@ impl LoweringContext<'_, '_> {
         components: &[Symbol],
         params: Option<P<hir::GenericArgs>>,
         attrs: AttrVec,
-    ) -> hir::Expr {
+    ) -> hir::Expr<'hir> {
         let path = self.std_path(span, components, params, true);
         self.expr(span, hir::ExprKind::Path(hir::QPath::Resolved(None, P(path))), attrs)
     }
 
-    pub(super) fn expr_ident(&mut self, sp: Span, ident: Ident, binding: hir::HirId) -> hir::Expr {
+    pub(super) fn expr_ident(
+        &mut self,
+        sp: Span,
+        ident: Ident,
+        binding: hir::HirId,
+    ) -> &'hir hir::Expr<'hir> {
+        self.arena.alloc(self.expr_ident_mut(sp, ident, binding))
+    }
+
+    pub(super) fn expr_ident_mut(
+        &mut self,
+        sp: Span,
+        ident: Ident,
+        binding: hir::HirId,
+    ) -> hir::Expr<'hir> {
         self.expr_ident_with_attrs(sp, ident, binding, ThinVec::new())
     }
 
@@ -1308,7 +1369,7 @@ impl LoweringContext<'_, '_> {
         ident: Ident,
         binding: hir::HirId,
         attrs: AttrVec,
-    ) -> hir::Expr {
+    ) -> hir::Expr<'hir> {
         let expr_path = hir::ExprKind::Path(hir::QPath::Resolved(
             None,
             P(hir::Path {
@@ -1321,14 +1382,14 @@ impl LoweringContext<'_, '_> {
         self.expr(span, expr_path, attrs)
     }
 
-    fn expr_unsafe(&mut self, expr: P<hir::Expr>) -> hir::Expr {
+    fn expr_unsafe(&mut self, expr: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> {
         let hir_id = self.next_id();
         let span = expr.span;
         self.expr(
             span,
             hir::ExprKind::Block(
-                P(hir::Block {
-                    stmts: hir_vec![],
+                self.arena.alloc(hir::Block {
+                    stmts: &[],
                     expr: Some(expr),
                     hir_id,
                     rules: hir::UnsafeBlock(hir::CompilerGenerated),
@@ -1341,27 +1402,37 @@ impl LoweringContext<'_, '_> {
         )
     }
 
-    fn expr_block_empty(&mut self, span: Span) -> hir::Expr {
-        let blk = self.block_all(span, hir_vec![], None);
-        self.expr_block(P(blk), ThinVec::new())
+    fn expr_block_empty(&mut self, span: Span) -> &'hir hir::Expr<'hir> {
+        let blk = self.block_all(span, &[], None);
+        let expr = self.expr_block(blk, ThinVec::new());
+        self.arena.alloc(expr)
     }
 
-    pub(super) fn expr_block(&mut self, b: P<hir::Block>, attrs: AttrVec) -> hir::Expr {
+    pub(super) fn expr_block(
+        &mut self,
+        b: &'hir hir::Block<'hir>,
+        attrs: AttrVec,
+    ) -> hir::Expr<'hir> {
         self.expr(b.span, hir::ExprKind::Block(b, None), attrs)
     }
 
-    pub(super) fn expr(&mut self, span: Span, kind: hir::ExprKind, attrs: AttrVec) -> hir::Expr {
+    pub(super) fn expr(
+        &mut self,
+        span: Span,
+        kind: hir::ExprKind<'hir>,
+        attrs: AttrVec,
+    ) -> hir::Expr<'hir> {
         hir::Expr { hir_id: self.next_id(), kind, span, attrs }
     }
 
-    fn field(&mut self, ident: Ident, expr: P<hir::Expr>, span: Span) -> hir::Field {
+    fn field(&mut self, ident: Ident, expr: &'hir hir::Expr<'hir>, span: Span) -> hir::Field<'hir> {
         hir::Field { hir_id: self.next_id(), ident, span, expr, is_shorthand: false }
     }
 
-    fn arm(&mut self, pat: P<hir::Pat>, expr: P<hir::Expr>) -> hir::Arm {
+    fn arm(&mut self, pat: &'hir hir::Pat<'hir>, expr: &'hir hir::Expr<'hir>) -> hir::Arm<'hir> {
         hir::Arm {
             hir_id: self.next_id(),
-            attrs: hir_vec![],
+            attrs: &[],
             pat,
             guard: None,
             span: expr.span,
diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs
index 04ebe3e8a72..0157e89c96b 100644
--- a/src/librustc/hir/lowering/item.rs
+++ b/src/librustc/hir/lowering/item.rs
@@ -797,8 +797,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 (generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Provided(body_id)))
             }
             AssocItemKind::TyAlias(ref bounds, ref default) => {
-                let ty = default.as_ref().map(|x| -> &'hir hir::Ty {
-                    self.arena.alloc(self.lower_ty(x, ImplTraitContext::disallowed()).into_inner())
+                let ty = default.as_ref().map(|x| {
+                    &*self
+                        .arena
+                        .alloc(self.lower_ty(x, ImplTraitContext::disallowed()).into_inner())
                 });
                 let generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed());
                 let kind = hir::TraitItemKind::Type(
@@ -840,7 +842,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     }
 
     /// Construct `ExprKind::Err` for the given `span`.
-    fn expr_err(&mut self, span: Span) -> hir::Expr {
+    fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> {
         self.expr(span, hir::ExprKind::Err, AttrVec::new())
     }
 
@@ -981,7 +983,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
         }
     }
 
-    fn record_body(&mut self, params: &'hir [hir::Param], value: hir::Expr) -> hir::BodyId {
+    fn record_body(
+        &mut self,
+        params: &'hir [hir::Param<'hir>],
+        value: hir::Expr<'hir>,
+    ) -> hir::BodyId {
         let body = hir::Body { generator_kind: self.generator_kind, params, value };
         let id = body.id();
         self.bodies.insert(id, body);
@@ -990,7 +996,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
     fn lower_body(
         &mut self,
-        f: impl FnOnce(&mut Self) -> (&'hir [hir::Param], hir::Expr),
+        f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
     ) -> hir::BodyId {
         let prev_gen_kind = self.generator_kind.take();
         let (parameters, result) = f(self);
@@ -999,9 +1005,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
         body_id
     }
 
-    fn lower_param(&mut self, param: &Param) -> hir::Param {
+    fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
         hir::Param {
-            attrs: self.lower_attrs(&param.attrs),
+            attrs: self.lower_attrs_arena(&param.attrs),
             hir_id: self.lower_node_id(param.id),
             pat: self.lower_pat(&param.pat),
             span: param.span,
@@ -1011,7 +1017,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     pub(super) fn lower_fn_body(
         &mut self,
         decl: &FnDecl,
-        body: impl FnOnce(&mut LoweringContext<'_, '_>) -> hir::Expr,
+        body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
     ) -> hir::BodyId {
         self.lower_body(|this| {
             (
@@ -1030,7 +1036,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         self.lower_fn_body(decl, |this| this.lower_block_expr_opt(span, body))
     }
 
-    fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr {
+    fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> {
         match block {
             Some(block) => self.lower_block_expr(block),
             None => self.expr_err(span),
@@ -1042,7 +1048,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             (
                 &[],
                 match expr {
-                    Some(expr) => this.lower_expr(expr),
+                    Some(expr) => this.lower_expr_mut(expr),
                     None => this.expr_err(span),
                 },
             )
@@ -1062,8 +1068,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
         };
 
         self.lower_body(|this| {
-            let mut parameters: Vec<hir::Param> = Vec::new();
-            let mut statements: Vec<hir::Stmt> = Vec::new();
+            let mut parameters: Vec<hir::Param<'_>> = Vec::new();
+            let mut statements: Vec<hir::Stmt<'_>> = Vec::new();
 
             // Async function parameters are lowered into the closure body so that they are
             // captured and so that the drop order matches the equivalent non-async functions.
@@ -1141,7 +1147,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     let stmt = this.stmt_let_pat(
                         stmt_attrs,
                         desugared_span,
-                        Some(P(expr)),
+                        Some(this.arena.alloc(expr)),
                         parameter.pat,
                         hir::LocalSource::AsyncFn,
                     );
@@ -1171,7 +1177,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     let move_stmt = this.stmt_let_pat(
                         AttrVec::new(),
                         desugared_span,
-                        Some(P(move_expr)),
+                        Some(this.arena.alloc(move_expr)),
                         move_pat,
                         hir::LocalSource::AsyncFn,
                     );
@@ -1182,7 +1188,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     let pattern_stmt = this.stmt_let_pat(
                         stmt_attrs,
                         desugared_span,
-                        Some(P(pattern_expr)),
+                        Some(this.arena.alloc(pattern_expr)),
                         parameter.pat,
                         hir::LocalSource::AsyncFn,
                     );
@@ -1208,8 +1214,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     // Transform into `drop-temps { <user-body> }`, an expression:
                     let desugared_span =
                         this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);
-                    let user_body =
-                        this.expr_drop_temps(desugared_span, P(user_body), AttrVec::new());
+                    let user_body = this.expr_drop_temps(
+                        desugared_span,
+                        this.arena.alloc(user_body),
+                        AttrVec::new(),
+                    );
 
                     // As noted above, create the final block like
                     //
@@ -1220,9 +1229,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     //   drop-temps { <user-body> }
                     // }
                     // ```
-                    let body =
-                        this.block_all(desugared_span, statements.into(), Some(P(user_body)));
-                    this.expr_block(P(body), AttrVec::new())
+                    let body = this.block_all(
+                        desugared_span,
+                        this.arena.alloc_from_iter(statements),
+                        Some(user_body),
+                    );
+
+                    this.expr_block(body, AttrVec::new())
                 },
             );
 
diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs
index 880e6d6dcf4..7701c33f916 100644
--- a/src/librustc/hir/map/blocks.rs
+++ b/src/librustc/hir/map/blocks.rs
@@ -66,7 +66,7 @@ impl MaybeFnLike for ast::TraitItem<'_> {
     }
 }
 
-impl MaybeFnLike for ast::Expr {
+impl MaybeFnLike for ast::Expr<'_> {
     fn is_fn_like(&self) -> bool {
         match self.kind {
             ast::ExprKind::Closure(..) => true,
@@ -81,7 +81,7 @@ impl MaybeFnLike for ast::Expr {
 #[derive(Copy, Clone)]
 pub enum Code<'a> {
     FnLike(FnLikeNode<'a>),
-    Expr(&'a Expr),
+    Expr(&'a Expr<'a>),
 }
 
 impl<'a> Code<'a> {
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index feab7cdac1e..610be0a0753 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -365,7 +365,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         self.currently_in_body = prev_in_body;
     }
 
-    fn visit_param(&mut self, param: &'hir Param) {
+    fn visit_param(&mut self, param: &'hir Param<'hir>) {
         let node = Node::Param(param);
         self.insert(param.pat.span, param.hir_id, node);
         self.with_parent(param.hir_id, |this| {
@@ -434,7 +434,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         });
     }
 
-    fn visit_pat(&mut self, pat: &'hir Pat) {
+    fn visit_pat(&mut self, pat: &'hir Pat<'hir>) {
         let node =
             if let PatKind::Binding(..) = pat.kind { Node::Binding(pat) } else { Node::Pat(pat) };
         self.insert(pat.span, pat.hir_id, node);
@@ -444,7 +444,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         });
     }
 
-    fn visit_arm(&mut self, arm: &'hir Arm) {
+    fn visit_arm(&mut self, arm: &'hir Arm<'hir>) {
         let node = Node::Arm(arm);
 
         self.insert(arm.span, arm.hir_id, node);
@@ -462,7 +462,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         });
     }
 
-    fn visit_expr(&mut self, expr: &'hir Expr) {
+    fn visit_expr(&mut self, expr: &'hir Expr<'hir>) {
         self.insert(expr.span, expr.hir_id, Node::Expr(expr));
 
         self.with_parent(expr.hir_id, |this| {
@@ -470,7 +470,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         });
     }
 
-    fn visit_stmt(&mut self, stmt: &'hir Stmt) {
+    fn visit_stmt(&mut self, stmt: &'hir Stmt<'hir>) {
         self.insert(stmt.span, stmt.hir_id, Node::Stmt(stmt));
 
         self.with_parent(stmt.hir_id, |this| {
@@ -513,14 +513,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         intravisit::walk_fn(self, fk, fd, b, s, id);
     }
 
-    fn visit_block(&mut self, block: &'hir Block) {
+    fn visit_block(&mut self, block: &'hir Block<'hir>) {
         self.insert(block.span, block.hir_id, Node::Block(block));
         self.with_parent(block.hir_id, |this| {
             intravisit::walk_block(this, block);
         });
     }
 
-    fn visit_local(&mut self, l: &'hir Local) {
+    fn visit_local(&mut self, l: &'hir Local<'hir>) {
         self.insert(l.span, l.hir_id, Node::Local(l));
         self.with_parent(l.hir_id, |this| intravisit::walk_local(this, l))
     }
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index f3be7e32cea..cc5cb58173f 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -180,19 +180,19 @@ pub struct Map<'hir> {
     hir_to_node_id: FxHashMap<HirId, NodeId>,
 }
 
-struct ParentHirIterator<'map> {
+struct ParentHirIterator<'map, 'hir> {
     current_id: HirId,
-    map: &'map Map<'map>,
+    map: &'map Map<'hir>,
 }
 
-impl<'map> ParentHirIterator<'map> {
-    fn new(current_id: HirId, map: &'map Map<'map>) -> ParentHirIterator<'map> {
+impl<'map, 'hir> ParentHirIterator<'map, 'hir> {
+    fn new(current_id: HirId, map: &'map Map<'hir>) -> ParentHirIterator<'map, 'hir> {
         ParentHirIterator { current_id, map }
     }
 }
 
-impl<'map> Iterator for ParentHirIterator<'map> {
-    type Item = (HirId, Node<'map>);
+impl<'map, 'hir> Iterator for ParentHirIterator<'map, 'hir> {
+    type Item = (HirId, Node<'hir>);
 
     fn next(&mut self) -> Option<Self::Item> {
         if self.current_id == CRATE_HIR_ID {
@@ -782,7 +782,7 @@ impl<'hir> Map<'hir> {
     ///
     /// Used by error reporting when there's a type error in a match arm caused by the `match`
     /// expression needing to be unit.
-    pub fn get_match_if_cause(&self, hir_id: HirId) -> Option<&Expr> {
+    pub fn get_match_if_cause(&self, hir_id: HirId) -> Option<&'hir Expr<'hir>> {
         for (_, node) in ParentHirIterator::new(hir_id, &self) {
             match node {
                 Node::Item(_) | Node::ForeignItem(_) | Node::TraitItem(_) | Node::ImplItem(_) => {
@@ -925,7 +925,7 @@ impl<'hir> Map<'hir> {
         }
     }
 
-    pub fn expect_expr(&self, id: HirId) -> &'hir Expr {
+    pub fn expect_expr(&self, id: HirId) -> &'hir Expr<'hir> {
         match self.find(id) {
             // read recorded by find
             Some(Node::Expr(expr)) => expr,
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index e955b7058e3..8a450cf167a 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -832,12 +832,12 @@ pub struct MacroDef<'hir> {
 /// `targeted_by_break` field will be `true`) and may be `unsafe` by means of
 /// the `rules` being anything but `DefaultBlock`.
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub struct Block {
+pub struct Block<'hir> {
     /// Statements in a block.
-    pub stmts: HirVec<Stmt>,
+    pub stmts: &'hir [Stmt<'hir>],
     /// An expression at the end of the block
     /// without a semicolon, if any.
-    pub expr: Option<P<Expr>>,
+    pub expr: Option<&'hir Expr<'hir>>,
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
     /// Distinguishes between `unsafe { ... }` and `{ ... }`.
@@ -850,14 +850,14 @@ pub struct Block {
 }
 
 #[derive(RustcEncodable, RustcDecodable, HashStable)]
-pub struct Pat {
+pub struct Pat<'hir> {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
-    pub kind: PatKind,
+    pub kind: PatKind<'hir>,
     pub span: Span,
 }
 
-impl fmt::Debug for Pat {
+impl fmt::Debug for Pat<'_> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(
             f,
@@ -868,9 +868,9 @@ impl fmt::Debug for Pat {
     }
 }
 
-impl Pat {
+impl Pat<'_> {
     // FIXME(#19596) this is a workaround, but there should be a better way
-    fn walk_short_(&self, it: &mut impl FnMut(&Pat) -> bool) -> bool {
+    fn walk_short_(&self, it: &mut impl FnMut(&Pat<'_>) -> bool) -> bool {
         if !it(self) {
             return false;
         }
@@ -893,12 +893,12 @@ impl Pat {
     /// Note that when visiting e.g. `Tuple(ps)`,
     /// if visiting `ps[0]` returns `false`,
     /// then `ps[1]` will not be visited.
-    pub fn walk_short(&self, mut it: impl FnMut(&Pat) -> bool) -> bool {
+    pub fn walk_short(&self, mut it: impl FnMut(&Pat<'_>) -> bool) -> bool {
         self.walk_short_(&mut it)
     }
 
     // FIXME(#19596) this is a workaround, but there should be a better way
-    fn walk_(&self, it: &mut impl FnMut(&Pat) -> bool) {
+    fn walk_(&self, it: &mut impl FnMut(&Pat<'_>) -> bool) {
         if !it(self) {
             return;
         }
@@ -918,14 +918,14 @@ impl Pat {
     /// Walk the pattern in left-to-right order.
     ///
     /// If `it(pat)` returns `false`, the children are not visited.
-    pub fn walk(&self, mut it: impl FnMut(&Pat) -> bool) {
+    pub fn walk(&self, mut it: impl FnMut(&Pat<'_>) -> bool) {
         self.walk_(&mut it)
     }
 
     /// Walk the pattern in left-to-right order.
     ///
     /// If you always want to recurse, prefer this method over `walk`.
-    pub fn walk_always(&self, mut it: impl FnMut(&Pat)) {
+    pub fn walk_always(&self, mut it: impl FnMut(&Pat<'_>)) {
         self.walk(|p| {
             it(p);
             true
@@ -939,14 +939,14 @@ impl Pat {
 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
 /// except `is_shorthand` is true.
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub struct FieldPat {
+pub struct FieldPat<'hir> {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
     /// The identifier for the field.
     #[stable_hasher(project(name))]
     pub ident: Ident,
     /// The pattern the field is destructured to.
-    pub pat: P<Pat>,
+    pub pat: &'hir Pat<'hir>,
     pub is_shorthand: bool,
     pub span: Span,
 }
@@ -991,7 +991,7 @@ impl fmt::Display for RangeEnd {
 }
 
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub enum PatKind {
+pub enum PatKind<'hir> {
     /// Represents a wildcard pattern (i.e., `_`).
     Wild,
 
@@ -999,20 +999,20 @@ pub enum PatKind {
     /// The `HirId` is the canonical ID for the variable being bound,
     /// (e.g., in `Ok(x) | Err(x)`, both `x` use the same canonical ID),
     /// which is the pattern ID of the first `x`.
-    Binding(BindingAnnotation, HirId, Ident, Option<P<Pat>>),
+    Binding(BindingAnnotation, HirId, Ident, Option<&'hir Pat<'hir>>),
 
     /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
     /// The `bool` is `true` in the presence of a `..`.
-    Struct(QPath, HirVec<FieldPat>, bool),
+    Struct(QPath, &'hir [FieldPat<'hir>], bool),
 
     /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
     /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
     /// `0 <= position <= subpats.len()`
-    TupleStruct(QPath, HirVec<P<Pat>>, Option<usize>),
+    TupleStruct(QPath, &'hir [&'hir Pat<'hir>], Option<usize>),
 
     /// An or-pattern `A | B | C`.
     /// Invariant: `pats.len() >= 2`.
-    Or(HirVec<P<Pat>>),
+    Or(&'hir [&'hir Pat<'hir>]),
 
     /// A path pattern for an unit struct/variant or a (maybe-associated) constant.
     Path(QPath),
@@ -1020,19 +1020,19 @@ pub enum PatKind {
     /// A tuple pattern (e.g., `(a, b)`).
     /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
     /// `0 <= position <= subpats.len()`
-    Tuple(HirVec<P<Pat>>, Option<usize>),
+    Tuple(&'hir [&'hir Pat<'hir>], Option<usize>),
 
     /// A `box` pattern.
-    Box(P<Pat>),
+    Box(&'hir Pat<'hir>),
 
     /// A reference pattern (e.g., `&mut (a, b)`).
-    Ref(P<Pat>, Mutability),
+    Ref(&'hir Pat<'hir>, Mutability),
 
     /// A literal.
-    Lit(P<Expr>),
+    Lit(&'hir Expr<'hir>),
 
     /// A range pattern (e.g., `1..=2` or `1..2`).
-    Range(P<Expr>, P<Expr>, RangeEnd),
+    Range(&'hir Expr<'hir>, &'hir Expr<'hir>, RangeEnd),
 
     /// A slice pattern, `[before_0, ..., before_n, (slice, after_0, ..., after_n)?]`.
     ///
@@ -1043,7 +1043,7 @@ pub enum PatKind {
     /// ```
     /// PatKind::Slice([Binding(a), Binding(b)], Some(Wild), [Binding(c), Binding(d)])
     /// ```
-    Slice(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>),
+    Slice(&'hir [&'hir Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [&'hir Pat<'hir>]),
 }
 
 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
@@ -1210,13 +1210,13 @@ impl UnOp {
 
 /// A statement.
 #[derive(RustcEncodable, RustcDecodable, HashStable)]
-pub struct Stmt {
+pub struct Stmt<'hir> {
     pub hir_id: HirId,
-    pub kind: StmtKind,
+    pub kind: StmtKind<'hir>,
     pub span: Span,
 }
 
-impl fmt::Debug for Stmt {
+impl fmt::Debug for Stmt<'_> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(
             f,
@@ -1229,22 +1229,22 @@ impl fmt::Debug for Stmt {
 
 /// The contents of a statement.
 #[derive(RustcEncodable, RustcDecodable, HashStable)]
-pub enum StmtKind {
+pub enum StmtKind<'hir> {
     /// A local (`let`) binding.
-    Local(P<Local>),
+    Local(&'hir Local<'hir>),
 
     /// An item binding.
     Item(ItemId),
 
     /// An expression without a trailing semi-colon (must have unit type).
-    Expr(P<Expr>),
+    Expr(&'hir Expr<'hir>),
 
     /// An expression with a trailing semi-colon (may have any type).
-    Semi(P<Expr>),
+    Semi(&'hir Expr<'hir>),
 }
 
-impl StmtKind {
-    pub fn attrs(&self) -> &[Attribute] {
+impl StmtKind<'hir> {
+    pub fn attrs(&self) -> &'hir [Attribute] {
         match *self {
             StmtKind::Local(ref l) => &l.attrs,
             StmtKind::Item(_) => &[],
@@ -1255,12 +1255,12 @@ impl StmtKind {
 
 /// Represents a `let` statement (i.e., `let <pat>:<ty> = <expr>;`).
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub struct Local {
-    pub pat: P<Pat>,
+pub struct Local<'hir> {
+    pub pat: &'hir Pat<'hir>,
     /// Type annotation, if any (otherwise the type will be inferred).
-    pub ty: Option<P<Ty>>,
+    pub ty: Option<&'hir Ty>,
     /// Initializer expression to set the value, if any.
-    pub init: Option<P<Expr>>,
+    pub init: Option<&'hir Expr<'hir>>,
     pub hir_id: HirId,
     pub span: Span,
     pub attrs: AttrVec,
@@ -1272,30 +1272,30 @@ pub struct Local {
 /// Represents a single arm of a `match` expression, e.g.
 /// `<pat> (if <guard>) => <body>`.
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub struct Arm {
+pub struct Arm<'hir> {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
     pub span: Span,
-    pub attrs: HirVec<Attribute>,
+    pub attrs: &'hir [Attribute],
     /// If this pattern and the optional guard matches, then `body` is evaluated.
-    pub pat: P<Pat>,
+    pub pat: &'hir Pat<'hir>,
     /// Optional guard clause.
-    pub guard: Option<Guard>,
+    pub guard: Option<Guard<'hir>>,
     /// The expression the arm evaluates to if this arm matches.
-    pub body: P<Expr>,
+    pub body: &'hir Expr<'hir>,
 }
 
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub enum Guard {
-    If(P<Expr>),
+pub enum Guard<'hir> {
+    If(&'hir Expr<'hir>),
 }
 
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub struct Field {
+pub struct Field<'hir> {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
     pub ident: Ident,
-    pub expr: P<Expr>,
+    pub expr: &'hir Expr<'hir>,
     pub span: Span,
     pub is_shorthand: bool,
 }
@@ -1342,8 +1342,8 @@ pub struct BodyId {
 /// map using `body_owner_def_id()`.
 #[derive(RustcEncodable, RustcDecodable, Debug)]
 pub struct Body<'hir> {
-    pub params: &'hir [Param],
-    pub value: Expr,
+    pub params: &'hir [Param<'hir>],
+    pub value: Expr<'hir>,
     pub generator_kind: Option<GeneratorKind>,
 }
 
@@ -1443,18 +1443,18 @@ pub struct AnonConst {
 
 /// An expression.
 #[derive(RustcEncodable, RustcDecodable)]
-pub struct Expr {
+pub struct Expr<'hir> {
     pub hir_id: HirId,
-    pub kind: ExprKind,
+    pub kind: ExprKind<'hir>,
     pub attrs: AttrVec,
     pub span: Span,
 }
 
 // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(Expr, 64);
+static_assert_size!(Expr<'static>, 64);
 
-impl Expr {
+impl Expr<'_> {
     pub fn precedence(&self) -> ExprPrecedence {
         match self.kind {
             ExprKind::Box(_) => ExprPrecedence::Box,
@@ -1563,7 +1563,7 @@ impl Expr {
     }
 }
 
-impl fmt::Debug for Expr {
+impl fmt::Debug for Expr<'_> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(
             f,
@@ -1579,7 +1579,7 @@ impl fmt::Debug for Expr {
 ///
 /// FIXME(#60607): This function is a hack. If and when we have `QPath::Lang(...)`,
 /// we can use that instead as simpler, more reliable mechanism, as opposed to using `SourceMap`.
-pub fn is_range_literal(sm: &SourceMap, expr: &Expr) -> bool {
+pub fn is_range_literal(sm: &SourceMap, expr: &Expr<'_>) -> bool {
     // Returns whether the given path represents a (desugared) range,
     // either in std or core, i.e. has either a `::std::ops::Range` or
     // `::core::ops::Range` prefix.
@@ -1637,18 +1637,18 @@ pub fn is_range_literal(sm: &SourceMap, expr: &Expr) -> bool {
 }
 
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub enum ExprKind {
+pub enum ExprKind<'hir> {
     /// A `box x` expression.
-    Box(P<Expr>),
+    Box(&'hir Expr<'hir>),
     /// An array (e.g., `[a, b, c, d]`).
-    Array(HirVec<Expr>),
+    Array(&'hir [Expr<'hir>]),
     /// A function call.
     ///
     /// The first field resolves to the function itself (usually an `ExprKind::Path`),
     /// and the second field is the list of arguments.
     /// This also represents calling the constructor of
     /// tuple-like ADTs such as tuple structs and enum variants.
-    Call(P<Expr>, HirVec<Expr>),
+    Call(&'hir Expr<'hir>, &'hir [Expr<'hir>]),
     /// A method call (e.g., `x.foo::<'static, Bar, Baz>(a, b, c, d)`).
     ///
     /// The `PathSegment`/`Span` represent the method name and its generic arguments
@@ -1663,83 +1663,82 @@ pub enum ExprKind {
     /// the `hir_id` of the `MethodCall` node itself.
     ///
     /// [`type_dependent_def_id`]: ../ty/struct.TypeckTables.html#method.type_dependent_def_id
-    MethodCall(P<PathSegment>, Span, HirVec<Expr>),
+    MethodCall(&'hir PathSegment, Span, &'hir [Expr<'hir>]),
     /// A tuple (e.g., `(a, b, c, d)`).
-    Tup(HirVec<Expr>),
+    Tup(&'hir [Expr<'hir>]),
     /// A binary operation (e.g., `a + b`, `a * b`).
-    Binary(BinOp, P<Expr>, P<Expr>),
+    Binary(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
     /// A unary operation (e.g., `!x`, `*x`).
-    Unary(UnOp, P<Expr>),
+    Unary(UnOp, &'hir Expr<'hir>),
     /// A literal (e.g., `1`, `"foo"`).
     Lit(Lit),
     /// A cast (e.g., `foo as f64`).
-    Cast(P<Expr>, P<Ty>),
+    Cast(&'hir Expr<'hir>, &'hir Ty),
     /// A type reference (e.g., `Foo`).
-    Type(P<Expr>, P<Ty>),
+    Type(&'hir Expr<'hir>, &'hir Ty),
     /// Wraps the expression in a terminating scope.
     /// This makes it semantically equivalent to `{ let _t = expr; _t }`.
     ///
     /// This construct only exists to tweak the drop order in HIR lowering.
     /// An example of that is the desugaring of `for` loops.
-    DropTemps(P<Expr>),
+    DropTemps(&'hir Expr<'hir>),
     /// A conditionless loop (can be exited with `break`, `continue`, or `return`).
     ///
     /// I.e., `'label: loop { <block> }`.
-    Loop(P<Block>, Option<Label>, LoopSource),
+    Loop(&'hir Block<'hir>, Option<Label>, LoopSource),
     /// A `match` block, with a source that indicates whether or not it is
     /// the result of a desugaring, and if so, which kind.
-    Match(P<Expr>, HirVec<Arm>, MatchSource),
+    Match(&'hir Expr<'hir>, &'hir [Arm<'hir>], MatchSource),
     /// A closure (e.g., `move |a, b, c| {a + b + c}`).
     ///
     /// The `Span` is the argument block `|...|`.
     ///
     /// This may also be a generator literal or an `async block` as indicated by the
     /// `Option<Movability>`.
-    Closure(CaptureBy, P<FnDecl>, BodyId, Span, Option<Movability>),
+    Closure(CaptureBy, &'hir FnDecl, BodyId, Span, Option<Movability>),
     /// A block (e.g., `'label: { ... }`).
-    Block(P<Block>, Option<Label>),
+    Block(&'hir Block<'hir>, Option<Label>),
 
     /// An assignment (e.g., `a = foo()`).
-    /// The `Span` argument is the span of the `=` token.
-    Assign(P<Expr>, P<Expr>, Span),
+    Assign(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
     /// An assignment with an operator.
     ///
     /// E.g., `a += 1`.
-    AssignOp(BinOp, P<Expr>, P<Expr>),
+    AssignOp(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
     /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct or tuple field.
-    Field(P<Expr>, Ident),
+    Field(&'hir Expr<'hir>, Ident),
     /// An indexing operation (`foo[2]`).
-    Index(P<Expr>, P<Expr>),
+    Index(&'hir Expr<'hir>, &'hir Expr<'hir>),
 
     /// Path to a definition, possibly containing lifetime or type parameters.
     Path(QPath),
 
-    /// A referencing operation (i.e., `&a`, `&mut a`, `&raw const a`, or `&raw mut a`).
-    AddrOf(BorrowKind, Mutability, P<Expr>),
+    /// A referencing operation (i.e., `&a` or `&mut a`).
+    AddrOf(BorrowKind, Mutability, &'hir Expr<'hir>),
     /// A `break`, with an optional label to break.
-    Break(Destination, Option<P<Expr>>),
+    Break(Destination, Option<&'hir Expr<'hir>>),
     /// A `continue`, with an optional label.
     Continue(Destination),
     /// A `return`, with an optional value to be returned.
-    Ret(Option<P<Expr>>),
+    Ret(Option<&'hir Expr<'hir>>),
 
     /// Inline assembly (from `asm!`), with its outputs and inputs.
-    InlineAsm(P<InlineAsm>),
+    InlineAsm(&'hir InlineAsm<'hir>),
 
     /// A struct or struct-like variant literal expression.
     ///
     /// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. base}`,
     /// where `base` is the `Option<Expr>`.
-    Struct(P<QPath>, HirVec<Field>, Option<P<Expr>>),
+    Struct(&'hir QPath, &'hir [Field<'hir>], Option<&'hir Expr<'hir>>),
 
     /// An array literal constructed from one repeated element.
     ///
     /// E.g., `[1; 5]`. The first expression is the element
     /// to be repeated; the second is the number of times to repeat it.
-    Repeat(P<Expr>, AnonConst),
+    Repeat(&'hir Expr<'hir>, AnonConst),
 
     /// A suspension point for generators (i.e., `yield <expr>`).
-    Yield(P<Expr>, YieldSource),
+    Yield(&'hir Expr<'hir>, YieldSource),
 
     /// A placeholder for an expression that wasn't syntactically well formed in some way.
     Err,
@@ -2159,18 +2158,18 @@ pub struct InlineAsmInner {
 }
 
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub struct InlineAsm {
+pub struct InlineAsm<'hir> {
     pub inner: InlineAsmInner,
-    pub outputs_exprs: HirVec<Expr>,
-    pub inputs_exprs: HirVec<Expr>,
+    pub outputs_exprs: &'hir [Expr<'hir>],
+    pub inputs_exprs: &'hir [Expr<'hir>],
 }
 
 /// Represents a parameter in a function header.
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub struct Param {
-    pub attrs: HirVec<Attribute>,
+pub struct Param<'hir> {
+    pub attrs: &'hir [Attribute],
     pub hir_id: HirId,
-    pub pat: P<Pat>,
+    pub pat: &'hir Pat<'hir>,
     pub span: Span,
 }
 
@@ -2828,7 +2827,7 @@ impl CodegenFnAttrs {
 
 #[derive(Copy, Clone, Debug)]
 pub enum Node<'hir> {
-    Param(&'hir Param),
+    Param(&'hir Param<'hir>),
     Item(&'hir Item<'hir>),
     ForeignItem(&'hir ForeignItem<'hir>),
     TraitItem(&'hir TraitItem<'hir>),
@@ -2836,16 +2835,16 @@ pub enum Node<'hir> {
     Variant(&'hir Variant<'hir>),
     Field(&'hir StructField<'hir>),
     AnonConst(&'hir AnonConst),
-    Expr(&'hir Expr),
-    Stmt(&'hir Stmt),
+    Expr(&'hir Expr<'hir>),
+    Stmt(&'hir Stmt<'hir>),
     PathSegment(&'hir PathSegment),
     Ty(&'hir Ty),
     TraitRef(&'hir TraitRef),
-    Binding(&'hir Pat),
-    Pat(&'hir Pat),
-    Arm(&'hir Arm),
-    Block(&'hir Block),
-    Local(&'hir Local),
+    Binding(&'hir Pat<'hir>),
+    Pat(&'hir Pat<'hir>),
+    Arm(&'hir Arm<'hir>),
+    Block(&'hir Block<'hir>),
+    Local(&'hir Local<'hir>),
     MacroDef(&'hir MacroDef<'hir>),
 
     /// `Ctor` refers to the constructor of an enum variant or struct. Only tuple or unit variants
diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs
index 8d3b464a8ff..0831f5403db 100644
--- a/src/librustc/hir/pat_util.rs
+++ b/src/librustc/hir/pat_util.rs
@@ -57,7 +57,7 @@ impl<T: ExactSizeIterator> EnumerateAndAdjustIterator for T {
     }
 }
 
-impl hir::Pat {
+impl hir::Pat<'_> {
     pub fn is_refutable(&self) -> bool {
         match self.kind {
             PatKind::Lit(_)
@@ -126,7 +126,7 @@ impl hir::Pat {
     }
 
     /// Checks if the pattern satisfies the given predicate on some sub-pattern.
-    fn satisfies(&self, pred: impl Fn(&Self) -> bool) -> bool {
+    fn satisfies(&self, pred: impl Fn(&hir::Pat<'_>) -> bool) -> bool {
         let mut satisfies = false;
         self.walk_short(|p| {
             if pred(p) {
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 2f3b6f82ee5..11a596a8317 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -10,7 +10,6 @@ use syntax::util::parser::{self, AssocOp, Fixity};
 use syntax_pos::{self, BytePos, FileName};
 
 use crate::hir;
-use crate::hir::ptr::P;
 use crate::hir::{GenericArg, GenericParam, GenericParamKind};
 use crate::hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier};
 
@@ -20,12 +19,12 @@ use std::vec;
 
 pub enum AnnNode<'a> {
     Name(&'a ast::Name),
-    Block(&'a hir::Block),
+    Block(&'a hir::Block<'a>),
     Item(&'a hir::Item<'a>),
     SubItem(hir::HirId),
-    Expr(&'a hir::Expr),
-    Pat(&'a hir::Pat),
-    Arm(&'a hir::Arm),
+    Expr(&'a hir::Expr<'a>),
+    Pat(&'a hir::Pat<'a>),
+    Arm(&'a hir::Arm<'a>),
 }
 
 pub enum Nested {
@@ -242,7 +241,7 @@ impl<'a> State<'a> {
         self.end();
     }
 
-    pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[hir::Expr]) {
+    pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[hir::Expr<'_>]) {
         self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&e), |e| e.span)
     }
 
@@ -902,7 +901,7 @@ impl<'a> State<'a> {
         self.ann.post(self, AnnNode::SubItem(ii.hir_id))
     }
 
-    pub fn print_local(&mut self, init: Option<&hir::Expr>, decl: impl Fn(&mut Self)) {
+    pub fn print_local(&mut self, init: Option<&hir::Expr<'_>>, decl: impl Fn(&mut Self)) {
         self.space_if_not_bol();
         self.ibox(INDENT_UNIT);
         self.word_nbsp("let");
@@ -919,7 +918,7 @@ impl<'a> State<'a> {
         self.end()
     }
 
-    pub fn print_stmt(&mut self, st: &hir::Stmt) {
+    pub fn print_stmt(&mut self, st: &hir::Stmt<'_>) {
         self.maybe_print_comment(st.span.lo());
         match st.kind {
             hir::StmtKind::Local(ref loc) => {
@@ -942,21 +941,21 @@ impl<'a> State<'a> {
         self.maybe_print_trailing_comment(st.span, None)
     }
 
-    pub fn print_block(&mut self, blk: &hir::Block) {
+    pub fn print_block(&mut self, blk: &hir::Block<'_>) {
         self.print_block_with_attrs(blk, &[])
     }
 
-    pub fn print_block_unclosed(&mut self, blk: &hir::Block) {
+    pub fn print_block_unclosed(&mut self, blk: &hir::Block<'_>) {
         self.print_block_maybe_unclosed(blk, &[], false)
     }
 
-    pub fn print_block_with_attrs(&mut self, blk: &hir::Block, attrs: &[ast::Attribute]) {
+    pub fn print_block_with_attrs(&mut self, blk: &hir::Block<'_>, attrs: &[ast::Attribute]) {
         self.print_block_maybe_unclosed(blk, attrs, true)
     }
 
     pub fn print_block_maybe_unclosed(
         &mut self,
-        blk: &hir::Block,
+        blk: &hir::Block<'_>,
         attrs: &[ast::Attribute],
         close_box: bool,
     ) {
@@ -972,7 +971,7 @@ impl<'a> State<'a> {
 
         self.print_inner_attributes(attrs);
 
-        for st in &blk.stmts {
+        for st in blk.stmts {
             self.print_stmt(st);
         }
         if let Some(ref expr) = blk.expr {
@@ -988,13 +987,13 @@ impl<'a> State<'a> {
         self.ann.nested(self, Nested::Body(constant.body))
     }
 
-    fn print_call_post(&mut self, args: &[hir::Expr]) {
+    fn print_call_post(&mut self, args: &[hir::Expr<'_>]) {
         self.popen();
         self.commasep_exprs(Inconsistent, args);
         self.pclose()
     }
 
-    pub fn print_expr_maybe_paren(&mut self, expr: &hir::Expr, prec: i8) {
+    pub fn print_expr_maybe_paren(&mut self, expr: &hir::Expr<'_>, prec: i8) {
         let needs_par = expr.precedence().order() < prec;
         if needs_par {
             self.popen();
@@ -1007,7 +1006,7 @@ impl<'a> State<'a> {
 
     /// Print an expr using syntax that's acceptable in a condition position, such as the `cond` in
     /// `if cond { ... }`.
-    pub fn print_expr_as_cond(&mut self, expr: &hir::Expr) {
+    pub fn print_expr_as_cond(&mut self, expr: &hir::Expr<'_>) {
         let needs_par = match expr.kind {
             // These cases need parens due to the parse error observed in #26461: `if return {}`
             // parses as the erroneous construct `if (return {})`, not `if (return) {}`.
@@ -1025,7 +1024,7 @@ impl<'a> State<'a> {
         }
     }
 
-    fn print_expr_vec(&mut self, exprs: &[hir::Expr]) {
+    fn print_expr_vec(&mut self, exprs: &[hir::Expr<'_>]) {
         self.ibox(INDENT_UNIT);
         self.s.word("[");
         self.commasep_exprs(Inconsistent, exprs);
@@ -1033,7 +1032,7 @@ impl<'a> State<'a> {
         self.end()
     }
 
-    fn print_expr_repeat(&mut self, element: &hir::Expr, count: &hir::AnonConst) {
+    fn print_expr_repeat(&mut self, element: &hir::Expr<'_>, count: &hir::AnonConst) {
         self.ibox(INDENT_UNIT);
         self.s.word("[");
         self.print_expr(element);
@@ -1046,8 +1045,8 @@ impl<'a> State<'a> {
     fn print_expr_struct(
         &mut self,
         qpath: &hir::QPath,
-        fields: &[hir::Field],
-        wth: &Option<P<hir::Expr>>,
+        fields: &[hir::Field<'_>],
+        wth: &Option<&'hir hir::Expr<'_>>,
     ) {
         self.print_qpath(qpath, true);
         self.s.word("{");
@@ -1085,7 +1084,7 @@ impl<'a> State<'a> {
         self.s.word("}");
     }
 
-    fn print_expr_tup(&mut self, exprs: &[hir::Expr]) {
+    fn print_expr_tup(&mut self, exprs: &[hir::Expr<'_>]) {
         self.popen();
         self.commasep_exprs(Inconsistent, exprs);
         if exprs.len() == 1 {
@@ -1094,7 +1093,7 @@ impl<'a> State<'a> {
         self.pclose()
     }
 
-    fn print_expr_call(&mut self, func: &hir::Expr, args: &[hir::Expr]) {
+    fn print_expr_call(&mut self, func: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
         let prec = match func.kind {
             hir::ExprKind::Field(..) => parser::PREC_FORCE_PAREN,
             _ => parser::PREC_POSTFIX,
@@ -1104,7 +1103,7 @@ impl<'a> State<'a> {
         self.print_call_post(args)
     }
 
-    fn print_expr_method_call(&mut self, segment: &hir::PathSegment, args: &[hir::Expr]) {
+    fn print_expr_method_call(&mut self, segment: &hir::PathSegment, args: &[hir::Expr<'_>]) {
         let base_args = &args[1..];
         self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX);
         self.s.word(".");
@@ -1118,7 +1117,7 @@ impl<'a> State<'a> {
         self.print_call_post(base_args)
     }
 
-    fn print_expr_binary(&mut self, op: hir::BinOp, lhs: &hir::Expr, rhs: &hir::Expr) {
+    fn print_expr_binary(&mut self, op: hir::BinOp, lhs: &hir::Expr<'_>, rhs: &hir::Expr<'_>) {
         let assoc_op = bin_op_to_assoc_op(op.node);
         let prec = assoc_op.precedence() as i8;
         let fixity = assoc_op.fixity();
@@ -1144,7 +1143,7 @@ impl<'a> State<'a> {
         self.print_expr_maybe_paren(rhs, right_prec)
     }
 
-    fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr) {
+    fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr<'_>) {
         self.s.word(op.as_str());
         self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
     }
@@ -1153,7 +1152,7 @@ impl<'a> State<'a> {
         &mut self,
         kind: hir::BorrowKind,
         mutability: hir::Mutability,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
     ) {
         self.s.word("&");
         match kind {
@@ -1171,7 +1170,7 @@ impl<'a> State<'a> {
         self.word(lit.node.to_lit_token().to_string())
     }
 
-    pub fn print_expr(&mut self, expr: &hir::Expr) {
+    pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
         self.maybe_print_comment(expr.span.lo());
         self.print_outer_attributes(&expr.attrs);
         self.ibox(INDENT_UNIT);
@@ -1187,8 +1186,8 @@ impl<'a> State<'a> {
             hir::ExprKind::Repeat(ref element, ref count) => {
                 self.print_expr_repeat(&element, count);
             }
-            hir::ExprKind::Struct(ref qpath, ref fields, ref wth) => {
-                self.print_expr_struct(qpath, &fields[..], wth);
+            hir::ExprKind::Struct(ref qpath, fields, ref wth) => {
+                self.print_expr_struct(qpath, fields, wth);
             }
             hir::ExprKind::Tup(ref exprs) => {
                 self.print_expr_tup(exprs);
@@ -1251,7 +1250,7 @@ impl<'a> State<'a> {
                 self.s.space();
                 self.print_block(&blk);
             }
-            hir::ExprKind::Match(ref expr, ref arms, _) => {
+            hir::ExprKind::Match(ref expr, arms, _) => {
                 self.cbox(INDENT_UNIT);
                 self.ibox(INDENT_UNIT);
                 self.word_nbsp("match");
@@ -1418,7 +1417,7 @@ impl<'a> State<'a> {
         self.end()
     }
 
-    pub fn print_local_decl(&mut self, loc: &hir::Local) {
+    pub fn print_local_decl(&mut self, loc: &hir::Local<'_>) {
         self.print_pat(&loc.pat);
         if let Some(ref ty) = loc.ty {
             self.word_space(":");
@@ -1434,7 +1433,7 @@ impl<'a> State<'a> {
         self.print_ident(ast::Ident::with_dummy_span(name))
     }
 
-    pub fn print_for_decl(&mut self, loc: &hir::Local, coll: &hir::Expr) {
+    pub fn print_for_decl(&mut self, loc: &hir::Local<'_>, coll: &hir::Expr<'_>) {
         self.print_local_decl(loc);
         self.s.space();
         self.word_space("in");
@@ -1599,7 +1598,7 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_pat(&mut self, pat: &hir::Pat) {
+    pub fn print_pat(&mut self, pat: &hir::Pat<'_>) {
         self.maybe_print_comment(pat.span.lo());
         self.ann.pre(self, AnnNode::Pat(pat));
         // Pat isn't normalized, but the beauty of it
@@ -1761,12 +1760,12 @@ impl<'a> State<'a> {
         self.ann.post(self, AnnNode::Pat(pat))
     }
 
-    pub fn print_param(&mut self, arg: &hir::Param) {
+    pub fn print_param(&mut self, arg: &hir::Param<'_>) {
         self.print_outer_attributes(&arg.attrs);
         self.print_pat(&arg.pat);
     }
 
-    pub fn print_arm(&mut self, arm: &hir::Arm) {
+    pub fn print_arm(&mut self, arm: &hir::Arm<'_>) {
         // I have no idea why this check is necessary, but here it
         // is :(
         if arm.attrs.is_empty() {
@@ -2212,7 +2211,7 @@ impl<'a> State<'a> {
 /// isn't parsed as (if true {...} else {...} | x) | 5
 //
 // Duplicated from `parse::classify`, but adapted for the HIR.
-fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool {
+fn expr_requires_semi_to_be_stmt(e: &hir::Expr<'_>) -> bool {
     match e.kind {
         hir::ExprKind::Match(..) | hir::ExprKind::Block(..) | hir::ExprKind::Loop(..) => false,
         _ => true,
@@ -2222,7 +2221,7 @@ fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool {
 /// This statement requires a semicolon after it.
 /// note that in one case (stmt_semi), we've already
 /// seen the semicolon, and thus don't need another.
-fn stmt_ends_with_semi(stmt: &hir::StmtKind) -> bool {
+fn stmt_ends_with_semi(stmt: &hir::StmtKind<'_>) -> bool {
     match *stmt {
         hir::StmtKind::Local(_) => true,
         hir::StmtKind::Item(_) => false,
@@ -2261,7 +2260,7 @@ fn bin_op_to_assoc_op(op: hir::BinOpKind) -> AssocOp {
 /// Expressions that syntactically contain an "exterior" struct literal, i.e., not surrounded by any
 /// parens or other delimiters, e.g., `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and
 /// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not.
-fn contains_exterior_struct_lit(value: &hir::Expr) -> bool {
+fn contains_exterior_struct_lit(value: &hir::Expr<'_>) -> bool {
     match value.kind {
         hir::ExprKind::Struct(..) => true,
 
diff --git a/src/librustc/hir/upvars.rs b/src/librustc/hir/upvars.rs
index 2df7a38693a..d7de226df59 100644
--- a/src/librustc/hir/upvars.rs
+++ b/src/librustc/hir/upvars.rs
@@ -46,7 +46,7 @@ impl Visitor<'tcx> for LocalCollector {
         NestedVisitorMap::None
     }
 
-    fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
+    fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) {
         if let hir::PatKind::Binding(_, hir_id, ..) = pat.kind {
             self.locals.insert(hir_id);
         }
@@ -81,7 +81,7 @@ impl Visitor<'tcx> for CaptureCollector<'a, 'tcx> {
         intravisit::walk_path(self, path);
     }
 
-    fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         if let hir::ExprKind::Closure(..) = expr.kind {
             let closure_def_id = self.tcx.hir().local_def_id(expr.hir_id);
             if let Some(upvars) = self.tcx.upvars(closure_def_id) {
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index 360fa99c620..31d4f8513b2 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -117,7 +117,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
     }
 }
 
-impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
+impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr<'_> {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         hcx.while_hashing_hir_bodies(true, |hcx| {
             let hir::Expr { hir_id: _, ref span, ref kind, ref attrs } = *self;
diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs
index 9954c35433c..6b977393806 100644
--- a/src/librustc/infer/error_reporting/need_type_info.rs
+++ b/src/librustc/infer/error_reporting/need_type_info.rs
@@ -17,11 +17,11 @@ struct FindLocalByTypeVisitor<'a, 'tcx> {
     infcx: &'a InferCtxt<'a, 'tcx>,
     target_ty: Ty<'tcx>,
     hir_map: &'a hir::map::Map<'tcx>,
-    found_local_pattern: Option<&'tcx Pat>,
-    found_arg_pattern: Option<&'tcx Pat>,
+    found_local_pattern: Option<&'tcx Pat<'tcx>>,
+    found_arg_pattern: Option<&'tcx Pat<'tcx>>,
     found_ty: Option<Ty<'tcx>>,
-    found_closure: Option<&'tcx ExprKind>,
-    found_method_call: Option<&'tcx Expr>,
+    found_closure: Option<&'tcx ExprKind<'tcx>>,
+    found_method_call: Option<&'tcx Expr<'tcx>>,
 }
 
 impl<'a, 'tcx> FindLocalByTypeVisitor<'a, 'tcx> {
@@ -72,7 +72,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindLocalByTypeVisitor<'a, 'tcx> {
         NestedVisitorMap::OnlyBodies(&self.hir_map)
     }
 
-    fn visit_local(&mut self, local: &'tcx Local) {
+    fn visit_local(&mut self, local: &'tcx Local<'tcx>) {
         if let (None, Some(ty)) = (self.found_local_pattern, self.node_matches_type(local.hir_id)) {
             self.found_local_pattern = Some(&*local.pat);
             self.found_ty = Some(ty);
@@ -91,7 +91,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindLocalByTypeVisitor<'a, 'tcx> {
         intravisit::walk_body(self, body);
     }
 
-    fn visit_expr(&mut self, expr: &'tcx Expr) {
+    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
         if self.node_matches_type(expr.hir_id).is_some() {
             match expr.kind {
                 ExprKind::Closure(..) => self.found_closure = Some(&expr.kind),
@@ -460,8 +460,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     /// needed, suggest annotating the call, otherwise point out the resulting type of the call.
     fn annotate_method_call(
         &self,
-        segment: &hir::ptr::P<hir::PathSegment>,
-        e: &Expr,
+        segment: &hir::PathSegment,
+        e: &Expr<'_>,
         err: &mut DiagnosticBuilder<'_>,
     ) {
         if let (Ok(snippet), Some(tables), None) = (
diff --git a/src/librustc/infer/error_reporting/nice_region_error/util.rs b/src/librustc/infer/error_reporting/nice_region_error/util.rs
index 36e91fa3e37..638c8f52007 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/util.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/util.rs
@@ -12,7 +12,7 @@ use syntax_pos::Span;
 #[derive(Debug)]
 pub(super) struct AnonymousParamInfo<'tcx> {
     // the parameter corresponding to the anonymous region
-    pub param: &'tcx hir::Param,
+    pub param: &'tcx hir::Param<'tcx>,
     // the type corresponding to the anonymopus region parameter
     pub param_ty: Ty<'tcx>,
     // the ty::BoundRegion corresponding to the anonymous region
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 113084e7b7e..4e1e62512ac 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -894,7 +894,7 @@ impl<'a, 'tcx, T: LateLintPass<'a, 'tcx>> hir_visit::Visitor<'tcx>
         self.context.tables = old_tables;
     }
 
-    fn visit_param(&mut self, param: &'tcx hir::Param) {
+    fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
         self.with_lint_attrs(param.hir_id, &param.attrs, |cx| {
             lint_callback!(cx, check_param, param);
             hir_visit::walk_param(cx, param);
@@ -930,12 +930,12 @@ impl<'a, 'tcx, T: LateLintPass<'a, 'tcx>> hir_visit::Visitor<'tcx>
         })
     }
 
-    fn visit_pat(&mut self, p: &'tcx hir::Pat) {
+    fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
         lint_callback!(self, check_pat, p);
         hir_visit::walk_pat(self, p);
     }
 
-    fn visit_expr(&mut self, e: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
         self.with_lint_attrs(e.hir_id, &e.attrs, |cx| {
             lint_callback!(cx, check_expr, e);
             hir_visit::walk_expr(cx, e);
@@ -943,7 +943,7 @@ impl<'a, 'tcx, T: LateLintPass<'a, 'tcx>> hir_visit::Visitor<'tcx>
         })
     }
 
-    fn visit_stmt(&mut self, s: &'tcx hir::Stmt) {
+    fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
         // statement attributes are actually just attributes on one of
         // - item
         // - local
@@ -1020,20 +1020,20 @@ impl<'a, 'tcx, T: LateLintPass<'a, 'tcx>> hir_visit::Visitor<'tcx>
         }
     }
 
-    fn visit_local(&mut self, l: &'tcx hir::Local) {
+    fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
         self.with_lint_attrs(l.hir_id, &l.attrs, |cx| {
             lint_callback!(cx, check_local, l);
             hir_visit::walk_local(cx, l);
         })
     }
 
-    fn visit_block(&mut self, b: &'tcx hir::Block) {
+    fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) {
         lint_callback!(self, check_block, b);
         hir_visit::walk_block(self, b);
         lint_callback!(self, check_block_post, b);
     }
 
-    fn visit_arm(&mut self, a: &'tcx hir::Arm) {
+    fn visit_arm(&mut self, a: &'tcx hir::Arm<'tcx>) {
         lint_callback!(self, check_arm, a);
         hir_visit::walk_arm(self, a);
     }
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 6900ed4f475..97b38db4165 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -87,7 +87,7 @@ macro_rules! declare_lint_pass {
 macro_rules! late_lint_methods {
     ($macro:path, $args:tt, [$hir:tt]) => (
         $macro!($args, [$hir], [
-            fn check_param(a: &$hir hir::Param);
+            fn check_param(a: &$hir hir::Param<$hir>);
             fn check_body(a: &$hir hir::Body<$hir>);
             fn check_body_post(a: &$hir hir::Body<$hir>);
             fn check_name(a: Span, b: ast::Name);
@@ -99,14 +99,14 @@ macro_rules! late_lint_methods {
             fn check_foreign_item_post(a: &$hir hir::ForeignItem<$hir>);
             fn check_item(a: &$hir hir::Item<$hir>);
             fn check_item_post(a: &$hir hir::Item<$hir>);
-            fn check_local(a: &$hir hir::Local);
-            fn check_block(a: &$hir hir::Block);
-            fn check_block_post(a: &$hir hir::Block);
-            fn check_stmt(a: &$hir hir::Stmt);
-            fn check_arm(a: &$hir hir::Arm);
-            fn check_pat(a: &$hir hir::Pat);
-            fn check_expr(a: &$hir hir::Expr);
-            fn check_expr_post(a: &$hir hir::Expr);
+            fn check_local(a: &$hir hir::Local<$hir>);
+            fn check_block(a: &$hir hir::Block<$hir>);
+            fn check_block_post(a: &$hir hir::Block<$hir>);
+            fn check_stmt(a: &$hir hir::Stmt<$hir>);
+            fn check_arm(a: &$hir hir::Arm<$hir>);
+            fn check_pat(a: &$hir hir::Pat<$hir>);
+            fn check_expr(a: &$hir hir::Expr<$hir>);
+            fn check_expr_post(a: &$hir hir::Expr<$hir>);
             fn check_ty(a: &$hir hir::Ty);
             fn check_generic_param(a: &$hir hir::GenericParam);
             fn check_generics(a: &$hir hir::Generics);
@@ -610,7 +610,7 @@ impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'_, 'tcx> {
         intravisit::NestedVisitorMap::All(&self.tcx.hir())
     }
 
-    fn visit_param(&mut self, param: &'tcx hir::Param) {
+    fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
         self.with_lint_attrs(param.hir_id, &param.attrs, |builder| {
             intravisit::walk_param(builder, param);
         });
@@ -628,7 +628,7 @@ impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'_, 'tcx> {
         })
     }
 
-    fn visit_expr(&mut self, e: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
         self.with_lint_attrs(e.hir_id, &e.attrs, |builder| {
             intravisit::walk_expr(builder, e);
         })
@@ -651,13 +651,13 @@ impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'_, 'tcx> {
         })
     }
 
-    fn visit_local(&mut self, l: &'tcx hir::Local) {
+    fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
         self.with_lint_attrs(l.hir_id, &l.attrs, |builder| {
             intravisit::walk_local(builder, l);
         })
     }
 
-    fn visit_arm(&mut self, a: &'tcx hir::Arm) {
+    fn visit_arm(&mut self, a: &'tcx hir::Arm<'tcx>) {
         self.with_lint_attrs(a.hir_id, &a.attrs, |builder| {
             intravisit::walk_arm(builder, a);
         })
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 22af74c1361..c6598f2d328 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -96,7 +96,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
         self.tables = old_tables;
     }
 
-    fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         let res = match expr.kind {
             hir::ExprKind::Path(ref qpath) => Some(self.tables.qpath_res(qpath, expr.hir_id)),
             hir::ExprKind::MethodCall(..) => self
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 3e97beb7bce..5126d3f7fde 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -432,7 +432,7 @@ impl<'tcx> Visitor<'tcx> for ExprLocatorVisitor {
         NestedVisitorMap::None
     }
 
-    fn visit_pat(&mut self, pat: &'tcx Pat) {
+    fn visit_pat(&mut self, pat: &'tcx Pat<'tcx>) {
         intravisit::walk_pat(self, pat);
 
         self.expr_and_pat_count += 1;
@@ -442,7 +442,7 @@ impl<'tcx> Visitor<'tcx> for ExprLocatorVisitor {
         }
     }
 
-    fn visit_expr(&mut self, expr: &'tcx Expr) {
+    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
         debug!("ExprLocatorVisitor - pre-increment {} expr = {:?}", self.expr_and_pat_count, expr);
 
         intravisit::walk_expr(self, expr);
@@ -773,7 +773,7 @@ fn record_var_lifetime(
     }
 }
 
-fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx hir::Block) {
+fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx hir::Block<'tcx>) {
     debug!("resolve_block(blk.hir_id={:?})", blk.hir_id);
 
     let prev_cx = visitor.cx;
@@ -837,7 +837,7 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h
     visitor.cx = prev_cx;
 }
 
-fn resolve_arm<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, arm: &'tcx hir::Arm) {
+fn resolve_arm<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, arm: &'tcx hir::Arm<'tcx>) {
     let prev_cx = visitor.cx;
 
     visitor.enter_scope(Scope { id: arm.hir_id.local_id, data: ScopeData::Node });
@@ -854,7 +854,7 @@ fn resolve_arm<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, arm: &'tcx hir
     visitor.cx = prev_cx;
 }
 
-fn resolve_pat<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, pat: &'tcx hir::Pat) {
+fn resolve_pat<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, pat: &'tcx hir::Pat<'tcx>) {
     visitor.record_child_scope(Scope { id: pat.hir_id.local_id, data: ScopeData::Node });
 
     // If this is a binding then record the lifetime of that binding.
@@ -871,7 +871,7 @@ fn resolve_pat<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, pat: &'tcx hir
     debug!("resolve_pat - post-increment {} pat = {:?}", visitor.expr_and_pat_count, pat);
 }
 
-fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx hir::Stmt) {
+fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx hir::Stmt<'tcx>) {
     let stmt_id = stmt.hir_id.local_id;
     debug!("resolve_stmt(stmt.id={:?})", stmt_id);
 
@@ -890,7 +890,7 @@ fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx h
     visitor.cx.parent = prev_parent;
 }
 
-fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx hir::Expr) {
+fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
     debug!("resolve_expr - pre-increment {} expr = {:?}", visitor.expr_and_pat_count, expr);
 
     let prev_cx = visitor.cx;
@@ -1107,8 +1107,8 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
 
 fn resolve_local<'tcx>(
     visitor: &mut RegionResolutionVisitor<'tcx>,
-    pat: Option<&'tcx hir::Pat>,
-    init: Option<&'tcx hir::Expr>,
+    pat: Option<&'tcx hir::Pat<'tcx>>,
+    init: Option<&'tcx hir::Expr<'tcx>>,
 ) {
     debug!("resolve_local(pat={:?}, init={:?})", pat, init);
 
@@ -1197,7 +1197,7 @@ fn resolve_local<'tcx>(
     ///        | ( ..., P&, ... )
     ///        | ... "|" P& "|" ...
     ///        | box P&
-    fn is_binding_pat(pat: &hir::Pat) -> bool {
+    fn is_binding_pat(pat: &hir::Pat<'_>) -> bool {
         // Note that the code below looks for *explicit* refs only, that is, it won't
         // know about *implicit* refs as introduced in #42640.
         //
@@ -1263,7 +1263,7 @@ fn resolve_local<'tcx>(
     ///        | ( E& )
     fn record_rvalue_scope_if_borrow_expr<'tcx>(
         visitor: &mut RegionResolutionVisitor<'tcx>,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         blk_id: Option<Scope>,
     ) {
         match expr.kind {
@@ -1271,12 +1271,12 @@ fn resolve_local<'tcx>(
                 record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id);
                 record_rvalue_scope(visitor, &subexpr, blk_id);
             }
-            hir::ExprKind::Struct(_, ref fields, _) => {
+            hir::ExprKind::Struct(_, fields, _) => {
                 for field in fields {
                     record_rvalue_scope_if_borrow_expr(visitor, &field.expr, blk_id);
                 }
             }
-            hir::ExprKind::Array(ref subexprs) | hir::ExprKind::Tup(ref subexprs) => {
+            hir::ExprKind::Array(subexprs) | hir::ExprKind::Tup(subexprs) => {
                 for subexpr in subexprs {
                     record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id);
                 }
@@ -1310,7 +1310,7 @@ fn resolve_local<'tcx>(
     /// Note: ET is intended to match "rvalues or places based on rvalues".
     fn record_rvalue_scope<'tcx>(
         visitor: &mut RegionResolutionVisitor<'tcx>,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         blk_scope: Option<Scope>,
     ) {
         let mut expr = expr;
@@ -1372,7 +1372,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
         NestedVisitorMap::None
     }
 
-    fn visit_block(&mut self, b: &'tcx Block) {
+    fn visit_block(&mut self, b: &'tcx Block<'tcx>) {
         resolve_block(self, b);
     }
 
@@ -1444,19 +1444,19 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
         self.terminating_scopes = outer_ts;
     }
 
-    fn visit_arm(&mut self, a: &'tcx Arm) {
+    fn visit_arm(&mut self, a: &'tcx Arm<'tcx>) {
         resolve_arm(self, a);
     }
-    fn visit_pat(&mut self, p: &'tcx Pat) {
+    fn visit_pat(&mut self, p: &'tcx Pat<'tcx>) {
         resolve_pat(self, p);
     }
-    fn visit_stmt(&mut self, s: &'tcx Stmt) {
+    fn visit_stmt(&mut self, s: &'tcx Stmt<'tcx>) {
         resolve_stmt(self, s);
     }
-    fn visit_expr(&mut self, ex: &'tcx Expr) {
+    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
         resolve_expr(self, ex);
     }
-    fn visit_local(&mut self, l: &'tcx Local) {
+    fn visit_local(&mut self, l: &'tcx Local<'tcx>) {
         resolve_local(self, Some(&l.pat), l.init.as_ref().map(|e| &**e));
     }
 }
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 67630a75768..7950ff421b4 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -1133,7 +1133,7 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) {
             NestedVisitorMap::None
         }
 
-        fn visit_expr(&mut self, ex: &hir::Expr) {
+        fn visit_expr(&mut self, ex: &hir::Expr<'_>) {
             if let Some(label) = expression_label(ex) {
                 for prior_label in &self.labels_in_fn[..] {
                     // FIXME (#24278): non-hygienic comparison
@@ -1155,7 +1155,7 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) {
         }
     }
 
-    fn expression_label(ex: &hir::Expr) -> Option<ast::Ident> {
+    fn expression_label(ex: &hir::Expr<'_>) -> Option<ast::Ident> {
         if let hir::ExprKind::Loop(_, Some(label), _) = ex.kind { Some(label.ident) } else { None }
     }
 
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 42db64c7915..f7d9cb34fa9 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -1331,19 +1331,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         err: &mut DiagnosticBuilder<'_>,
         msg: &str,
     ) -> Option<String> {
-        let get_name = |err: &mut DiagnosticBuilder<'_>, kind: &hir::PatKind| -> Option<String> {
-            // Get the local name of this closure. This can be inaccurate because
-            // of the possibility of reassignment, but this should be good enough.
-            match &kind {
-                hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, name, None) => {
-                    Some(format!("{}", name))
-                }
-                _ => {
-                    err.note(&msg);
-                    None
+        let get_name =
+            |err: &mut DiagnosticBuilder<'_>, kind: &hir::PatKind<'_>| -> Option<String> {
+                // Get the local name of this closure. This can be inaccurate because
+                // of the possibility of reassignment, but this should be good enough.
+                match &kind {
+                    hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, name, None) => {
+                        Some(format!("{}", name))
+                    }
+                    _ => {
+                        err.note(&msg);
+                        None
+                    }
                 }
-            }
-        };
+            };
 
         let hir = self.tcx.hir();
         let hir_id = hir.as_local_hir_id(def_id)?;
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index e99e00a366d..2659caf030b 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -553,11 +553,11 @@ impl<'tcx> TypeckTables<'tcx> {
 
     // Returns the type of a pattern as a monotype. Like @expr_ty, this function
     // doesn't provide type parameter substitutions.
-    pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> {
+    pub fn pat_ty(&self, pat: &hir::Pat<'_>) -> Ty<'tcx> {
         self.node_type(pat.hir_id)
     }
 
-    pub fn pat_ty_opt(&self, pat: &hir::Pat) -> Option<Ty<'tcx>> {
+    pub fn pat_ty_opt(&self, pat: &hir::Pat<'_>) -> Option<Ty<'tcx>> {
         self.node_type_opt(pat.hir_id)
     }
 
@@ -571,11 +571,11 @@ impl<'tcx> TypeckTables<'tcx> {
     // NB (2): This type doesn't provide type parameter substitutions; e.g., if you
     // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
     // instead of "fn(ty) -> T with T = isize".
-    pub fn expr_ty(&self, expr: &hir::Expr) -> Ty<'tcx> {
+    pub fn expr_ty(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
         self.node_type(expr.hir_id)
     }
 
-    pub fn expr_ty_opt(&self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
+    pub fn expr_ty_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
         self.node_type_opt(expr.hir_id)
     }
 
@@ -589,22 +589,22 @@ impl<'tcx> TypeckTables<'tcx> {
         LocalTableInContextMut { local_id_root: self.local_id_root, data: &mut self.adjustments }
     }
 
-    pub fn expr_adjustments(&self, expr: &hir::Expr) -> &[ty::adjustment::Adjustment<'tcx>] {
+    pub fn expr_adjustments(&self, expr: &hir::Expr<'_>) -> &[ty::adjustment::Adjustment<'tcx>] {
         validate_hir_id_for_typeck_tables(self.local_id_root, expr.hir_id, false);
         self.adjustments.get(&expr.hir_id.local_id).map_or(&[], |a| &a[..])
     }
 
     /// Returns the type of `expr`, considering any `Adjustment`
     /// entry recorded for that expression.
-    pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> Ty<'tcx> {
+    pub fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
         self.expr_adjustments(expr).last().map_or_else(|| self.expr_ty(expr), |adj| adj.target)
     }
 
-    pub fn expr_ty_adjusted_opt(&self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
+    pub fn expr_ty_adjusted_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
         self.expr_adjustments(expr).last().map(|adj| adj.target).or_else(|| self.expr_ty_opt(expr))
     }
 
-    pub fn is_method_call(&self, expr: &hir::Expr) -> bool {
+    pub fn is_method_call(&self, expr: &hir::Expr<'_>) -> bool {
         // Only paths and method calls/overloaded operators have
         // entries in type_dependent_defs, ignore the former here.
         if let hir::ExprKind::Path(_) = expr.kind {
diff --git a/src/librustc_lint/array_into_iter.rs b/src/librustc_lint/array_into_iter.rs
index b6075d165dd..481ca43aa79 100644
--- a/src/librustc_lint/array_into_iter.rs
+++ b/src/librustc_lint/array_into_iter.rs
@@ -25,7 +25,7 @@ declare_lint_pass!(
 );
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIntoIter {
-    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
+    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'tcx>) {
         // We only care about method call expressions.
         if let hir::ExprKind::MethodCall(call, span, args) = &expr.kind {
             if call.ident.name != sym::into_iter {
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 332176e1b0c..2d9e960716f 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -142,7 +142,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxPointers {
         }
     }
 
-    fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) {
+    fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr<'_>) {
         let ty = cx.tables.node_type(e.hir_id);
         self.check_heap_type(cx, e.span, ty);
     }
@@ -157,8 +157,8 @@ declare_lint! {
 declare_lint_pass!(NonShorthandFieldPatterns => [NON_SHORTHAND_FIELD_PATTERNS]);
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns {
-    fn check_pat(&mut self, cx: &LateContext<'_, '_>, pat: &hir::Pat) {
-        if let PatKind::Struct(ref qpath, ref field_pats, _) = pat.kind {
+    fn check_pat(&mut self, cx: &LateContext<'_, '_>, pat: &hir::Pat<'_>) {
+        if let PatKind::Struct(ref qpath, field_pats, _) = pat.kind {
             let variant = cx
                 .tables
                 .pat_ty(pat)
@@ -901,7 +901,7 @@ declare_lint! {
 declare_lint_pass!(MutableTransmutes => [MUTABLE_TRANSMUTES]);
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
-    fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &hir::Expr) {
+    fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) {
         use rustc_target::spec::abi::Abi::RustIntrinsic;
 
         let msg = "mutating transmuted &mut T from &T may cause undefined behavior, \
@@ -917,7 +917,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
 
         fn get_transmute_from_to<'a, 'tcx>(
             cx: &LateContext<'a, 'tcx>,
-            expr: &hir::Expr,
+            expr: &hir::Expr<'_>,
         ) -> Option<(Ty<'tcx>, Ty<'tcx>)> {
             let def = if let hir::ExprKind::Path(ref qpath) = expr.kind {
                 cx.tables.qpath_res(qpath, expr.hir_id)
@@ -1840,7 +1840,7 @@ declare_lint! {
 declare_lint_pass!(InvalidValue => [INVALID_VALUE]);
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
-    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &hir::Expr) {
+    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &hir::Expr<'_>) {
         #[derive(Debug, Copy, Clone, PartialEq)]
         enum InitKind {
             Zeroed,
@@ -1852,7 +1852,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
         type InitError = (String, Option<Span>);
 
         /// Test if this constant is all-0.
-        fn is_zero(expr: &hir::Expr) -> bool {
+        fn is_zero(expr: &hir::Expr<'_>) -> bool {
             use hir::ExprKind::*;
             use syntax::ast::LitKind::*;
             match &expr.kind {
@@ -1869,7 +1869,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
         }
 
         /// Determine if this expression is a "dangerous initialization".
-        fn is_dangerous_init(cx: &LateContext<'_, '_>, expr: &hir::Expr) -> Option<InitKind> {
+        fn is_dangerous_init(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) -> Option<InitKind> {
             // `transmute` is inside an anonymous module (the `extern` block?);
             // `Invalid` represents the empty string and matches that.
             // FIXME(#66075): use diagnostic items.  Somehow, that does not seem to work
diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs
index b8b4c2b39e5..2752be9a6de 100644
--- a/src/librustc_lint/nonstandard_style.rs
+++ b/src/librustc_lint/nonstandard_style.rs
@@ -344,7 +344,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase {
         }
     }
 
-    fn check_pat(&mut self, cx: &LateContext<'_, '_>, p: &hir::Pat) {
+    fn check_pat(&mut self, cx: &LateContext<'_, '_>, p: &hir::Pat<'_>) {
         if let &PatKind::Binding(_, _, ident, _) = &p.kind {
             self.check_snake_case(cx, "variable", &ident);
         }
@@ -410,7 +410,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals {
         }
     }
 
-    fn check_pat(&mut self, cx: &LateContext<'_, '_>, p: &hir::Pat) {
+    fn check_pat(&mut self, cx: &LateContext<'_, '_>, p: &hir::Pat<'_>) {
         // Lint for constants that look like binding identifiers (#7526)
         if let PatKind::Path(hir::QPath::Resolved(None, ref path)) = p.kind {
             if let Res::Def(DefKind::Const, _) = path.res {
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 45b8666c42b..ba2087d2f26 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -65,8 +65,8 @@ fn lint_overflowing_range_endpoint<'a, 'tcx>(
     lit: &hir::Lit,
     lit_val: u128,
     max: u128,
-    expr: &'tcx hir::Expr,
-    parent_expr: &'tcx hir::Expr,
+    expr: &'tcx hir::Expr<'tcx>,
+    parent_expr: &'tcx hir::Expr<'tcx>,
     ty: &str,
 ) -> bool {
     // We only want to handle exclusive (`..`) ranges,
@@ -150,7 +150,7 @@ fn get_bin_hex_repr(cx: &LateContext<'_, '_>, lit: &hir::Lit) -> Option<String>
 
 fn report_bin_hex_error(
     cx: &LateContext<'_, '_>,
-    expr: &hir::Expr,
+    expr: &hir::Expr<'_>,
     ty: attr::IntType,
     repr_str: String,
     val: u128,
@@ -244,7 +244,7 @@ fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static
 fn lint_int_literal<'a, 'tcx>(
     cx: &LateContext<'a, 'tcx>,
     type_limits: &TypeLimits,
-    e: &'tcx hir::Expr,
+    e: &'tcx hir::Expr<'tcx>,
     lit: &hir::Lit,
     t: ast::IntTy,
     v: u128,
@@ -284,7 +284,7 @@ fn lint_int_literal<'a, 'tcx>(
 
 fn lint_uint_literal<'a, 'tcx>(
     cx: &LateContext<'a, 'tcx>,
-    e: &'tcx hir::Expr,
+    e: &'tcx hir::Expr<'tcx>,
     lit: &hir::Lit,
     t: ast::UintTy,
 ) {
@@ -342,7 +342,7 @@ fn lint_uint_literal<'a, 'tcx>(
 fn lint_literal<'a, 'tcx>(
     cx: &LateContext<'a, 'tcx>,
     type_limits: &TypeLimits,
-    e: &'tcx hir::Expr,
+    e: &'tcx hir::Expr<'tcx>,
     lit: &hir::Lit,
 ) {
     match cx.tables.node_type(e.hir_id).kind {
@@ -377,7 +377,7 @@ fn lint_literal<'a, 'tcx>(
 }
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
-    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx hir::Expr) {
+    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx hir::Expr<'tcx>) {
         match e.kind {
             hir::ExprKind::Unary(hir::UnNeg, ref expr) => {
                 // propagate negation, if the negation itself isn't negated
@@ -425,8 +425,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
         fn check_limits(
             cx: &LateContext<'_, '_>,
             binop: hir::BinOp,
-            l: &hir::Expr,
-            r: &hir::Expr,
+            l: &hir::Expr<'_>,
+            r: &hir::Expr<'_>,
         ) -> bool {
             let (lit, expr, swap) = match (&l.kind, &r.kind) {
                 (&hir::ExprKind::Lit(_), _) => (l, r, true),
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 5f57aabe8d4..5edb81c1e51 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -37,7 +37,7 @@ declare_lint! {
 declare_lint_pass!(UnusedResults => [UNUSED_MUST_USE, UNUSED_RESULTS]);
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
-    fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt) {
+    fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt<'_>) {
         let expr = match s.kind {
             hir::StmtKind::Semi(ref expr) => &**expr,
             _ => return,
@@ -123,7 +123,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
         fn check_must_use_ty<'tcx>(
             cx: &LateContext<'_, 'tcx>,
             ty: Ty<'tcx>,
-            expr: &hir::Expr,
+            expr: &hir::Expr<'_>,
             span: Span,
             descr_pre: &str,
             descr_post: &str,
@@ -245,7 +245,7 @@ declare_lint! {
 declare_lint_pass!(PathStatements => [PATH_STATEMENTS]);
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PathStatements {
-    fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt) {
+    fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt<'_>) {
         if let hir::StmtKind::Semi(ref expr) = s.kind {
             if let hir::ExprKind::Path(_) = expr.kind {
                 cx.span_lint(PATH_STATEMENTS, s.span, "path statement with no effect");
@@ -637,7 +637,7 @@ declare_lint! {
 declare_lint_pass!(UnusedAllocation => [UNUSED_ALLOCATION]);
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAllocation {
-    fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) {
+    fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr<'_>) {
         match e.kind {
             hir::ExprKind::Box(_) => {}
             _ => return,
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index 1e93d144f15..84d5d529adf 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -1524,7 +1524,7 @@ impl Visitor<'tcx> for EncodeContext<'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
         NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
-    fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
         intravisit::walk_expr(self, ex);
         self.encode_info_for_expr(ex);
     }
@@ -1587,7 +1587,7 @@ impl EncodeContext<'tcx> {
         }
     }
 
-    fn encode_info_for_expr(&mut self, expr: &hir::Expr) {
+    fn encode_info_for_expr(&mut self, expr: &hir::Expr<'_>) {
         match expr.kind {
             hir::ExprKind::Closure(..) => {
                 let def_id = self.tcx.hir().local_def_id(expr.hir_id);
diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs
index 077854c8ed5..da8bb6adf84 100644
--- a/src/librustc_mir/build/block.rs
+++ b/src/librustc_mir/build/block.rs
@@ -11,7 +11,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         &mut self,
         destination: &Place<'tcx>,
         block: BasicBlock,
-        ast_block: &'tcx hir::Block,
+        ast_block: &'tcx hir::Block<'tcx>,
         source_info: SourceInfo,
     ) -> BlockAnd<()> {
         let Block {
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 5ecf393179c..f459ca8dbba 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -29,8 +29,10 @@ pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
 
     // Figure out what primary body this item has.
     let (body_id, return_ty_span) = match tcx.hir().get(id) {
-        Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, decl, body_id, _, _), .. })
-        | Node::Item(hir::Item {
+        Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, decl, body_id, _, _), .. }) => {
+            (*body_id, decl.output.span())
+        }
+        Node::Item(hir::Item {
             kind: hir::ItemKind::Fn(hir::FnSig { decl, .. }, _, body_id),
             ..
         })
@@ -529,7 +531,12 @@ fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: DefId, _abi: Abi) -> bool {
 ///////////////////////////////////////////////////////////////////////////
 /// the main entry point for building MIR for a function
 
-struct ArgInfo<'tcx>(Ty<'tcx>, Option<Span>, Option<&'tcx hir::Param>, Option<ImplicitSelfKind>);
+struct ArgInfo<'tcx>(
+    Ty<'tcx>,
+    Option<Span>,
+    Option<&'tcx hir::Param<'tcx>>,
+    Option<ImplicitSelfKind>,
+);
 
 fn construct_fn<'a, 'tcx, A>(
     hir: Cx<'a, 'tcx>,
@@ -738,7 +745,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         fn_def_id: DefId,
         arguments: &[ArgInfo<'tcx>],
         argument_scope: region::Scope,
-        ast_body: &'tcx hir::Expr,
+        ast_body: &'tcx hir::Expr<'tcx>,
     ) -> BlockAnd<()> {
         // Allocate locals for the function arguments
         for &ArgInfo(ty, _, arg_opt, _) in arguments.iter() {
diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs
index 85adb6a0056..14f6c394530 100644
--- a/src/librustc_mir/hair/cx/block.rs
+++ b/src/librustc_mir/hair/cx/block.rs
@@ -8,7 +8,7 @@ use rustc::ty;
 
 use rustc_index::vec::Idx;
 
-impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
+impl<'tcx> Mirror<'tcx> for &'tcx hir::Block<'tcx> {
     type Output = Block<'tcx>;
 
     fn make_mirror(self, cx: &mut Cx<'_, 'tcx>) -> Block<'tcx> {
@@ -37,7 +37,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
 fn mirror_stmts<'a, 'tcx>(
     cx: &mut Cx<'a, 'tcx>,
     block_id: hir::ItemLocalId,
-    stmts: &'tcx [hir::Stmt],
+    stmts: &'tcx [hir::Stmt<'tcx>],
 ) -> Vec<StmtRef<'tcx>> {
     let mut result = vec![];
     for (index, stmt) in stmts.iter().enumerate() {
@@ -101,7 +101,10 @@ fn mirror_stmts<'a, 'tcx>(
     return result;
 }
 
-pub fn to_expr_ref<'a, 'tcx>(cx: &mut Cx<'a, 'tcx>, block: &'tcx hir::Block) -> ExprRef<'tcx> {
+pub fn to_expr_ref<'a, 'tcx>(
+    cx: &mut Cx<'a, 'tcx>,
+    block: &'tcx hir::Block<'tcx>,
+) -> ExprRef<'tcx> {
     let block_ty = cx.tables().node_type(block.hir_id);
     let temp_lifetime = cx.region_scope_tree.temporary_scope(block.hir_id.local_id);
     let expr = Expr {
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index b5cd24bebc3..124b788fe8d 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -14,7 +14,7 @@ use rustc::ty::{self, AdtKind, Ty};
 use rustc_index::vec::Idx;
 use syntax_pos::Span;
 
-impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
+impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr<'tcx> {
     type Output = Expr<'tcx>;
 
     fn make_mirror(self, cx: &mut Cx<'_, 'tcx>) -> Expr<'tcx> {
@@ -65,7 +65,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
 
 fn apply_adjustment<'a, 'tcx>(
     cx: &mut Cx<'a, 'tcx>,
-    hir_expr: &'tcx hir::Expr,
+    hir_expr: &'tcx hir::Expr<'tcx>,
     mut expr: Expr<'tcx>,
     adjustment: &Adjustment<'tcx>,
 ) -> Expr<'tcx> {
@@ -129,7 +129,10 @@ fn apply_adjustment<'a, 'tcx>(
     Expr { temp_lifetime, ty: adjustment.target, span, kind }
 }
 
-fn make_mirror_unadjusted<'a, 'tcx>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr) -> Expr<'tcx> {
+fn make_mirror_unadjusted<'a, 'tcx>(
+    cx: &mut Cx<'a, 'tcx>,
+    expr: &'tcx hir::Expr<'tcx>,
+) -> Expr<'tcx> {
     let expr_ty = cx.tables().expr_ty(expr);
     let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
 
@@ -608,7 +611,7 @@ fn user_substs_applied_to_res(
 
 fn method_callee<'a, 'tcx>(
     cx: &mut Cx<'a, 'tcx>,
-    expr: &hir::Expr,
+    expr: &hir::Expr<'_>,
     span: Span,
     overloaded_callee: Option<(DefId, SubstsRef<'tcx>)>,
 ) -> Expr<'tcx> {
@@ -662,7 +665,7 @@ impl ToBorrowKind for hir::Mutability {
     }
 }
 
-fn convert_arm<'tcx>(cx: &mut Cx<'_, 'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> {
+fn convert_arm<'tcx>(cx: &mut Cx<'_, 'tcx>, arm: &'tcx hir::Arm<'tcx>) -> Arm<'tcx> {
     Arm {
         pattern: cx.pattern_from_hir(&arm.pat),
         guard: match arm.guard {
@@ -678,7 +681,7 @@ fn convert_arm<'tcx>(cx: &mut Cx<'_, 'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> {
 
 fn convert_path_expr<'a, 'tcx>(
     cx: &mut Cx<'a, 'tcx>,
-    expr: &'tcx hir::Expr,
+    expr: &'tcx hir::Expr<'tcx>,
     res: Res,
 ) -> ExprKind<'tcx> {
     let substs = cx.tables().node_substs(expr.hir_id);
@@ -771,7 +774,7 @@ fn convert_path_expr<'a, 'tcx>(
 
 fn convert_var(
     cx: &mut Cx<'_, 'tcx>,
-    expr: &'tcx hir::Expr,
+    expr: &'tcx hir::Expr<'tcx>,
     var_hir_id: hir::HirId,
 ) -> ExprKind<'tcx> {
     let upvar_index = cx
@@ -914,7 +917,7 @@ fn bin_op(op: hir::BinOpKind) -> BinOp {
 
 fn overloaded_operator<'a, 'tcx>(
     cx: &mut Cx<'a, 'tcx>,
-    expr: &'tcx hir::Expr,
+    expr: &'tcx hir::Expr<'tcx>,
     args: Vec<ExprRef<'tcx>>,
 ) -> ExprKind<'tcx> {
     let fun = method_callee(cx, expr, expr.span, None);
@@ -923,7 +926,7 @@ fn overloaded_operator<'a, 'tcx>(
 
 fn overloaded_place<'a, 'tcx>(
     cx: &mut Cx<'a, 'tcx>,
-    expr: &'tcx hir::Expr,
+    expr: &'tcx hir::Expr<'tcx>,
     place_ty: Ty<'tcx>,
     overloaded_callee: Option<(DefId, SubstsRef<'tcx>)>,
     args: Vec<ExprRef<'tcx>>,
@@ -963,7 +966,7 @@ fn overloaded_place<'a, 'tcx>(
 
 fn capture_upvar<'tcx>(
     cx: &mut Cx<'_, 'tcx>,
-    closure_expr: &'tcx hir::Expr,
+    closure_expr: &'tcx hir::Expr<'tcx>,
     var_hir_id: hir::HirId,
     upvar_ty: Ty<'tcx>,
 ) -> ExprRef<'tcx> {
@@ -1002,7 +1005,7 @@ fn capture_upvar<'tcx>(
 /// Converts a list of named fields (i.e., for struct-like struct/enum ADTs) into FieldExprRef.
 fn field_refs<'a, 'tcx>(
     cx: &mut Cx<'a, 'tcx>,
-    fields: &'tcx [hir::Field],
+    fields: &'tcx [hir::Field<'tcx>],
 ) -> Vec<FieldExprRef<'tcx>> {
     fields
         .iter()
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index dbabfb1b161..5c3baaa6ddc 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -151,7 +151,7 @@ impl<'a, 'tcx> Cx<'a, 'tcx> {
         }
     }
 
-    pub fn pattern_from_hir(&mut self, p: &hir::Pat) -> Pat<'tcx> {
+    pub fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Pat<'tcx> {
         let p = match self.tcx.hir().get(p.hir_id) {
             Node::Pat(p) | Node::Binding(p) => p,
             node => bug!("pattern became {:?}", node),
diff --git a/src/librustc_mir/hair/cx/to_ref.rs b/src/librustc_mir/hair/cx/to_ref.rs
index c365cc2ad85..e40e21e76c3 100644
--- a/src/librustc_mir/hair/cx/to_ref.rs
+++ b/src/librustc_mir/hair/cx/to_ref.rs
@@ -1,14 +1,13 @@
 use crate::hair::*;
 
 use rustc::hir;
-use rustc::hir::ptr::P;
 
 pub trait ToRef {
     type Output;
     fn to_ref(self) -> Self::Output;
 }
 
-impl<'tcx> ToRef for &'tcx hir::Expr {
+impl<'tcx> ToRef for &'tcx hir::Expr<'tcx> {
     type Output = ExprRef<'tcx>;
 
     fn to_ref(self) -> ExprRef<'tcx> {
@@ -16,7 +15,7 @@ impl<'tcx> ToRef for &'tcx hir::Expr {
     }
 }
 
-impl<'tcx> ToRef for &'tcx P<hir::Expr> {
+impl<'tcx> ToRef for &'tcx &'tcx hir::Expr<'tcx> {
     type Output = ExprRef<'tcx>;
 
     fn to_ref(self) -> ExprRef<'tcx> {
@@ -54,7 +53,7 @@ where
     }
 }
 
-impl<'tcx, T, U> ToRef for &'tcx P<[T]>
+impl<'tcx, T, U> ToRef for &'tcx [T]
 where
     &'tcx T: ToRef<Output = U>,
 {
diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs
index 188c73e105a..8973c19d58f 100644
--- a/src/librustc_mir/hair/mod.rs
+++ b/src/librustc_mir/hair/mod.rs
@@ -184,7 +184,7 @@ pub enum ExprKind<'tcx> {
         arms: Vec<Arm<'tcx>>,
     },
     Block {
-        body: &'tcx hir::Block,
+        body: &'tcx hir::Block<'tcx>,
     },
     Assign {
         lhs: ExprRef<'tcx>,
@@ -289,7 +289,7 @@ pub enum ExprKind<'tcx> {
 
 #[derive(Clone, Debug)]
 pub enum ExprRef<'tcx> {
-    Hair(&'tcx hir::Expr),
+    Hair(&'tcx hir::Expr<'tcx>),
     Mirror(Box<Expr<'tcx>>),
 }
 
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index 67c89c7293c..47f2b480850 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -53,7 +53,7 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> {
         NestedVisitorMap::None
     }
 
-    fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
         intravisit::walk_expr(self, ex);
 
         if let hir::ExprKind::Match(ref scrut, ref arms, source) = ex.kind {
@@ -61,7 +61,7 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> {
         }
     }
 
-    fn visit_local(&mut self, loc: &'tcx hir::Local) {
+    fn visit_local(&mut self, loc: &'tcx hir::Local<'tcx>) {
         intravisit::walk_local(self, loc);
 
         let (msg, sp) = match loc.source {
@@ -121,7 +121,7 @@ impl PatCtxt<'_, '_> {
 }
 
 impl<'tcx> MatchVisitor<'_, 'tcx> {
-    fn check_patterns(&mut self, has_guard: bool, pat: &Pat) {
+    fn check_patterns(&mut self, has_guard: bool, pat: &Pat<'_>) {
         check_legality_of_move_bindings(self, has_guard, pat);
         check_borrow_conflicts_in_at_patterns(self, pat);
         if !self.tcx.features().bindings_after_at {
@@ -129,7 +129,12 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
         }
     }
 
-    fn check_match(&mut self, scrut: &hir::Expr, arms: &'tcx [hir::Arm], source: hir::MatchSource) {
+    fn check_match(
+        &mut self,
+        scrut: &hir::Expr<'_>,
+        arms: &'tcx [hir::Arm<'tcx>],
+        source: hir::MatchSource,
+    ) {
         for arm in arms {
             // First, check legality of move bindings.
             self.check_patterns(arm.guard.is_some(), &arm.pat);
@@ -178,7 +183,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
         })
     }
 
-    fn check_irrefutable(&self, pat: &'tcx Pat, origin: &str, sp: Option<Span>) {
+    fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>) {
         let module = self.tcx.hir().get_module_parent(pat.hir_id);
         MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module, |ref mut cx| {
             let mut patcx =
@@ -246,7 +251,12 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
 
 /// A path pattern was interpreted as a constant, not a new variable.
 /// This caused an irrefutable match failure in e.g. `let`.
-fn const_not_var(err: &mut DiagnosticBuilder<'_>, tcx: TyCtxt<'_>, pat: &Pat, path: &hir::Path) {
+fn const_not_var(
+    err: &mut DiagnosticBuilder<'_>,
+    tcx: TyCtxt<'_>,
+    pat: &Pat<'_>,
+    path: &hir::Path,
+) {
     let descr = path.res.descr();
     err.span_label(
         pat.span,
@@ -268,7 +278,7 @@ fn const_not_var(err: &mut DiagnosticBuilder<'_>, tcx: TyCtxt<'_>, pat: &Pat, pa
     }
 }
 
-fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pat) {
+fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_>) {
     pat.walk_always(|p| {
         if let hir::PatKind::Binding(_, _, ident, None) = p.kind {
             if let Some(ty::BindByValue(hir::Mutability::Not)) =
@@ -307,7 +317,7 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pa
 }
 
 /// Checks for common cases of "catchall" patterns that may not be intended as such.
-fn pat_is_catchall(pat: &Pat) -> bool {
+fn pat_is_catchall(pat: &Pat<'_>) -> bool {
     match pat.kind {
         hir::PatKind::Binding(.., None) => true,
         hir::PatKind::Binding(.., Some(ref s)) => pat_is_catchall(s),
@@ -320,7 +330,7 @@ fn pat_is_catchall(pat: &Pat) -> bool {
 /// Check for unreachable patterns.
 fn check_arms<'p, 'tcx>(
     cx: &mut MatchCheckCtxt<'p, 'tcx>,
-    arms: &[(&'p super::Pat<'tcx>, &hir::Pat, bool)],
+    arms: &[(&'p super::Pat<'tcx>, &hir::Pat<'_>, bool)],
     source: hir::MatchSource,
 ) -> Matrix<'p, 'tcx> {
     let mut seen = Matrix::empty();
@@ -575,7 +585,7 @@ fn maybe_point_at_variant(ty: Ty<'_>, patterns: &[super::Pat<'_>]) -> Vec<Span>
 }
 
 /// Check the legality of legality of by-move bindings.
-fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: bool, pat: &Pat) {
+fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: bool, pat: &Pat<'_>) {
     let sess = cx.tcx.sess;
     let tables = cx.tables;
 
@@ -589,7 +599,7 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo
 
     // Find bad by-move spans:
     let by_move_spans = &mut Vec::new();
-    let mut check_move = |p: &Pat, sub: Option<&Pat>| {
+    let mut check_move = |p: &Pat<'_>, sub: Option<&Pat<'_>>| {
         // Check legality of moving out of the enum.
         //
         // `x @ Foo(..)` is legal, but `x @ Foo(y)` isn't.
@@ -638,7 +648,7 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo
 /// - `ref mut x @ Some(ref mut y)`.
 ///
 /// This analysis is *not* subsumed by NLL.
-fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) {
+fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_>) {
     let tab = cx.tables;
     let sess = cx.tcx.sess;
     // Get the mutability of `p` if it's by-ref.
@@ -709,7 +719,7 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) {
 
 /// Forbids bindings in `@` patterns. This used to be is necessary for memory safety,
 /// because of the way rvalues were handled in the borrow check. (See issue #14587.)
-fn check_legality_of_bindings_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) {
+fn check_legality_of_bindings_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_>) {
     AtBindingPatternVisitor { cx, bindings_allowed: true }.visit_pat(pat);
 
     struct AtBindingPatternVisitor<'a, 'b, 'tcx> {
@@ -722,7 +732,7 @@ fn check_legality_of_bindings_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pa
             NestedVisitorMap::None
         }
 
-        fn visit_pat(&mut self, pat: &Pat) {
+        fn visit_pat(&mut self, pat: &Pat<'_>) {
             match pat.kind {
                 hir::PatKind::Binding(.., ref subpat) => {
                     if !self.bindings_allowed {
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 869aeeba418..bf0de7e9ef0 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -11,7 +11,6 @@ use crate::hair::util::UserAnnotatedTyHelpers;
 
 use rustc::hir::def::{CtorKind, CtorOf, DefKind, Res};
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
-use rustc::hir::ptr::P;
 use rustc::hir::{self, RangeEnd};
 use rustc::mir::interpret::{get_slice_bytes, sign_extend, ConstValue, ErrorHandled};
 use rustc::mir::UserTypeProjection;
@@ -356,7 +355,7 @@ impl<'a, 'tcx> Pat<'tcx> {
         tcx: TyCtxt<'tcx>,
         param_env_and_substs: ty::ParamEnvAnd<'tcx, SubstsRef<'tcx>>,
         tables: &'a ty::TypeckTables<'tcx>,
-        pat: &'tcx hir::Pat,
+        pat: &'tcx hir::Pat<'tcx>,
     ) -> Self {
         let mut pcx = PatCtxt::new(tcx, param_env_and_substs, tables);
         let result = pcx.lower_pattern(pat);
@@ -390,7 +389,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         self
     }
 
-    pub fn lower_pattern(&mut self, pat: &'tcx hir::Pat) -> Pat<'tcx> {
+    pub fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Pat<'tcx> {
         // When implicit dereferences have been inserted in this pattern, the unadjusted lowered
         // pattern has the type that results *after* dereferencing. For example, in this code:
         //
@@ -426,7 +425,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
 
     fn lower_range_expr(
         &mut self,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
     ) -> (PatKind<'tcx>, Option<Ascription<'tcx>>) {
         match self.lower_lit(expr) {
             PatKind::AscribeUserType {
@@ -437,7 +436,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         }
     }
 
-    fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pat<'tcx> {
+    fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Pat<'tcx> {
         let mut ty = self.tables.node_type(pat.hir_id);
 
         if let ty::Error = ty.kind {
@@ -616,7 +615,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
 
     fn lower_tuple_subpats(
         &mut self,
-        pats: &'tcx [P<hir::Pat>],
+        pats: &'tcx [&'tcx hir::Pat<'tcx>],
         expected_len: usize,
         gap_pos: Option<usize>,
     ) -> Vec<FieldPat<'tcx>> {
@@ -629,11 +628,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             .collect()
     }
 
-    fn lower_patterns(&mut self, pats: &'tcx [P<hir::Pat>]) -> Vec<Pat<'tcx>> {
+    fn lower_patterns(&mut self, pats: &'tcx [&'tcx hir::Pat<'tcx>]) -> Vec<Pat<'tcx>> {
         pats.iter().map(|p| self.lower_pattern(p)).collect()
     }
 
-    fn lower_opt_pattern(&mut self, pat: &'tcx Option<P<hir::Pat>>) -> Option<Pat<'tcx>> {
+    fn lower_opt_pattern(&mut self, pat: &'tcx Option<&'tcx hir::Pat<'tcx>>) -> Option<Pat<'tcx>> {
         pat.as_ref().map(|p| self.lower_pattern(p))
     }
 
@@ -641,9 +640,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         &mut self,
         span: Span,
         ty: Ty<'tcx>,
-        prefix: &'tcx [P<hir::Pat>],
-        slice: &'tcx Option<P<hir::Pat>>,
-        suffix: &'tcx [P<hir::Pat>],
+        prefix: &'tcx [&'tcx hir::Pat<'tcx>],
+        slice: &'tcx Option<&'tcx hir::Pat<'tcx>>,
+        suffix: &'tcx [&'tcx hir::Pat<'tcx>],
     ) -> PatKind<'tcx> {
         let prefix = self.lower_patterns(prefix);
         let slice = self.lower_opt_pattern(slice);
@@ -795,7 +794,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
     /// The special case for negation exists to allow things like `-128_i8`
     /// which would overflow if we tried to evaluate `128_i8` and then negate
     /// afterwards.
-    fn lower_lit(&mut self, expr: &'tcx hir::Expr) -> PatKind<'tcx> {
+    fn lower_lit(&mut self, expr: &'tcx hir::Expr<'tcx>) -> PatKind<'tcx> {
         match expr.kind {
             hir::ExprKind::Lit(ref lit) => {
                 let ty = self.tables.expr_ty(expr);
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index 715ae1ce01e..8b8f1b6f670 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -479,7 +479,7 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'a> {
         hir::intravisit::NestedVisitorMap::None
     }
 
-    fn visit_block(&mut self, block: &'tcx hir::Block) {
+    fn visit_block(&mut self, block: &'tcx hir::Block<'tcx>) {
         hir::intravisit::walk_block(self, block);
 
         if let hir::UnsafeBlock(hir::UserProvided) = block.rules {
diff --git a/src/librustc_passes/check_const.rs b/src/librustc_passes/check_const.rs
index a0aead98911..fbfe2135012 100644
--- a/src/librustc_passes/check_const.rs
+++ b/src/librustc_passes/check_const.rs
@@ -214,7 +214,7 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
         self.recurse_into(kind, |this| hir::intravisit::walk_body(this, body));
     }
 
-    fn visit_pat(&mut self, p: &'tcx hir::Pat) {
+    fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
         if self.const_kind.is_some() {
             if let hir::PatKind::Or { .. } = p.kind {
                 self.const_check_violated(NonConstExpr::OrPattern, p.span);
@@ -223,7 +223,7 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
         hir::intravisit::walk_pat(self, p)
     }
 
-    fn visit_expr(&mut self, e: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
         match &e.kind {
             // Skip the following checks if we are not currently in a const context.
             _ if self.const_kind.is_none() => {}
diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs
index ce1b68c967c..a13c9aff70a 100644
--- a/src/librustc_passes/dead.rs
+++ b/src/librustc_passes/dead.rs
@@ -115,7 +115,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
         }
     }
 
-    fn handle_field_access(&mut self, lhs: &hir::Expr, hir_id: hir::HirId) {
+    fn handle_field_access(&mut self, lhs: &hir::Expr<'_>, hir_id: hir::HirId) {
         match self.tables.expr_ty_adjusted(lhs).kind {
             ty::Adt(def, _) => {
                 let index = self.tcx.field_index(hir_id, self.tables);
@@ -126,7 +126,12 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
         }
     }
 
-    fn handle_field_pattern_match(&mut self, lhs: &hir::Pat, res: Res, pats: &[hir::FieldPat]) {
+    fn handle_field_pattern_match(
+        &mut self,
+        lhs: &hir::Pat<'_>,
+        res: Res,
+        pats: &[hir::FieldPat<'_>],
+    ) {
         let variant = match self.tables.node_type(lhs.hir_id).kind {
             ty::Adt(adt, _) => adt.variant_of_res(res),
             _ => span_bug!(lhs.span, "non-ADT in struct pattern"),
@@ -197,7 +202,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
         self.inherited_pub_visibility = had_inherited_pub_visibility;
     }
 
-    fn mark_as_used_if_union(&mut self, adt: &ty::AdtDef, fields: &hir::HirVec<hir::Field>) {
+    fn mark_as_used_if_union(&mut self, adt: &ty::AdtDef, fields: &[hir::Field<'_>]) {
         if adt.is_union() && adt.non_enum_variant().fields.len() > 1 && adt.did.is_local() {
             for field in fields {
                 let index = self.tcx.field_index(field.hir_id, self.tables);
@@ -239,7 +244,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
         intravisit::walk_struct_def(self, def);
     }
 
-    fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         match expr.kind {
             hir::ExprKind::Path(ref qpath @ hir::QPath::TypeRelative(..)) => {
                 let res = self.tables.qpath_res(qpath, expr.hir_id);
@@ -262,7 +267,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
         intravisit::walk_expr(self, expr);
     }
 
-    fn visit_arm(&mut self, arm: &'tcx hir::Arm) {
+    fn visit_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) {
         // Inside the body, ignore constructions of variants
         // necessary for the pattern to match. Those construction sites
         // can't be reached unless the variant is constructed elsewhere.
@@ -272,7 +277,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
         self.ignore_variant_stack.truncate(len);
     }
 
-    fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
+    fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) {
         match pat.kind {
             PatKind::Struct(ref path, ref fields, _) => {
                 let res = self.tables.qpath_res(path, pat.hir_id);
diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs
index fc06538e94a..5ec1d458a96 100644
--- a/src/librustc_passes/hir_stats.rs
+++ b/src/librustc_passes/hir_stats.rs
@@ -86,7 +86,7 @@ impl<'k> StatCollector<'k> {
 }
 
 impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
-    fn visit_param(&mut self, param: &'v hir::Param) {
+    fn visit_param(&mut self, param: &'v hir::Param<'v>) {
         self.record("Param", Id::Node(param.hir_id), param);
         hir_visit::walk_param(self, param)
     }
@@ -130,32 +130,32 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
         hir_visit::walk_foreign_item(self, i)
     }
 
-    fn visit_local(&mut self, l: &'v hir::Local) {
+    fn visit_local(&mut self, l: &'v hir::Local<'v>) {
         self.record("Local", Id::Node(l.hir_id), l);
         hir_visit::walk_local(self, l)
     }
 
-    fn visit_block(&mut self, b: &'v hir::Block) {
+    fn visit_block(&mut self, b: &'v hir::Block<'v>) {
         self.record("Block", Id::Node(b.hir_id), b);
         hir_visit::walk_block(self, b)
     }
 
-    fn visit_stmt(&mut self, s: &'v hir::Stmt) {
+    fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) {
         self.record("Stmt", Id::Node(s.hir_id), s);
         hir_visit::walk_stmt(self, s)
     }
 
-    fn visit_arm(&mut self, a: &'v hir::Arm) {
+    fn visit_arm(&mut self, a: &'v hir::Arm<'v>) {
         self.record("Arm", Id::Node(a.hir_id), a);
         hir_visit::walk_arm(self, a)
     }
 
-    fn visit_pat(&mut self, p: &'v hir::Pat) {
+    fn visit_pat(&mut self, p: &'v hir::Pat<'v>) {
         self.record("Pat", Id::Node(p.hir_id), p);
         hir_visit::walk_pat(self, p)
     }
 
-    fn visit_expr(&mut self, ex: &'v hir::Expr) {
+    fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
         self.record("Expr", Id::Node(ex.hir_id), ex);
         hir_visit::walk_expr(self, ex)
     }
diff --git a/src/librustc_passes/intrinsicck.rs b/src/librustc_passes/intrinsicck.rs
index de74877b7dd..92903e95a0d 100644
--- a/src/librustc_passes/intrinsicck.rs
+++ b/src/librustc_passes/intrinsicck.rs
@@ -142,7 +142,7 @@ impl Visitor<'tcx> for ExprVisitor<'tcx> {
         NestedVisitorMap::None
     }
 
-    fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         let res = if let hir::ExprKind::Path(ref qpath) = expr.kind {
             self.tables.qpath_res(qpath, expr.hir_id)
         } else {
diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs
index 1a8abeb7abc..ea4479ef5ce 100644
--- a/src/librustc_passes/liveness.rs
+++ b/src/librustc_passes/liveness.rs
@@ -100,7 +100,6 @@ use rustc::hir;
 use rustc::hir::def::*;
 use rustc::hir::def_id::DefId;
 use rustc::hir::intravisit::{self, FnKind, NestedVisitorMap, Visitor};
-use rustc::hir::ptr::P;
 use rustc::hir::Node;
 use rustc::hir::{Expr, HirId};
 use rustc::lint;
@@ -171,13 +170,13 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
         visit_fn(self, fk, fd, b, s, id);
     }
 
-    fn visit_local(&mut self, l: &'tcx hir::Local) {
+    fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
         visit_local(self, l);
     }
-    fn visit_expr(&mut self, ex: &'tcx Expr) {
+    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
         visit_expr(self, ex);
     }
-    fn visit_arm(&mut self, a: &'tcx hir::Arm) {
+    fn visit_arm(&mut self, a: &'tcx hir::Arm<'tcx>) {
         visit_arm(self, a);
     }
 }
@@ -406,7 +405,7 @@ fn visit_fn<'tcx>(
     lsets.warn_about_unused_args(body, entry_ln);
 }
 
-fn add_from_pat(ir: &mut IrMaps<'_>, pat: &P<hir::Pat>) {
+fn add_from_pat(ir: &mut IrMaps<'_>, pat: &hir::Pat<'_>) {
     // For struct patterns, take note of which fields used shorthand
     // (`x` rather than `x: x`).
     let mut shorthand_field_ids = HirIdSet::default();
@@ -447,17 +446,17 @@ fn add_from_pat(ir: &mut IrMaps<'_>, pat: &P<hir::Pat>) {
     });
 }
 
-fn visit_local<'tcx>(ir: &mut IrMaps<'tcx>, local: &'tcx hir::Local) {
+fn visit_local<'tcx>(ir: &mut IrMaps<'tcx>, local: &'tcx hir::Local<'tcx>) {
     add_from_pat(ir, &local.pat);
     intravisit::walk_local(ir, local);
 }
 
-fn visit_arm<'tcx>(ir: &mut IrMaps<'tcx>, arm: &'tcx hir::Arm) {
+fn visit_arm<'tcx>(ir: &mut IrMaps<'tcx>, arm: &'tcx hir::Arm<'tcx>) {
     add_from_pat(ir, &arm.pat);
     intravisit::walk_arm(ir, arm);
 }
 
-fn visit_expr<'tcx>(ir: &mut IrMaps<'tcx>, expr: &'tcx Expr) {
+fn visit_expr<'tcx>(ir: &mut IrMaps<'tcx>, expr: &'tcx Expr<'tcx>) {
     match expr.kind {
         // live nodes required for uses or definitions of variables:
         hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => {
@@ -714,7 +713,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         self.ir.variable(hir_id, span)
     }
 
-    fn define_bindings_in_pat(&mut self, pat: &hir::Pat, mut succ: LiveNode) -> LiveNode {
+    fn define_bindings_in_pat(&mut self, pat: &hir::Pat<'_>, mut succ: LiveNode) -> LiveNode {
         // In an or-pattern, only consider the first pattern; any later patterns
         // must have the same bindings, and we also consider the first pattern
         // to be the "authoritative" set of ids.
@@ -891,7 +890,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         self.rwu_table.assign_unpacked(idx, rwu);
     }
 
-    fn compute(&mut self, body: &hir::Expr) -> LiveNode {
+    fn compute(&mut self, body: &hir::Expr<'_>) -> LiveNode {
         debug!(
             "compute: using id for body, {}",
             self.ir.tcx.hir().hir_to_pretty_string(body.hir_id)
@@ -920,7 +919,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         entry_ln
     }
 
-    fn propagate_through_block(&mut self, blk: &hir::Block, succ: LiveNode) -> LiveNode {
+    fn propagate_through_block(&mut self, blk: &hir::Block<'_>, succ: LiveNode) -> LiveNode {
         if blk.targeted_by_break {
             self.break_ln.insert(blk.hir_id, succ);
         }
@@ -928,7 +927,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         blk.stmts.iter().rev().fold(succ, |succ, stmt| self.propagate_through_stmt(stmt, succ))
     }
 
-    fn propagate_through_stmt(&mut self, stmt: &hir::Stmt, succ: LiveNode) -> LiveNode {
+    fn propagate_through_stmt(&mut self, stmt: &hir::Stmt<'_>, succ: LiveNode) -> LiveNode {
         match stmt.kind {
             hir::StmtKind::Local(ref local) => {
                 // Note: we mark the variable as defined regardless of whether
@@ -955,15 +954,19 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         }
     }
 
-    fn propagate_through_exprs(&mut self, exprs: &[Expr], succ: LiveNode) -> LiveNode {
+    fn propagate_through_exprs(&mut self, exprs: &[Expr<'_>], succ: LiveNode) -> LiveNode {
         exprs.iter().rev().fold(succ, |succ, expr| self.propagate_through_expr(&expr, succ))
     }
 
-    fn propagate_through_opt_expr(&mut self, opt_expr: Option<&Expr>, succ: LiveNode) -> LiveNode {
+    fn propagate_through_opt_expr(
+        &mut self,
+        opt_expr: Option<&Expr<'_>>,
+        succ: LiveNode,
+    ) -> LiveNode {
         opt_expr.map_or(succ, |expr| self.propagate_through_expr(expr, succ))
     }
 
-    fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode) -> LiveNode {
+    fn propagate_through_expr(&mut self, expr: &Expr<'_>, succ: LiveNode) -> LiveNode {
         debug!("propagate_through_expr: {}", self.ir.tcx.hir().hir_to_pretty_string(expr.hir_id));
 
         match expr.kind {
@@ -1001,7 +1004,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             // at the label ident
             hir::ExprKind::Loop(ref blk, _, _) => self.propagate_through_loop(expr, &blk, succ),
 
-            hir::ExprKind::Match(ref e, ref arms, _) => {
+            hir::ExprKind::Match(ref e, arms, _) => {
                 //
                 //      (e)
                 //       |
@@ -1023,7 +1026,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                     let body_succ = self.propagate_through_expr(&arm.body, succ);
 
                     let guard_succ = self.propagate_through_opt_expr(
-                        arm.guard.as_ref().map(|hir::Guard::If(e)| &**e),
+                        arm.guard.as_ref().map(|hir::Guard::If(e)| *e),
                         body_succ,
                     );
                     let arm_succ = self.define_bindings_in_pat(&arm.pat, guard_succ);
@@ -1162,8 +1165,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
             hir::ExprKind::InlineAsm(ref asm) => {
                 let ia = &asm.inner;
-                let outputs = &asm.outputs_exprs;
-                let inputs = &asm.inputs_exprs;
+                let outputs = asm.outputs_exprs;
+                let inputs = asm.inputs_exprs;
                 let succ = ia.outputs.iter().zip(outputs).rev().fold(succ, |succ, (o, output)| {
                     // see comment on places
                     // in propagate_through_place_components()
@@ -1190,7 +1193,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         }
     }
 
-    fn propagate_through_place_components(&mut self, expr: &Expr, succ: LiveNode) -> LiveNode {
+    fn propagate_through_place_components(&mut self, expr: &Expr<'_>, succ: LiveNode) -> LiveNode {
         // # Places
         //
         // In general, the full flow graph structure for an
@@ -1248,7 +1251,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     }
 
     // see comment on propagate_through_place()
-    fn write_place(&mut self, expr: &Expr, succ: LiveNode, acc: u32) -> LiveNode {
+    fn write_place(&mut self, expr: &Expr<'_>, succ: LiveNode, acc: u32) -> LiveNode {
         match expr.kind {
             hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => {
                 self.access_path(expr.hir_id, path, succ, acc)
@@ -1301,8 +1304,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
     fn propagate_through_loop(
         &mut self,
-        expr: &Expr,
-        body: &hir::Block,
+        expr: &Expr<'_>,
+        body: &hir::Block<'_>,
         succ: LiveNode,
     ) -> LiveNode {
         /*
@@ -1351,7 +1354,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> {
         NestedVisitorMap::None
     }
 
-    fn visit_local(&mut self, local: &'tcx hir::Local) {
+    fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
         self.check_unused_vars_in_pat(&local.pat, None, |spans, hir_id, ln, var| {
             if local.init.is_some() {
                 self.warn_about_dead_assign(spans, hir_id, ln, var);
@@ -1361,17 +1364,17 @@ impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> {
         intravisit::walk_local(self, local);
     }
 
-    fn visit_expr(&mut self, ex: &'tcx Expr) {
+    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
         check_expr(self, ex);
     }
 
-    fn visit_arm(&mut self, arm: &'tcx hir::Arm) {
+    fn visit_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) {
         self.check_unused_vars_in_pat(&arm.pat, None, |_, _, _, _| {});
         intravisit::walk_arm(self, arm);
     }
 }
 
-fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr) {
+fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) {
     match expr.kind {
         hir::ExprKind::Assign(ref l, ..) => {
             this.check_place(&l);
@@ -1384,12 +1387,12 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr) {
         }
 
         hir::ExprKind::InlineAsm(ref asm) => {
-            for input in &asm.inputs_exprs {
+            for input in asm.inputs_exprs {
                 this.visit_expr(input);
             }
 
             // Output operands must be places
-            for (o, output) in asm.inner.outputs.iter().zip(&asm.outputs_exprs) {
+            for (o, output) in asm.inner.outputs.iter().zip(asm.outputs_exprs) {
                 if !o.is_indirect {
                     this.check_place(output);
                 }
@@ -1430,7 +1433,7 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr) {
 }
 
 impl<'tcx> Liveness<'_, 'tcx> {
-    fn check_place(&mut self, expr: &'tcx Expr) {
+    fn check_place(&mut self, expr: &'tcx Expr<'tcx>) {
         match expr.kind {
             hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => {
                 if let Res::Local(var_hid) = path.res {
@@ -1471,7 +1474,7 @@ impl<'tcx> Liveness<'_, 'tcx> {
 
     fn check_unused_vars_in_pat(
         &self,
-        pat: &hir::Pat,
+        pat: &hir::Pat<'_>,
         entry_ln: Option<LiveNode>,
         on_used_on_entry: impl Fn(Vec<Span>, HirId, LiveNode, Variable),
     ) {
diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs
index e422501e81b..463e6899c4f 100644
--- a/src/librustc_passes/loops.rs
+++ b/src/librustc_passes/loops.rs
@@ -52,7 +52,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
         self.with_context(AnonConst, |v| intravisit::walk_anon_const(v, c));
     }
 
-    fn visit_expr(&mut self, e: &'hir hir::Expr) {
+    fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
         match e.kind {
             hir::ExprKind::Loop(ref b, _, source) => {
                 self.with_context(Loop(source), |v| v.visit_block(&b));
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index cdfcb8090e6..a72b3b74cbb 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -883,7 +883,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
         self.prev_level = orig_level;
     }
 
-    fn visit_block(&mut self, b: &'tcx hir::Block) {
+    fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) {
         // Blocks can have public items, for example impls, but they always
         // start as completely private regardless of publicity of a function,
         // constant, type, field, etc., in which this block resides.
@@ -1080,9 +1080,9 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> {
         self.tables = orig_tables;
     }
 
-    fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         match expr.kind {
-            hir::ExprKind::Struct(ref qpath, ref fields, ref base) => {
+            hir::ExprKind::Struct(ref qpath, fields, ref base) => {
                 let res = self.tables.qpath_res(qpath, expr.hir_id);
                 let adt = self.tables.expr_ty(expr).ty_adt_def().unwrap();
                 let variant = adt.variant_of_res(res);
@@ -1114,9 +1114,9 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> {
         intravisit::walk_expr(self, expr);
     }
 
-    fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
+    fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) {
         match pat.kind {
-            PatKind::Struct(ref qpath, ref fields, _) => {
+            PatKind::Struct(ref qpath, fields, _) => {
                 let res = self.tables.qpath_res(qpath, pat.hir_id);
                 let adt = self.tables.pat_ty(pat).ty_adt_def().unwrap();
                 let variant = adt.variant_of_res(res);
@@ -1245,7 +1245,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
     }
 
     // Check types of expressions
-    fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         if self.check_expr_pat_type(expr.hir_id, expr.span) {
             // Do not check nested expressions if the error already happened.
             return;
@@ -1313,7 +1313,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
     }
 
     // Check types of patterns.
-    fn visit_pat(&mut self, pattern: &'tcx hir::Pat) {
+    fn visit_pat(&mut self, pattern: &'tcx hir::Pat<'tcx>) {
         if self.check_expr_pat_type(pattern.hir_id, pattern.span) {
             // Do not check nested patterns if the error already happened.
             return;
@@ -1322,7 +1322,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
         intravisit::walk_pat(self, pattern);
     }
 
-    fn visit_local(&mut self, local: &'tcx hir::Local) {
+    fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
         if let Some(ref init) = local.init {
             if self.check_expr_pat_type(init.hir_id, init.span) {
                 // Do not report duplicate errors for `let x = y`.
@@ -1459,7 +1459,7 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for ObsoleteCheckTypeForPrivatenessVisitor<'a
     }
 
     // Don't want to recurse into `[, .. expr]`.
-    fn visit_expr(&mut self, _: &hir::Expr) {}
+    fn visit_expr(&mut self, _: &hir::Expr<'_>) {}
 }
 
 impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
@@ -1708,8 +1708,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
     // expression/block context can't possibly contain exported things.
     // (Making them no-ops stops us from traversing the whole AST without
     // having to be super careful about our `walk_...` calls above.)
-    fn visit_block(&mut self, _: &'tcx hir::Block) {}
-    fn visit_expr(&mut self, _: &'tcx hir::Expr) {}
+    fn visit_block(&mut self, _: &'tcx hir::Block<'tcx>) {}
+    fn visit_expr(&mut self, _: &'tcx hir::Expr<'tcx>) {}
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index d28af783c0b..8e0f5d17b9f 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -2648,7 +2648,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     }
 
     /// Returns the `DefId` of the constant parameter that the provided expression is a path to.
-    pub fn const_param_def_id(&self, expr: &hir::Expr) -> Option<DefId> {
+    pub fn const_param_def_id(&self, expr: &hir::Expr<'_>) -> Option<DefId> {
         // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
         // currently have to be wrapped in curly brackets, so it's necessary to special-case.
         let expr = match &expr.kind {
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 8a74143de01..0d7ddd0fc48 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -10,9 +10,9 @@ use syntax_pos::Span;
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn check_match(
         &self,
-        expr: &'tcx hir::Expr,
-        discrim: &'tcx hir::Expr,
-        arms: &'tcx [hir::Arm],
+        expr: &'tcx hir::Expr<'tcx>,
+        discrim: &'tcx hir::Expr<'tcx>,
+        arms: &'tcx [hir::Arm<'tcx>],
         expected: Expectation<'tcx>,
         match_src: hir::MatchSource,
     ) -> Ty<'tcx> {
@@ -194,7 +194,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// When the previously checked expression (the scrutinee) diverges,
     /// warn the user about the match arms being unreachable.
-    fn warn_arms_when_scrutinee_diverges(&self, arms: &'tcx [hir::Arm], source: hir::MatchSource) {
+    fn warn_arms_when_scrutinee_diverges(
+        &self,
+        arms: &'tcx [hir::Arm<'tcx>],
+        source: hir::MatchSource,
+    ) {
         if self.diverges.get().is_always() {
             use hir::MatchSource::*;
             let msg = match source {
@@ -214,8 +218,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn if_fallback_coercion(
         &self,
         span: Span,
-        then_expr: &'tcx hir::Expr,
-        coercion: &mut CoerceMany<'tcx, '_, rustc::hir::Arm>,
+        then_expr: &'tcx hir::Expr<'tcx>,
+        coercion: &mut CoerceMany<'tcx, '_, rustc::hir::Arm<'tcx>>,
     ) -> bool {
         // If this `if` expr is the parent's function return expr,
         // the cause of the type coercion is the return type, point at it. (#25228)
@@ -277,8 +281,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn if_cause(
         &self,
         span: Span,
-        then_expr: &'tcx hir::Expr,
-        else_expr: &'tcx hir::Expr,
+        then_expr: &'tcx hir::Expr<'tcx>,
+        else_expr: &'tcx hir::Expr<'tcx>,
         then_ty: Ty<'tcx>,
         else_ty: Ty<'tcx>,
     ) -> ObligationCause<'tcx> {
@@ -386,8 +390,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn demand_discriminant_type(
         &self,
-        arms: &'tcx [hir::Arm],
-        discrim: &'tcx hir::Expr,
+        arms: &'tcx [hir::Arm<'tcx>],
+        discrim: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         // Not entirely obvious: if matches may create ref bindings, we want to
         // use the *precise* type of the discriminant, *not* some supertype, as
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 922e751db50..116f5ffc251 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -39,9 +39,9 @@ enum CallStep<'tcx> {
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn check_call(
         &self,
-        call_expr: &'tcx hir::Expr,
-        callee_expr: &'tcx hir::Expr,
-        arg_exprs: &'tcx [hir::Expr],
+        call_expr: &'tcx hir::Expr<'tcx>,
+        callee_expr: &'tcx hir::Expr<'tcx>,
+        arg_exprs: &'tcx [hir::Expr<'tcx>],
         expected: Expectation<'tcx>,
     ) -> Ty<'tcx> {
         let original_callee_ty = self.check_expr(callee_expr);
@@ -81,9 +81,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn try_overloaded_call_step(
         &self,
-        call_expr: &'tcx hir::Expr,
-        callee_expr: &'tcx hir::Expr,
-        arg_exprs: &'tcx [hir::Expr],
+        call_expr: &'tcx hir::Expr<'tcx>,
+        callee_expr: &'tcx hir::Expr<'tcx>,
+        arg_exprs: &'tcx [hir::Expr<'tcx>],
         autoderef: &Autoderef<'a, 'tcx>,
     ) -> Option<CallStep<'tcx>> {
         let adjusted_ty = autoderef.unambiguous_final_ty(self);
@@ -166,9 +166,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn try_overloaded_call_traits(
         &self,
-        call_expr: &hir::Expr,
+        call_expr: &hir::Expr<'_>,
         adjusted_ty: Ty<'tcx>,
-        opt_arg_exprs: Option<&'tcx [hir::Expr]>,
+        opt_arg_exprs: Option<&'tcx [hir::Expr<'tcx>]>,
     ) -> Option<(Option<Adjustment<'tcx>>, MethodCallee<'tcx>)> {
         // Try the options that are least restrictive on the caller first.
         for &(opt_trait_def_id, method_name, borrow) in &[
@@ -230,7 +230,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         err: &mut DiagnosticBuilder<'a>,
         hir_id: hir::HirId,
-        callee_node: &hir::ExprKind,
+        callee_node: &hir::ExprKind<'_>,
         callee_span: Span,
     ) {
         let hir_id = self.tcx.hir().get_parent_node(hir_id);
@@ -253,9 +253,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn confirm_builtin_call(
         &self,
-        call_expr: &'tcx hir::Expr,
+        call_expr: &'tcx hir::Expr<'tcx>,
         callee_ty: Ty<'tcx>,
-        arg_exprs: &'tcx [hir::Expr],
+        arg_exprs: &'tcx [hir::Expr<'tcx>],
         expected: Expectation<'tcx>,
     ) -> Ty<'tcx> {
         let (fn_sig, def_span) = match callee_ty.kind {
@@ -403,8 +403,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn confirm_deferred_closure_call(
         &self,
-        call_expr: &'tcx hir::Expr,
-        arg_exprs: &'tcx [hir::Expr],
+        call_expr: &'tcx hir::Expr<'tcx>,
+        arg_exprs: &'tcx [hir::Expr<'tcx>],
         expected: Expectation<'tcx>,
         fn_sig: ty::FnSig<'tcx>,
     ) -> Ty<'tcx> {
@@ -436,8 +436,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn confirm_overloaded_call(
         &self,
-        call_expr: &'tcx hir::Expr,
-        arg_exprs: &'tcx [hir::Expr],
+        call_expr: &'tcx hir::Expr<'tcx>,
+        arg_exprs: &'tcx [hir::Expr<'tcx>],
         expected: Expectation<'tcx>,
         method_callee: MethodCallee<'tcx>,
     ) -> Ty<'tcx> {
@@ -457,8 +457,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
 #[derive(Debug)]
 pub struct DeferredCallResolution<'tcx> {
-    call_expr: &'tcx hir::Expr,
-    callee_expr: &'tcx hir::Expr,
+    call_expr: &'tcx hir::Expr<'tcx>,
+    callee_expr: &'tcx hir::Expr<'tcx>,
     adjusted_ty: Ty<'tcx>,
     adjustments: Vec<Adjustment<'tcx>>,
     fn_sig: ty::FnSig<'tcx>,
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 23349a4e88d..f82bb1a751f 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -51,7 +51,7 @@ use rustc_error_codes::*;
 /// Reifies a cast check to be checked once we have full type information for
 /// a function context.
 pub struct CastCheck<'tcx> {
-    expr: &'tcx hir::Expr,
+    expr: &'tcx hir::Expr<'tcx>,
     expr_ty: Ty<'tcx>,
     cast_ty: Ty<'tcx>,
     cast_span: Span,
@@ -193,7 +193,7 @@ fn make_invalid_casting_error<'a, 'tcx>(
 impl<'a, 'tcx> CastCheck<'tcx> {
     pub fn new(
         fcx: &FnCtxt<'a, 'tcx>,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         expr_ty: Ty<'tcx>,
         cast_ty: Ty<'tcx>,
         cast_span: Span,
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 55bfa23a815..feb904ee71c 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -35,7 +35,7 @@ struct ClosureSignatures<'tcx> {
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn check_expr_closure(
         &self,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         _capture: hir::CaptureBy,
         decl: &'tcx hir::FnDecl,
         body_id: hir::BodyId,
@@ -57,7 +57,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_closure(
         &self,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         opt_kind: Option<ty::ClosureKind>,
         decl: &'tcx hir::FnDecl,
         body: &'tcx hir::Body<'tcx>,
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 7daa489374f..1df6a495343 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -805,7 +805,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// The expressions *must not* have any pre-existing adjustments.
     pub fn try_coerce(
         &self,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         expr_ty: Ty<'tcx>,
         target: Ty<'tcx>,
         allow_two_phase: AllowTwoPhase,
@@ -844,7 +844,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         cause: &ObligationCause<'tcx>,
         exprs: &[E],
         prev_ty: Ty<'tcx>,
-        new: &hir::Expr,
+        new: &hir::Expr<'_>,
         new_ty: Ty<'tcx>,
     ) -> RelateResult<'tcx, Ty<'tcx>>
     where
@@ -1020,10 +1020,10 @@ pub struct CoerceMany<'tcx, 'exprs, E: AsCoercionSite> {
 
 /// The type of a `CoerceMany` that is storing up the expressions into
 /// a buffer. We use this in `check/mod.rs` for things like `break`.
-pub type DynamicCoerceMany<'tcx> = CoerceMany<'tcx, 'tcx, P<hir::Expr>>;
+pub type DynamicCoerceMany<'tcx> = CoerceMany<'tcx, 'tcx, &'tcx hir::Expr<'tcx>>;
 
 enum Expressions<'tcx, 'exprs, E: AsCoercionSite> {
-    Dynamic(Vec<&'tcx hir::Expr>),
+    Dynamic(Vec<&'tcx hir::Expr<'tcx>>),
     UpFront(&'exprs [E]),
 }
 
@@ -1077,7 +1077,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
         &mut self,
         fcx: &FnCtxt<'a, 'tcx>,
         cause: &ObligationCause<'tcx>,
-        expression: &'tcx hir::Expr,
+        expression: &'tcx hir::Expr<'tcx>,
         expression_ty: Ty<'tcx>,
     ) {
         self.coerce_inner(fcx, cause, Some(expression), expression_ty, None, false)
@@ -1119,7 +1119,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
         &mut self,
         fcx: &FnCtxt<'a, 'tcx>,
         cause: &ObligationCause<'tcx>,
-        expression: Option<&'tcx hir::Expr>,
+        expression: Option<&'tcx hir::Expr<'tcx>>,
         mut expression_ty: Ty<'tcx>,
         augment_error: Option<&mut dyn FnMut(&mut DiagnosticBuilder<'_>)>,
         label_expression_as_expected: bool,
@@ -1298,7 +1298,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
         ty_err: TypeError<'tcx>,
         fcx: &FnCtxt<'a, 'tcx>,
         id: hir::HirId,
-        expression: Option<(&'tcx hir::Expr, hir::HirId)>,
+        expression: Option<(&'tcx hir::Expr<'tcx>, hir::HirId)>,
     ) -> DiagnosticBuilder<'a> {
         let mut err = fcx.report_mismatched_types(cause, expected, found, ty_err);
 
@@ -1368,17 +1368,17 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
 /// Something that can be converted into an expression to which we can
 /// apply a coercion.
 pub trait AsCoercionSite {
-    fn as_coercion_site(&self) -> &hir::Expr;
+    fn as_coercion_site(&self) -> &hir::Expr<'_>;
 }
 
-impl AsCoercionSite for hir::Expr {
-    fn as_coercion_site(&self) -> &hir::Expr {
+impl AsCoercionSite for hir::Expr<'_> {
+    fn as_coercion_site(&self) -> &hir::Expr<'_> {
         self
     }
 }
 
-impl AsCoercionSite for P<hir::Expr> {
-    fn as_coercion_site(&self) -> &hir::Expr {
+impl AsCoercionSite for P<hir::Expr<'_>> {
+    fn as_coercion_site(&self) -> &hir::Expr<'_> {
         self
     }
 }
@@ -1387,19 +1387,19 @@ impl<'a, T> AsCoercionSite for &'a T
 where
     T: AsCoercionSite,
 {
-    fn as_coercion_site(&self) -> &hir::Expr {
+    fn as_coercion_site(&self) -> &hir::Expr<'_> {
         (**self).as_coercion_site()
     }
 }
 
 impl AsCoercionSite for ! {
-    fn as_coercion_site(&self) -> &hir::Expr {
+    fn as_coercion_site(&self) -> &hir::Expr<'_> {
         unreachable!()
     }
 }
 
-impl AsCoercionSite for hir::Arm {
-    fn as_coercion_site(&self) -> &hir::Expr {
+impl AsCoercionSite for hir::Arm<'_> {
+    fn as_coercion_site(&self) -> &hir::Expr<'_> {
         &self.body
     }
 }
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 9a14b75ca2f..68f2943e9e1 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -16,7 +16,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn emit_coerce_suggestions(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         expr_ty: Ty<'tcx>,
         expected: Ty<'tcx>,
     ) {
@@ -110,7 +110,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     pub fn demand_coerce(
         &self,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         checked_ty: Ty<'tcx>,
         expected: Ty<'tcx>,
         allow_two_phase: AllowTwoPhase,
@@ -129,7 +129,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     // diverges flag is currently "always".
     pub fn demand_coerce_diag(
         &self,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         checked_ty: Ty<'tcx>,
         expected: Ty<'tcx>,
         allow_two_phase: AllowTwoPhase,
@@ -157,7 +157,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         (expected, Some(err))
     }
 
-    fn annotate_expected_due_to_let_ty(&self, err: &mut DiagnosticBuilder<'_>, expr: &hir::Expr) {
+    fn annotate_expected_due_to_let_ty(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        expr: &hir::Expr<'_>,
+    ) {
         let parent = self.tcx.hir().get_parent_node(expr.hir_id);
         if let Some(hir::Node::Local(hir::Local { ty: Some(ty), init: Some(init), .. })) =
             self.tcx.hir().find(parent)
@@ -170,7 +174,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Returns whether the expected type is `bool` and the expression is `x = y`.
-    pub fn is_assign_to_bool(&self, expr: &hir::Expr, expected: Ty<'tcx>) -> bool {
+    pub fn is_assign_to_bool(&self, expr: &hir::Expr<'_>, expected: Ty<'tcx>) -> bool {
         if let hir::ExprKind::Assign(..) = expr.kind {
             return expected == self.tcx.types.bool;
         }
@@ -182,7 +186,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn suggest_compatible_variants(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         expected: Ty<'tcx>,
         expr_ty: Ty<'tcx>,
     ) {
@@ -282,7 +286,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// ```
     /// opt.map(|param| { takes_ref(param) });
     /// ```
-    fn can_use_as_ref(&self, expr: &hir::Expr) -> Option<(Span, &'static str, String)> {
+    fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Span, &'static str, String)> {
         let path = match expr.kind {
             hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => path,
             _ => return None,
@@ -352,7 +356,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             if let Node::Expr(hir::Expr { kind: hir::ExprKind::Struct(_, fields, ..), .. }) = parent
             {
                 if let Ok(src) = cm.span_to_snippet(sp) {
-                    for field in fields {
+                    for field in *fields {
                         if field.ident.as_str() == src && field.is_shorthand {
                             return true;
                         }
@@ -381,7 +385,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// `&mut`!".
     pub fn check_ref(
         &self,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         checked_ty: Ty<'tcx>,
         expected: Ty<'tcx>,
     ) -> Option<(Span, &'static str, String)> {
@@ -605,7 +609,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn check_for_cast(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         checked_ty: Ty<'tcx>,
         expected_ty: Ty<'tcx>,
     ) -> bool {
@@ -635,7 +639,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         })) = self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.hir_id))
         {
             // `expr` is a literal field for a struct, only suggest if appropriate
-            for field in fields {
+            for field in *fields {
                 if field.expr.hir_id == expr.hir_id && field.is_shorthand {
                     // This is a field literal
                     prefix = format!("{}: ", field.ident);
@@ -728,7 +732,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 expected_ty,
                 if needs_paren { ")" } else { "" },
             );
-            let literal_is_ty_suffixed = |expr: &hir::Expr| {
+            let literal_is_ty_suffixed = |expr: &hir::Expr<'_>| {
                 if let hir::ExprKind::Lit(lit) = &expr.kind {
                     lit.node.is_suffixed()
                 } else {
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index e862971c9e2..4da4ce7680b 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -21,7 +21,6 @@ use errors::{pluralize, Applicability, DiagnosticBuilder, DiagnosticId};
 use rustc::hir;
 use rustc::hir::def::{CtorKind, DefKind, Res};
 use rustc::hir::def_id::DefId;
-use rustc::hir::ptr::P;
 use rustc::hir::{ExprKind, QPath};
 use rustc::infer;
 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -43,14 +42,14 @@ use rustc_error_codes::*;
 use std::fmt::Display;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    fn check_expr_eq_type(&self, expr: &'tcx hir::Expr, expected: Ty<'tcx>) {
+    fn check_expr_eq_type(&self, expr: &'tcx hir::Expr<'tcx>, expected: Ty<'tcx>) {
         let ty = self.check_expr_with_hint(expr, expected);
         self.demand_eqtype(expr.span, expected, ty);
     }
 
     pub fn check_expr_has_type_or_error(
         &self,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         expected: Ty<'tcx>,
         extend_err: impl Fn(&mut DiagnosticBuilder<'_>),
     ) -> Ty<'tcx> {
@@ -59,7 +58,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_expr_meets_expectation_or_error(
         &self,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         expected: Expectation<'tcx>,
         extend_err: impl Fn(&mut DiagnosticBuilder<'_>),
     ) -> Ty<'tcx> {
@@ -96,7 +95,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     pub(super) fn check_expr_coercable_to_type(
         &self,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         expected: Ty<'tcx>,
     ) -> Ty<'tcx> {
         let ty = self.check_expr_with_hint(expr, expected);
@@ -106,7 +105,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     pub(super) fn check_expr_with_hint(
         &self,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         expected: Ty<'tcx>,
     ) -> Ty<'tcx> {
         self.check_expr_with_expectation(expr, ExpectHasType(expected))
@@ -114,17 +113,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     pub(super) fn check_expr_with_expectation(
         &self,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         expected: Expectation<'tcx>,
     ) -> Ty<'tcx> {
         self.check_expr_with_expectation_and_needs(expr, expected, Needs::None)
     }
 
-    pub(super) fn check_expr(&self, expr: &'tcx hir::Expr) -> Ty<'tcx> {
+    pub(super) fn check_expr(&self, expr: &'tcx hir::Expr<'tcx>) -> Ty<'tcx> {
         self.check_expr_with_expectation(expr, NoExpectation)
     }
 
-    pub(super) fn check_expr_with_needs(&self, expr: &'tcx hir::Expr, needs: Needs) -> Ty<'tcx> {
+    pub(super) fn check_expr_with_needs(
+        &self,
+        expr: &'tcx hir::Expr<'tcx>,
+        needs: Needs,
+    ) -> Ty<'tcx> {
         self.check_expr_with_expectation_and_needs(expr, NoExpectation, needs)
     }
 
@@ -140,7 +143,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// that when err needs to be handled differently.
     fn check_expr_with_expectation_and_needs(
         &self,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         expected: Expectation<'tcx>,
         needs: Needs,
     ) -> Ty<'tcx> {
@@ -208,7 +211,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_expr_kind(
         &self,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         expected: Expectation<'tcx>,
         needs: Needs,
     ) -> Ty<'tcx> {
@@ -274,7 +277,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.check_expr_repeat(element, count, expected, expr)
             }
             ExprKind::Tup(ref elts) => self.check_expr_tuple(elts, expected, expr),
-            ExprKind::Struct(ref qpath, ref fields, ref base_expr) => {
+            ExprKind::Struct(ref qpath, fields, ref base_expr) => {
                 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
             }
             ExprKind::Field(ref base, field) => self.check_field(expr, needs, &base, field),
@@ -284,7 +287,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn check_expr_box(&self, expr: &'tcx hir::Expr, expected: Expectation<'tcx>) -> Ty<'tcx> {
+    fn check_expr_box(&self, expr: &'tcx hir::Expr<'tcx>, expected: Expectation<'tcx>) -> Ty<'tcx> {
         let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| match ty.kind {
             ty::Adt(def, _) if def.is_box() => Expectation::rvalue_hint(self, ty.boxed_ty()),
             _ => NoExpectation,
@@ -296,10 +299,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_expr_unary(
         &self,
         unop: hir::UnOp,
-        oprnd: &'tcx hir::Expr,
+        oprnd: &'tcx hir::Expr<'tcx>,
         expected: Expectation<'tcx>,
         needs: Needs,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
         let expected_inner = match unop {
@@ -382,9 +385,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         kind: hir::BorrowKind,
         mutbl: hir::Mutability,
-        oprnd: &'tcx hir::Expr,
+        oprnd: &'tcx hir::Expr<'tcx>,
         expected: Expectation<'tcx>,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
             match ty.kind {
@@ -437,7 +440,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// * Contains a dereference
     /// Note that the adjustments for the children of `expr` should already
     /// have been resolved.
-    fn check_named_place_expr(&self, oprnd: &'tcx hir::Expr) {
+    fn check_named_place_expr(&self, oprnd: &'tcx hir::Expr<'tcx>) {
         let is_named = oprnd.is_place_expr(|base| {
             // Allow raw borrows if there are any deref adjustments.
             //
@@ -466,7 +469,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn check_expr_path(&self, qpath: &hir::QPath, expr: &'tcx hir::Expr) -> Ty<'tcx> {
+    fn check_expr_path(&self, qpath: &hir::QPath, expr: &'tcx hir::Expr<'tcx>) -> Ty<'tcx> {
         let tcx = self.tcx;
         let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id, expr.span);
         let ty = match res {
@@ -538,8 +541,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_expr_break(
         &self,
         destination: hir::Destination,
-        expr_opt: Option<&'tcx hir::Expr>,
-        expr: &'tcx hir::Expr,
+        expr_opt: Option<&'tcx hir::Expr<'tcx>>,
+        expr: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
         if let Ok(target_id) = destination.target_id {
@@ -669,8 +672,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_expr_return(
         &self,
-        expr_opt: Option<&'tcx hir::Expr>,
-        expr: &'tcx hir::Expr,
+        expr_opt: Option<&'tcx hir::Expr<'tcx>>,
+        expr: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         if self.ret_coercion.is_none() {
             struct_span_err!(
@@ -710,7 +713,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.tcx.types.never
     }
 
-    pub(super) fn check_return_expr(&self, return_expr: &'tcx hir::Expr) {
+    pub(super) fn check_return_expr(&self, return_expr: &'tcx hir::Expr<'tcx>) {
         let ret_coercion = self.ret_coercion.as_ref().unwrap_or_else(|| {
             span_bug!(return_expr.span, "check_return_expr called outside fn body")
         });
@@ -725,7 +728,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         );
     }
 
-    fn is_destructuring_place_expr(&self, expr: &'tcx hir::Expr) -> bool {
+    fn is_destructuring_place_expr(&self, expr: &'tcx hir::Expr<'tcx>) -> bool {
         match &expr.kind {
             ExprKind::Array(comps) | ExprKind::Tup(comps) => {
                 comps.iter().all(|e| self.is_destructuring_place_expr(e))
@@ -740,7 +743,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     pub(crate) fn check_lhs_assignable(
         &self,
-        lhs: &'tcx hir::Expr,
+        lhs: &'tcx hir::Expr<'tcx>,
         err_code: &'static str,
         expr_span: &Span,
     ) {
@@ -763,10 +766,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// The expected type is `()` and is passsed to the function for the purposes of diagnostics.
     fn check_expr_assign(
         &self,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         expected: Expectation<'tcx>,
-        lhs: &'tcx hir::Expr,
-        rhs: &'tcx hir::Expr,
+        lhs: &'tcx hir::Expr<'tcx>,
+        rhs: &'tcx hir::Expr<'tcx>,
         span: &Span,
     ) -> Ty<'tcx> {
         let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
@@ -804,10 +807,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_expr_loop(
         &self,
-        body: &'tcx hir::Block,
+        body: &'tcx hir::Block<'tcx>,
         source: hir::LoopSource,
         expected: Expectation<'tcx>,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         let coerce = match source {
             // you can only use break with a value from a normal `loop { }`
@@ -849,10 +852,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Checks a method call.
     fn check_method_call(
         &self,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         segment: &hir::PathSegment,
         span: Span,
-        args: &'tcx [hir::Expr],
+        args: &'tcx [hir::Expr<'tcx>],
         expected: Expectation<'tcx>,
         needs: Needs,
     ) -> Ty<'tcx> {
@@ -892,7 +895,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         segment: &hir::PathSegment,
         span: Span,
-        args: &'tcx [hir::Expr],
+        args: &'tcx [hir::Expr<'tcx>],
         rcvr_t: Ty<'tcx>,
         error: MethodError<'tcx>,
     ) {
@@ -937,9 +940,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_expr_cast(
         &self,
-        e: &'tcx hir::Expr,
+        e: &'tcx hir::Expr<'tcx>,
         t: &'tcx hir::Ty,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         // Find the type of `e`. Supply hints based on the type we are casting to,
         // if appropriate.
@@ -966,9 +969,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_expr_array(
         &self,
-        args: &'tcx [hir::Expr],
+        args: &'tcx [hir::Expr<'tcx>],
         expected: Expectation<'tcx>,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         let uty = expected.to_option(self).and_then(|uty| match uty.kind {
             ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
@@ -1001,10 +1004,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_expr_repeat(
         &self,
-        element: &'tcx hir::Expr,
+        element: &'tcx hir::Expr<'tcx>,
         count: &'tcx hir::AnonConst,
         expected: Expectation<'tcx>,
-        _expr: &'tcx hir::Expr,
+        _expr: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
         let count_def_id = tcx.hir().local_def_id(count.hir_id);
@@ -1048,9 +1051,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_expr_tuple(
         &self,
-        elts: &'tcx [hir::Expr],
+        elts: &'tcx [hir::Expr<'tcx>],
         expected: Expectation<'tcx>,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         let flds = expected.only_has_type(self).and_then(|ty| {
             let ty = self.resolve_vars_with_obligations(ty);
@@ -1082,11 +1085,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_expr_struct(
         &self,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         expected: Expectation<'tcx>,
         qpath: &QPath,
-        fields: &'tcx [hir::Field],
-        base_expr: &'tcx Option<P<hir::Expr>>,
+        fields: &'tcx [hir::Field<'tcx>],
+        base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
     ) -> Ty<'tcx> {
         // Find the relevant variant
         let (variant, adt_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, expr.hir_id)
@@ -1170,7 +1173,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr_id: hir::HirId,
         span: Span,
         variant: &'tcx ty::VariantDef,
-        ast_fields: &'tcx [hir::Field],
+        ast_fields: &'tcx [hir::Field<'tcx>],
         check_completeness: bool,
     ) -> bool {
         let tcx = self.tcx;
@@ -1288,8 +1291,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_struct_fields_on_error(
         &self,
-        fields: &'tcx [hir::Field],
-        base_expr: &'tcx Option<P<hir::Expr>>,
+        fields: &'tcx [hir::Field<'tcx>],
+        base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
     ) {
         for field in fields {
             self.check_expr(&field.expr);
@@ -1303,8 +1306,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         ty: Ty<'tcx>,
         variant: &'tcx ty::VariantDef,
-        field: &hir::Field,
-        skip_fields: &[hir::Field],
+        field: &hir::Field<'_>,
+        skip_fields: &[hir::Field<'_>],
         kind_name: &str,
         ty_span: Span,
     ) {
@@ -1441,9 +1444,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     // Check field access expressions
     fn check_field(
         &self,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         needs: Needs,
-        base: &'tcx hir::Expr,
+        base: &'tcx hir::Expr<'tcx>,
         field: ast::Ident,
     ) -> Ty<'tcx> {
         let expr_t = self.check_expr_with_needs(base, needs);
@@ -1522,8 +1525,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn ban_nonexisting_field(
         &self,
         field: ast::Ident,
-        base: &'tcx hir::Expr,
-        expr: &'tcx hir::Expr,
+        base: &'tcx hir::Expr<'tcx>,
+        expr: &'tcx hir::Expr<'tcx>,
         expr_t: Ty<'tcx>,
     ) {
         let mut err = self.no_such_field_err(field.span, field, expr_t);
@@ -1557,7 +1560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn ban_private_field_access(
         &self,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         expr_t: Ty<'tcx>,
         field: ast::Ident,
         base_did: DefId,
@@ -1590,7 +1593,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err.emit();
     }
 
-    fn ban_take_value_of_method(&self, expr: &hir::Expr, expr_t: Ty<'tcx>, field: ast::Ident) {
+    fn ban_take_value_of_method(&self, expr: &hir::Expr<'_>, expr_t: Ty<'tcx>, field: ast::Ident) {
         let mut err = type_error_struct!(
             self.tcx().sess,
             field.span,
@@ -1664,8 +1667,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn maybe_suggest_array_indexing(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        expr: &hir::Expr,
-        base: &hir::Expr,
+        expr: &hir::Expr<'_>,
+        base: &hir::Expr<'_>,
         field: ast::Ident,
         len: &ty::Const<'tcx>,
     ) {
@@ -1692,8 +1695,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn suggest_first_deref_field(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        expr: &hir::Expr,
-        base: &hir::Expr,
+        expr: &hir::Expr<'_>,
+        base: &hir::Expr<'_>,
         field: ast::Ident,
     ) {
         let base = self
@@ -1726,10 +1729,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_expr_index(
         &self,
-        base: &'tcx hir::Expr,
-        idx: &'tcx hir::Expr,
+        base: &'tcx hir::Expr<'tcx>,
+        idx: &'tcx hir::Expr<'tcx>,
         needs: Needs,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         let base_t = self.check_expr_with_needs(&base, needs);
         let idx_t = self.check_expr(&idx);
@@ -1790,8 +1793,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_expr_yield(
         &self,
-        value: &'tcx hir::Expr,
-        expr: &'tcx hir::Expr,
+        value: &'tcx hir::Expr<'tcx>,
+        expr: &'tcx hir::Expr<'tcx>,
         src: &'tcx hir::YieldSource,
     ) -> Ty<'tcx> {
         match self.yield_ty {
diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs
index 3fedd19b829..3069f1b1d77 100644
--- a/src/librustc_typeck/check/generator_interior.rs
+++ b/src/librustc_typeck/check/generator_interior.rs
@@ -27,7 +27,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
         &mut self,
         ty: Ty<'tcx>,
         scope: Option<region::Scope>,
-        expr: Option<&'tcx Expr>,
+        expr: Option<&'tcx Expr<'tcx>>,
         source_span: Span,
     ) {
         use syntax_pos::DUMMY_SP;
@@ -196,7 +196,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
         NestedVisitorMap::None
     }
 
-    fn visit_pat(&mut self, pat: &'tcx Pat) {
+    fn visit_pat(&mut self, pat: &'tcx Pat<'tcx>) {
         intravisit::walk_pat(self, pat);
 
         self.expr_count += 1;
@@ -208,7 +208,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
         }
     }
 
-    fn visit_expr(&mut self, expr: &'tcx Expr) {
+    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
         let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id);
 
         match &expr.kind {
@@ -227,7 +227,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
                             self.expr_count += 1;
 
                             // Record the rest of the call expression normally.
-                            for arg in args {
+                            for arg in *args {
                                 self.visit_expr(arg);
                             }
                         }
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 0b26933459f..98645b3463e 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -19,8 +19,8 @@ use std::ops::Deref;
 struct ConfirmContext<'a, 'tcx> {
     fcx: &'a FnCtxt<'a, 'tcx>,
     span: Span,
-    self_expr: &'tcx hir::Expr,
-    call_expr: &'tcx hir::Expr,
+    self_expr: &'tcx hir::Expr<'tcx>,
+    call_expr: &'tcx hir::Expr<'tcx>,
 }
 
 impl<'a, 'tcx> Deref for ConfirmContext<'a, 'tcx> {
@@ -39,8 +39,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn confirm_method(
         &self,
         span: Span,
-        self_expr: &'tcx hir::Expr,
-        call_expr: &'tcx hir::Expr,
+        self_expr: &'tcx hir::Expr<'tcx>,
+        call_expr: &'tcx hir::Expr<'tcx>,
         unadjusted_self_ty: Ty<'tcx>,
         pick: probe::Pick<'tcx>,
         segment: &hir::PathSegment,
@@ -59,8 +59,8 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
     fn new(
         fcx: &'a FnCtxt<'a, 'tcx>,
         span: Span,
-        self_expr: &'tcx hir::Expr,
-        call_expr: &'tcx hir::Expr,
+        self_expr: &'tcx hir::Expr<'tcx>,
+        call_expr: &'tcx hir::Expr<'tcx>,
     ) -> ConfirmContext<'a, 'tcx> {
         ConfirmContext { fcx, span, self_expr, call_expr }
     }
@@ -482,8 +482,8 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
     fn convert_place_op_to_mutable(
         &self,
         op: PlaceOp,
-        expr: &hir::Expr,
-        base_expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
+        base_expr: &hir::Expr<'_>,
         arg_tys: &[Ty<'tcx>],
     ) {
         debug!("convert_place_op_to_mutable({:?}, {:?}, {:?}, {:?})", op, expr, base_expr, arg_tys);
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index d0aa709069e..41fd8d46346 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -180,8 +180,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self_ty: Ty<'tcx>,
         segment: &hir::PathSegment,
         span: Span,
-        call_expr: &'tcx hir::Expr,
-        self_expr: &'tcx hir::Expr,
+        call_expr: &'tcx hir::Expr<'tcx>,
+        self_expr: &'tcx hir::Expr<'tcx>,
     ) -> Result<MethodCallee<'tcx>, MethodError<'tcx>> {
         debug!(
             "lookup(method_name={}, self_ty={:?}, call_expr={:?}, self_expr={:?})",
@@ -260,7 +260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         span: Span,
         method_name: ast::Ident,
         self_ty: Ty<'tcx>,
-        call_expr: &'tcx hir::Expr,
+        call_expr: &'tcx hir::Expr<'tcx>,
         scope: ProbeScope,
     ) -> probe::PickResult<'tcx> {
         let mode = probe::Mode::MethodCall;
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 0c61c24d23a..f19e8c9ab1c 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -72,7 +72,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         item_name: ast::Ident,
         source: SelfSource<'b>,
         error: MethodError<'tcx>,
-        args: Option<&'tcx [hir::Expr]>,
+        args: Option<&'tcx [hir::Expr<'tcx>]>,
     ) -> Option<DiagnosticBuilder<'_>> {
         let orig_span = span;
         let mut span = span;
@@ -954,7 +954,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 #[derive(Copy, Clone)]
 pub enum SelfSource<'a> {
     QPath(&'a hir::Ty),
-    MethodCall(&'a hir::Expr /* rcvr */),
+    MethodCall(&'a hir::Expr<'a> /* rcvr */),
 }
 
 #[derive(Copy, Clone)]
@@ -1131,7 +1131,7 @@ impl hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
 
 fn print_disambiguation_help(
     item_name: ast::Ident,
-    args: Option<&'tcx [hir::Expr]>,
+    args: Option<&'tcx [hir::Expr<'tcx>]>,
     err: &mut DiagnosticBuilder<'_>,
     trait_name: String,
     rcvr_ty: Ty<'_>,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 8e79cc13895..f8e494a6ccd 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -95,7 +95,6 @@ use rustc::hir::def::{CtorOf, DefKind, Res};
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
-use rustc::hir::ptr::P;
 use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath};
 use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
 use rustc::infer::error_reporting::TypeAnnotationNeeded::E0282;
@@ -390,7 +389,7 @@ impl UnsafetyState {
         UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
     }
 
-    pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
+    pub fn recurse(&mut self, blk: &hir::Block<'_>) -> UnsafetyState {
         match self.unsafety {
             // If this unsafe, then if the outer function was already marked as
             // unsafe we shouldn't attribute the unsafe'ness to the block. This
@@ -1136,7 +1135,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
     }
 
     // Add explicitly-declared locals.
-    fn visit_local(&mut self, local: &'tcx hir::Local) {
+    fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
         let local_ty = match local.ty {
             Some(ref ty) => {
                 let o_ty = self.fcx.to_ty(&ty);
@@ -1174,7 +1173,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
     }
 
     // Add pattern bindings.
-    fn visit_pat(&mut self, p: &'tcx hir::Pat) {
+    fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
         if let PatKind::Binding(_, _, ident, _) = p.kind {
             let var_ty = self.assign(p.span, p.hir_id, None);
 
@@ -2934,7 +2933,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
+    pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
         debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
 
         if adj.is_empty() {
@@ -3181,7 +3180,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Registers obligations that all types appearing in `substs` are well-formed.
-    pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr) {
+    pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
         for ty in substs.types() {
             if !ty.references_error() {
                 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
@@ -3362,8 +3361,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn lookup_indexing(
         &self,
-        expr: &hir::Expr,
-        base_expr: &'tcx hir::Expr,
+        expr: &hir::Expr<'_>,
+        base_expr: &'tcx hir::Expr<'tcx>,
         base_ty: Ty<'tcx>,
         idx_ty: Ty<'tcx>,
         needs: Needs,
@@ -3388,8 +3387,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// is implemented by `lookup_indexing`.
     fn try_index_step(
         &self,
-        expr: &hir::Expr,
-        base_expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
+        base_expr: &hir::Expr<'_>,
         autoderef: &Autoderef<'a, 'tcx>,
         needs: Needs,
         index_ty: Ty<'tcx>,
@@ -3513,9 +3512,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_method_argument_types(
         &self,
         sp: Span,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         method: Result<MethodCallee<'tcx>, ()>,
-        args_no_rcvr: &'tcx [hir::Expr],
+        args_no_rcvr: &'tcx [hir::Expr<'tcx>],
         tuple_arguments: TupleArgumentsFlag,
         expected: Expectation<'tcx>,
     ) -> Ty<'tcx> {
@@ -3641,10 +3640,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_argument_types(
         &self,
         sp: Span,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         fn_inputs: &[Ty<'tcx>],
         expected_arg_tys: &[Ty<'tcx>],
-        args: &'tcx [hir::Expr],
+        args: &'tcx [hir::Expr<'tcx>],
         c_variadic: bool,
         tuple_arguments: TupleArgumentsFlag,
         def_span: Option<Span>,
@@ -3897,7 +3896,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         errors: &mut Vec<traits::FulfillmentError<'_>>,
         final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
         call_sp: Span,
-        args: &'tcx [hir::Expr],
+        args: &'tcx [hir::Expr<'tcx>],
     ) {
         // We *do not* do this for desugared call spans to keep good diagnostics when involving
         // the `?` operator.
@@ -3951,7 +3950,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn point_at_type_arg_instead_of_call_if_possible(
         &self,
         errors: &mut Vec<traits::FulfillmentError<'_>>,
-        call_expr: &'tcx hir::Expr,
+        call_expr: &'tcx hir::Expr<'tcx>,
     ) {
         if let hir::ExprKind::Call(path, _) = &call_expr.kind {
             if let hir::ExprKind::Path(qpath) = &path.kind {
@@ -4248,8 +4247,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     pub fn check_decl_initializer(
         &self,
-        local: &'tcx hir::Local,
-        init: &'tcx hir::Expr,
+        local: &'tcx hir::Local<'tcx>,
+        init: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
         // for #42640 (default match binding modes).
@@ -4275,7 +4274,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn check_decl_local(&self, local: &'tcx hir::Local) {
+    pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
         let t = self.local_ty(local.span, local.hir_id).decl_ty;
         self.write_ty(local.hir_id, t);
 
@@ -4289,7 +4288,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.overwrite_local_ty_if_err(local, t, pat_ty);
     }
 
-    fn overwrite_local_ty_if_err(&self, local: &'tcx hir::Local, decl_ty: Ty<'tcx>, ty: Ty<'tcx>) {
+    fn overwrite_local_ty_if_err(
+        &self,
+        local: &'tcx hir::Local<'tcx>,
+        decl_ty: Ty<'tcx>,
+        ty: Ty<'tcx>,
+    ) {
         if ty.references_error() {
             // Override the types everywhere with `types.err` to avoid knock down errors.
             self.write_ty(local.hir_id, ty);
@@ -4309,7 +4313,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         );
     }
 
-    pub fn check_stmt(&self, stmt: &'tcx hir::Stmt) {
+    pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
         // Don't do all the complex logic below for `DeclItem`.
         match stmt.kind {
             hir::StmtKind::Item(..) => return,
@@ -4347,7 +4351,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.has_errors.set(self.has_errors.get() | old_has_errors);
     }
 
-    pub fn check_block_no_value(&self, blk: &'tcx hir::Block) {
+    pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
         let unit = self.tcx.mk_unit();
         let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
 
@@ -4365,7 +4369,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// if false { return 0i32; } else { 1u32 }
     /// //                               ^^^^ point at this instead of the whole `if` expression
     /// ```
-    fn get_expr_coercion_span(&self, expr: &hir::Expr) -> syntax_pos::Span {
+    fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> syntax_pos::Span {
         if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
             let arm_spans: Vec<Span> = arms
                 .iter()
@@ -4396,7 +4400,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_block_with_expected(
         &self,
-        blk: &'tcx hir::Block,
+        blk: &'tcx hir::Block<'tcx>,
         expected: Expectation<'tcx>,
     ) -> Ty<'tcx> {
         let prev = {
@@ -4426,7 +4430,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let coerce = if blk.targeted_by_break {
             CoerceMany::new(coerce_to_ty)
         } else {
-            let tail_expr: &[P<hir::Expr>] = match tail_expr {
+            let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
                 Some(e) => slice::from_ref(e),
                 None => &[],
             };
@@ -4437,7 +4441,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
 
         let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
-            for s in &blk.stmts {
+            for s in blk.stmts {
                 self.check_stmt(s);
             }
 
@@ -4588,7 +4592,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn suggest_mismatched_types_on_tail(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
         cause_span: Span,
@@ -4613,7 +4617,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn suggest_fn_call(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
     ) -> bool {
@@ -4756,7 +4760,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn suggest_ref_or_into(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
     ) {
@@ -4819,7 +4823,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn suggest_boxing_when_appropriate(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
     ) {
@@ -4864,7 +4868,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn suggest_missing_semicolon(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        expression: &'tcx hir::Expr,
+        expression: &'tcx hir::Expr<'tcx>,
         expected: Ty<'tcx>,
         cause_span: Span,
     ) {
@@ -4970,7 +4974,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn suggest_missing_await(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
     ) {
@@ -5033,7 +5037,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// with `expected_ty`. If so, it suggests removing the semicolon.
     fn consider_hint_about_removing_semicolon(
         &self,
-        blk: &'tcx hir::Block,
+        blk: &'tcx hir::Block<'tcx>,
         expected_ty: Ty<'tcx>,
         err: &mut DiagnosticBuilder<'_>,
     ) {
@@ -5047,7 +5051,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn could_remove_semicolon(&self, blk: &'tcx hir::Block, expected_ty: Ty<'tcx>) -> Option<Span> {
+    fn could_remove_semicolon(
+        &self,
+        blk: &'tcx hir::Block<'tcx>,
+        expected_ty: Ty<'tcx>,
+    ) -> Option<Span> {
         // Be helpful when the user wrote `{... expr;}` and
         // taking the `;` off is enough to fix the error.
         let last_stmt = blk.stmts.last()?;
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index c5d3aac136b..873a9b86fd6 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -17,10 +17,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Checks a `a <op>= b`
     pub fn check_binop_assign(
         &self,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         op: hir::BinOp,
-        lhs: &'tcx hir::Expr,
-        rhs: &'tcx hir::Expr,
+        lhs: &'tcx hir::Expr<'tcx>,
+        rhs: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         let (lhs_ty, rhs_ty, return_ty) =
             self.check_overloaded_binop(expr, lhs, rhs, op, IsAssign::Yes);
@@ -41,10 +41,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Checks a potentially overloaded binary operator.
     pub fn check_binop(
         &self,
-        expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
         op: hir::BinOp,
-        lhs_expr: &'tcx hir::Expr,
-        rhs_expr: &'tcx hir::Expr,
+        lhs_expr: &'tcx hir::Expr<'tcx>,
+        rhs_expr: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
 
@@ -100,9 +100,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn enforce_builtin_binop_types(
         &self,
-        lhs_expr: &'tcx hir::Expr,
+        lhs_expr: &'tcx hir::Expr<'tcx>,
         lhs_ty: Ty<'tcx>,
-        rhs_expr: &'tcx hir::Expr,
+        rhs_expr: &'tcx hir::Expr<'tcx>,
         rhs_ty: Ty<'tcx>,
         op: hir::BinOp,
     ) -> Ty<'tcx> {
@@ -137,9 +137,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_overloaded_binop(
         &self,
-        expr: &'tcx hir::Expr,
-        lhs_expr: &'tcx hir::Expr,
-        rhs_expr: &'tcx hir::Expr,
+        expr: &'tcx hir::Expr<'tcx>,
+        lhs_expr: &'tcx hir::Expr<'tcx>,
+        rhs_expr: &'tcx hir::Expr<'tcx>,
         op: hir::BinOp,
         is_assign: IsAssign,
     ) -> (Ty<'tcx>, Ty<'tcx>, Ty<'tcx>) {
@@ -561,8 +561,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// to print the normal "implementation of `std::ops::Add` might be missing" note
     fn check_str_addition(
         &self,
-        lhs_expr: &'tcx hir::Expr,
-        rhs_expr: &'tcx hir::Expr,
+        lhs_expr: &'tcx hir::Expr<'tcx>,
+        rhs_expr: &'tcx hir::Expr<'tcx>,
         lhs_ty: Ty<'tcx>,
         rhs_ty: Ty<'tcx>,
         err: &mut errors::DiagnosticBuilder<'_>,
@@ -659,7 +659,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     pub fn check_user_unop(
         &self,
-        ex: &'tcx hir::Expr,
+        ex: &'tcx hir::Expr<'tcx>,
         operand_ty: Ty<'tcx>,
         op: hir::UnOp,
     ) -> Ty<'tcx> {
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index d0f1ef7b4ec..3fb6d5227f7 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -3,7 +3,6 @@ use crate::util::nodemap::FxHashMap;
 use errors::{pluralize, Applicability, DiagnosticBuilder};
 use rustc::hir::def::{CtorKind, DefKind, Res};
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
-use rustc::hir::ptr::P;
 use rustc::hir::{self, HirId, Pat, PatKind};
 use rustc::infer;
 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -31,7 +30,12 @@ You can read more about trait objects in the Trait Objects section of the Refere
 https://doc.rust-lang.org/reference/types.html#trait-objects";
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub fn check_pat_top(&self, pat: &'tcx Pat, expected: Ty<'tcx>, discrim_span: Option<Span>) {
+    pub fn check_pat_top(
+        &self,
+        pat: &'tcx Pat<'tcx>,
+        expected: Ty<'tcx>,
+        discrim_span: Option<Span>,
+    ) {
         let def_bm = BindingMode::BindByValue(hir::Mutability::Not);
         self.check_pat(pat, expected, def_bm, discrim_span);
     }
@@ -54,7 +58,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// ```
     fn check_pat(
         &self,
-        pat: &'tcx Pat,
+        pat: &'tcx Pat<'tcx>,
         expected: Ty<'tcx>,
         def_bm: BindingMode,
         discrim_span: Option<Span>,
@@ -97,13 +101,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.check_pat_struct(pat, qpath, fields, *etc, expected, def_bm, discrim_span)
             }
             PatKind::Or(pats) => {
-                for pat in pats {
+                for pat in *pats {
                     self.check_pat(pat, expected, def_bm, discrim_span);
                 }
                 expected
             }
             PatKind::Tuple(elements, ddpos) => {
-                self.check_pat_tuple(pat.span, elements, *ddpos, expected, def_bm, discrim_span)
+                self.check_pat_tuple(pat.span, *elements, *ddpos, expected, def_bm, discrim_span)
             }
             PatKind::Box(inner) => {
                 self.check_pat_box(pat.span, inner, expected, def_bm, discrim_span)
@@ -113,7 +117,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             PatKind::Slice(before, slice, after) => {
                 let slice = slice.as_deref();
-                self.check_pat_slice(pat.span, before, slice, after, expected, def_bm, discrim_span)
+                self.check_pat_slice(
+                    pat.span,
+                    *before,
+                    slice,
+                    *after,
+                    expected,
+                    def_bm,
+                    discrim_span,
+                )
             }
         };
 
@@ -173,7 +185,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// as well as the pattern form we are currently checking.
     fn calc_default_binding_mode(
         &self,
-        pat: &'tcx Pat,
+        pat: &'tcx Pat<'tcx>,
         expected: Ty<'tcx>,
         def_bm: BindingMode,
         is_non_ref_pat: bool,
@@ -203,7 +215,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Is the pattern a "non reference pattern"?
     /// When the pattern is a path pattern, `opt_path_res` must be `Some(res)`.
-    fn is_non_ref_pat(&self, pat: &'tcx Pat, opt_path_res: Option<Res>) -> bool {
+    fn is_non_ref_pat(&self, pat: &'tcx Pat<'tcx>, opt_path_res: Option<Res>) -> bool {
         match pat.kind {
             PatKind::Struct(..)
             | PatKind::TupleStruct(..)
@@ -242,7 +254,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// The adjustments vector, if non-empty is stored in a table.
     fn peel_off_references(
         &self,
-        pat: &'tcx Pat,
+        pat: &'tcx Pat<'tcx>,
         expected: Ty<'tcx>,
         mut def_bm: BindingMode,
     ) -> (Ty<'tcx>, BindingMode) {
@@ -288,7 +300,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_pat_lit(
         &self,
         span: Span,
-        lt: &hir::Expr,
+        lt: &hir::Expr<'tcx>,
         expected: Ty<'tcx>,
         discrim_span: Option<Span>,
     ) -> Ty<'tcx> {
@@ -341,8 +353,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_pat_range(
         &self,
         span: Span,
-        begin: &'tcx hir::Expr,
-        end: &'tcx hir::Expr,
+        begin: &'tcx hir::Expr<'tcx>,
+        end: &'tcx hir::Expr<'tcx>,
         expected: Ty<'tcx>,
         discrim_span: Option<Span>,
     ) -> Option<Ty<'tcx>> {
@@ -422,10 +434,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_pat_ident(
         &self,
-        pat: &Pat,
+        pat: &Pat<'_>,
         ba: hir::BindingAnnotation,
         var_id: HirId,
-        sub: Option<&'tcx Pat>,
+        sub: Option<&'tcx Pat<'tcx>>,
         expected: Ty<'tcx>,
         def_bm: BindingMode,
         discrim_span: Option<Span>,
@@ -477,8 +489,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn borrow_pat_suggestion(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        pat: &Pat,
-        inner: &Pat,
+        pat: &Pat<'_>,
+        inner: &Pat<'_>,
         expected: Ty<'tcx>,
     ) {
         let tcx = self.tcx;
@@ -513,7 +525,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn check_dereferenceable(&self, span: Span, expected: Ty<'tcx>, inner: &Pat) -> bool {
+    pub fn check_dereferenceable(&self, span: Span, expected: Ty<'tcx>, inner: &Pat<'_>) -> bool {
         if let PatKind::Binding(..) = inner.kind {
             if let Some(mt) = self.shallow_resolve(expected).builtin_deref(true) {
                 if let ty::Dynamic(..) = mt.ty.kind {
@@ -541,9 +553,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_pat_struct(
         &self,
-        pat: &'tcx Pat,
+        pat: &'tcx Pat<'tcx>,
         qpath: &hir::QPath,
-        fields: &'tcx [hir::FieldPat],
+        fields: &'tcx [hir::FieldPat<'tcx>],
         etc: bool,
         expected: Ty<'tcx>,
         def_bm: BindingMode,
@@ -574,7 +586,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_pat_path(
         &self,
-        pat: &Pat,
+        pat: &Pat<'_>,
         path_resolution: (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment]),
         qpath: &hir::QPath,
         expected: Ty<'tcx>,
@@ -609,9 +621,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_pat_tuple_struct(
         &self,
-        pat: &Pat,
+        pat: &Pat<'_>,
         qpath: &hir::QPath,
-        subpats: &'tcx [P<Pat>],
+        subpats: &'tcx [&'tcx Pat<'tcx>],
         ddpos: Option<usize>,
         expected: Ty<'tcx>,
         def_bm: BindingMode,
@@ -713,7 +725,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         pat_span: Span,
         res: Res,
         qpath: &hir::QPath,
-        subpats: &'tcx [P<Pat>],
+        subpats: &'tcx [&'tcx Pat<'tcx>],
         fields: &'tcx [ty::FieldDef],
         expected: Ty<'tcx>,
         had_err: bool,
@@ -795,7 +807,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_pat_tuple(
         &self,
         span: Span,
-        elements: &'tcx [P<Pat>],
+        elements: &'tcx [&'tcx Pat<'tcx>],
         ddpos: Option<usize>,
         expected: Ty<'tcx>,
         def_bm: BindingMode,
@@ -843,7 +855,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         pat_id: HirId,
         span: Span,
         variant: &'tcx ty::VariantDef,
-        fields: &'tcx [hir::FieldPat],
+        fields: &'tcx [hir::FieldPat<'tcx>],
         etc: bool,
         def_bm: BindingMode,
     ) -> bool {
@@ -1069,7 +1081,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_pat_box(
         &self,
         span: Span,
-        inner: &'tcx Pat,
+        inner: &'tcx Pat<'tcx>,
         expected: Ty<'tcx>,
         def_bm: BindingMode,
         discrim_span: Option<Span>,
@@ -1094,8 +1106,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_pat_ref(
         &self,
-        pat: &Pat,
-        inner: &'tcx Pat,
+        pat: &Pat<'_>,
+        inner: &'tcx Pat<'tcx>,
         mutbl: hir::Mutability,
         expected: Ty<'tcx>,
         def_bm: BindingMode,
@@ -1158,9 +1170,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_pat_slice(
         &self,
         span: Span,
-        before: &'tcx [P<Pat>],
-        slice: Option<&'tcx Pat>,
-        after: &'tcx [P<Pat>],
+        before: &'tcx [&'tcx Pat<'tcx>],
+        slice: Option<&'tcx Pat<'tcx>>,
+        after: &'tcx [&'tcx Pat<'tcx>],
         expected: Ty<'tcx>,
         def_bm: BindingMode,
         discrim_span: Option<Span>,
@@ -1208,7 +1220,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_array_pat_len(
         &self,
         span: Span,
-        slice: Option<&'tcx Pat>,
+        slice: Option<&'tcx Pat<'tcx>>,
         len: &ty::Const<'tcx>,
         min_len: u64,
     ) -> Option<u64> {
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 149f27ed305..1ce7748badb 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -269,7 +269,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
     }
 
     /// Try to resolve the type for the given node.
-    pub fn resolve_expr_type_adjusted(&mut self, expr: &hir::Expr) -> Ty<'tcx> {
+    pub fn resolve_expr_type_adjusted(&mut self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
         let ty = self.tables.borrow().expr_ty_adjusted(expr);
         self.resolve_type(ty)
     }
@@ -367,7 +367,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         );
     }
 
-    fn constrain_bindings_in_pat(&mut self, pat: &hir::Pat) {
+    fn constrain_bindings_in_pat(&mut self, pat: &hir::Pat<'_>) {
         debug!("regionck::visit_pat(pat={:?})", pat);
         pat.each_binding(|_, hir_id, span, _| {
             // If we have a variable that contains region'd data, that
@@ -453,20 +453,20 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
 
     //visit_pat: visit_pat, // (..) see above
 
-    fn visit_arm(&mut self, arm: &'tcx hir::Arm) {
+    fn visit_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) {
         // see above
         self.constrain_bindings_in_pat(&arm.pat);
         intravisit::walk_arm(self, arm);
     }
 
-    fn visit_local(&mut self, l: &'tcx hir::Local) {
+    fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
         // see above
         self.constrain_bindings_in_pat(&l.pat);
         self.link_local(l);
         intravisit::walk_local(self, l);
     }
 
-    fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         debug!("regionck::visit_expr(e={:?}, repeating_scope={:?})", expr, self.repeating_scope);
 
         // No matter what, the type of each expression must outlive the
@@ -580,7 +580,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
             hir::ExprKind::Unary(hir::UnDeref, ref base) => {
                 // For *a, the lifetime of a must enclose the deref
                 if is_method_call {
-                    self.constrain_call(expr, Some(base), None::<hir::Expr>.iter());
+                    self.constrain_call(expr, Some(base), None::<hir::Expr<'_>>.iter());
                 }
                 // For overloaded derefs, base_ty is the input to `Deref::deref`,
                 // but it's a reference type uing the same region as the output.
@@ -594,7 +594,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
 
             hir::ExprKind::Unary(_, ref lhs) if is_method_call => {
                 // As above.
-                self.constrain_call(expr, Some(&lhs), None::<hir::Expr>.iter());
+                self.constrain_call(expr, Some(&lhs), None::<hir::Expr<'_>>.iter());
 
                 intravisit::walk_expr(self, expr);
             }
@@ -670,7 +670,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
-    fn constrain_cast(&mut self, cast_expr: &hir::Expr, source_expr: &hir::Expr) {
+    fn constrain_cast(&mut self, cast_expr: &hir::Expr<'_>, source_expr: &hir::Expr<'_>) {
         debug!("constrain_cast(cast_expr={:?}, source_expr={:?})", cast_expr, source_expr);
 
         let source_ty = self.resolve_node_type(source_expr.hir_id);
@@ -679,7 +679,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         self.walk_cast(cast_expr, source_ty, target_ty);
     }
 
-    fn walk_cast(&mut self, cast_expr: &hir::Expr, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) {
+    fn walk_cast(&mut self, cast_expr: &hir::Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) {
         debug!("walk_cast(from_ty={:?}, to_ty={:?})", from_ty, to_ty);
         match (&from_ty.kind, &to_ty.kind) {
             /*From:*/
@@ -707,13 +707,13 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         }
     }
 
-    fn check_expr_fn_block(&mut self, expr: &'tcx hir::Expr, body_id: hir::BodyId) {
+    fn check_expr_fn_block(&mut self, expr: &'tcx hir::Expr<'tcx>, body_id: hir::BodyId) {
         let repeating_scope = self.set_repeating_scope(body_id.hir_id);
         intravisit::walk_expr(self, expr);
         self.set_repeating_scope(repeating_scope);
     }
 
-    fn constrain_callee(&mut self, callee_expr: &hir::Expr) {
+    fn constrain_callee(&mut self, callee_expr: &hir::Expr<'_>) {
         let callee_ty = self.resolve_node_type(callee_expr.hir_id);
         match callee_ty.kind {
             ty::FnDef(..) | ty::FnPtr(_) => {}
@@ -729,10 +729,10 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         }
     }
 
-    fn constrain_call<'b, I: Iterator<Item = &'b hir::Expr>>(
+    fn constrain_call<'b, I: Iterator<Item = &'b hir::Expr<'b>>>(
         &mut self,
-        call_expr: &hir::Expr,
-        receiver: Option<&hir::Expr>,
+        call_expr: &hir::Expr<'_>,
+        receiver: Option<&hir::Expr<'_>>,
         arg_exprs: I,
     ) {
         //! Invoked on every call site (i.e., normal calls, method calls,
@@ -786,7 +786,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
 
     /// Invoked on any adjustments that occur. Checks that if this is a region pointer being
     /// dereferenced, the lifetime of the pointer includes the deref expr.
-    fn constrain_adjustments(&mut self, expr: &hir::Expr) -> mc::McResult<mc::Place<'tcx>> {
+    fn constrain_adjustments(&mut self, expr: &hir::Expr<'_>) -> mc::McResult<mc::Place<'tcx>> {
         debug!("constrain_adjustments(expr={:?})", expr);
 
         let mut cmt = self.with_mc(|mc| mc.cat_expr_unadjusted(expr))?;
@@ -880,7 +880,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
 
     /// Invoked on any index expression that occurs. Checks that if this is a slice
     /// being indexed, the lifetime of the pointer includes the deref expr.
-    fn constrain_index(&mut self, index_expr: &hir::Expr, indexed_ty: Ty<'tcx>) {
+    fn constrain_index(&mut self, index_expr: &hir::Expr<'_>, indexed_ty: Ty<'tcx>) {
         debug!("constrain_index(index_expr=?, indexed_ty={}", self.ty_to_string(indexed_ty));
 
         let r_index_expr = ty::ReScope(region::Scope {
@@ -952,7 +952,12 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
 
     /// Computes the guarantor for an expression `&base` and then ensures that the lifetime of the
     /// resulting pointer is linked to the lifetime of its guarantor (if any).
-    fn link_addr_of(&mut self, expr: &hir::Expr, mutability: hir::Mutability, base: &hir::Expr) {
+    fn link_addr_of(
+        &mut self,
+        expr: &hir::Expr<'_>,
+        mutability: hir::Mutability,
+        base: &hir::Expr<'_>,
+    ) {
         debug!("link_addr_of(expr={:?}, base={:?})", expr, base);
 
         let cmt = ignore_err!(self.with_mc(|mc| mc.cat_expr(base)));
@@ -965,7 +970,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
     /// Computes the guarantors for any ref bindings in a `let` and
     /// then ensures that the lifetime of the resulting pointer is
     /// linked to the lifetime of the initialization expression.
-    fn link_local(&self, local: &hir::Local) {
+    fn link_local(&self, local: &hir::Local<'_>) {
         debug!("regionck::for_local()");
         let init_expr = match local.init {
             None => {
@@ -980,7 +985,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
     /// Computes the guarantors for any ref bindings in a match and
     /// then ensures that the lifetime of the resulting pointer is
     /// linked to the lifetime of its guarantor (if any).
-    fn link_match(&self, discr: &hir::Expr, arms: &[hir::Arm]) {
+    fn link_match(&self, discr: &hir::Expr<'_>, arms: &[hir::Arm<'_>]) {
         debug!("regionck::for_match()");
         let discr_cmt = ignore_err!(self.with_mc(|mc| mc.cat_expr(discr)));
         debug!("discr_cmt={:?}", discr_cmt);
@@ -992,7 +997,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
     /// Computes the guarantors for any ref bindings in a match and
     /// then ensures that the lifetime of the resulting pointer is
     /// linked to the lifetime of its guarantor (if any).
-    fn link_fn_params(&self, params: &[hir::Param]) {
+    fn link_fn_params(&self, params: &[hir::Param<'_>]) {
         for param in params {
             let param_ty = self.node_ty(param.hir_id);
             let param_cmt =
@@ -1004,7 +1009,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
 
     /// Link lifetimes of any ref bindings in `root_pat` to the pointers found
     /// in the discriminant, if needed.
-    fn link_pattern(&self, discr_cmt: mc::Place<'tcx>, root_pat: &hir::Pat) {
+    fn link_pattern(&self, discr_cmt: mc::Place<'tcx>, root_pat: &hir::Pat<'_>) {
         debug!("link_pattern(discr_cmt={:?}, root_pat={:?})", discr_cmt, root_pat);
         ignore_err!(self.with_mc(|mc| {
             mc.cat_pattern(discr_cmt, root_pat, |sub_cmt, hir::Pat { kind, span, hir_id }| {
@@ -1024,7 +1029,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
     /// autoref'd.
     fn link_autoref(
         &self,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         expr_cmt: &mc::Place<'tcx>,
         autoref: &adjustment::AutoBorrow<'tcx>,
     ) {
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index a7cdbd923ae..bdccced42c4 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -63,7 +63,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InferBorrowKindVisitor<'a, 'tcx> {
         NestedVisitorMap::None
     }
 
-    fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         if let hir::ExprKind::Closure(cc, _, body_id, _, _) = expr.kind {
             let body = self.fcx.tcx.hir().body(body_id);
             self.visit_body(body);
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 5ef5f4c648e..ca9a4763ed0 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -132,7 +132,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
     // as potentially overloaded. But then, during writeback, if
     // we observe that something like `a+b` is (known to be)
     // operating on scalars, we clear the overload.
-    fn fix_scalar_builtin_expr(&mut self, e: &hir::Expr) {
+    fn fix_scalar_builtin_expr(&mut self, e: &hir::Expr<'_>) {
         match e.kind {
             hir::ExprKind::Unary(hir::UnNeg, ref inner)
             | hir::ExprKind::Unary(hir::UnNot, ref inner) => {
@@ -181,7 +181,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
     // Here, correct cases where an indexing expression can be simplified
     // to use builtin indexing because the index type is known to be
     // usize-ish
-    fn fix_index_builtin_expr(&mut self, e: &hir::Expr) {
+    fn fix_index_builtin_expr(&mut self, e: &hir::Expr<'_>) {
         if let hir::ExprKind::Index(ref base, ref index) = e.kind {
             let mut tables = self.fcx.tables.borrow_mut();
 
@@ -247,7 +247,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
         NestedVisitorMap::None
     }
 
-    fn visit_expr(&mut self, e: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
         self.fix_scalar_builtin_expr(e);
         self.fix_index_builtin_expr(e);
 
@@ -262,7 +262,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
 
                 self.visit_body(body);
             }
-            hir::ExprKind::Struct(_, ref fields, _) => {
+            hir::ExprKind::Struct(_, fields, _) => {
                 for field in fields {
                     self.visit_field_id(field.hir_id);
                 }
@@ -276,12 +276,12 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
         intravisit::walk_expr(self, e);
     }
 
-    fn visit_block(&mut self, b: &'tcx hir::Block) {
+    fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) {
         self.visit_node_id(b.span, b.hir_id);
         intravisit::walk_block(self, b);
     }
 
-    fn visit_pat(&mut self, p: &'tcx hir::Pat) {
+    fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
         match p.kind {
             hir::PatKind::Binding(..) => {
                 let tables = self.fcx.tables.borrow();
@@ -289,7 +289,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
                     self.tables.pat_binding_modes_mut().insert(p.hir_id, bm);
                 }
             }
-            hir::PatKind::Struct(_, ref fields, _) => {
+            hir::PatKind::Struct(_, fields, _) => {
                 for field in fields {
                     self.visit_field_id(field.hir_id);
                 }
@@ -303,7 +303,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
         intravisit::walk_pat(self, p);
     }
 
-    fn visit_local(&mut self, l: &'tcx hir::Local) {
+    fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
         intravisit::walk_local(self, l);
         let var_ty = self.fcx.local_ty(l.span, l.hir_id).decl_ty;
         let var_ty = self.resolve(&var_ty, &l.span);
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index c437f4e78d5..01f11f669f7 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -134,7 +134,7 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
         intravisit::walk_generics(self, generics);
     }
 
-    fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
+    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         if let hir::ExprKind::Closure(..) = expr.kind {
             let def_id = self.tcx.hir().local_def_id(expr.hir_id);
             self.tcx.generics_of(def_id);
diff --git a/src/librustc_typeck/expr_use_visitor.rs b/src/librustc_typeck/expr_use_visitor.rs
index f3f5e54edd1..b1467d508dc 100644
--- a/src/librustc_typeck/expr_use_visitor.rs
+++ b/src/librustc_typeck/expr_use_visitor.rs
@@ -10,7 +10,6 @@ pub use mc::{Place, PlaceBase, Projection};
 
 use rustc::hir::def::Res;
 use rustc::hir::def_id::DefId;
-use rustc::hir::ptr::P;
 use rustc::hir::{self, PatKind};
 use rustc::infer::InferCtxt;
 use rustc::ty::{self, adjustment, TyCtxt};
@@ -150,13 +149,13 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
         self.delegate.consume(place, mode);
     }
 
-    fn consume_exprs(&mut self, exprs: &[hir::Expr]) {
+    fn consume_exprs(&mut self, exprs: &[hir::Expr<'_>]) {
         for expr in exprs {
             self.consume_expr(&expr);
         }
     }
 
-    pub fn consume_expr(&mut self, expr: &hir::Expr) {
+    pub fn consume_expr(&mut self, expr: &hir::Expr<'_>) {
         debug!("consume_expr(expr={:?})", expr);
 
         let place = return_if_err!(self.mc.cat_expr(expr));
@@ -164,13 +163,13 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
         self.walk_expr(expr);
     }
 
-    fn mutate_expr(&mut self, expr: &hir::Expr) {
+    fn mutate_expr(&mut self, expr: &hir::Expr<'_>) {
         let place = return_if_err!(self.mc.cat_expr(expr));
         self.delegate.mutate(&place);
         self.walk_expr(expr);
     }
 
-    fn borrow_expr(&mut self, expr: &hir::Expr, bk: ty::BorrowKind) {
+    fn borrow_expr(&mut self, expr: &hir::Expr<'_>, bk: ty::BorrowKind) {
         debug!("borrow_expr(expr={:?}, bk={:?})", expr, bk);
 
         let place = return_if_err!(self.mc.cat_expr(expr));
@@ -179,11 +178,11 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
         self.walk_expr(expr)
     }
 
-    fn select_from_expr(&mut self, expr: &hir::Expr) {
+    fn select_from_expr(&mut self, expr: &hir::Expr<'_>) {
         self.walk_expr(expr)
     }
 
-    pub fn walk_expr(&mut self, expr: &hir::Expr) {
+    pub fn walk_expr(&mut self, expr: &hir::Expr<'_>) {
         debug!("walk_expr(expr={:?})", expr);
 
         self.walk_adjustment(expr);
@@ -228,7 +227,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                 self.consume_exprs(exprs);
             }
 
-            hir::ExprKind::Match(ref discr, ref arms, _) => {
+            hir::ExprKind::Match(ref discr, arms, _) => {
                 let discr_place = return_if_err!(self.mc.cat_expr(&discr));
                 self.borrow_expr(&discr, ty::ImmBorrow);
 
@@ -251,7 +250,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
             }
 
             hir::ExprKind::InlineAsm(ref ia) => {
-                for (o, output) in ia.inner.outputs.iter().zip(&ia.outputs_exprs) {
+                for (o, output) in ia.inner.outputs.iter().zip(ia.outputs_exprs) {
                     if o.is_indirect {
                         self.consume_expr(output);
                     } else {
@@ -326,7 +325,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
         }
     }
 
-    fn walk_callee(&mut self, call: &hir::Expr, callee: &hir::Expr) {
+    fn walk_callee(&mut self, call: &hir::Expr<'_>, callee: &hir::Expr<'_>) {
         let callee_ty = return_if_err!(self.mc.expr_ty_adjusted(callee));
         debug!("walk_callee: callee={:?} callee_ty={:?}", callee, callee_ty);
         match callee_ty.kind {
@@ -354,7 +353,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
         }
     }
 
-    fn walk_stmt(&mut self, stmt: &hir::Stmt) {
+    fn walk_stmt(&mut self, stmt: &hir::Stmt<'_>) {
         match stmt.kind {
             hir::StmtKind::Local(ref local) => {
                 self.walk_local(&local);
@@ -371,7 +370,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
         }
     }
 
-    fn walk_local(&mut self, local: &hir::Local) {
+    fn walk_local(&mut self, local: &hir::Local<'_>) {
         if let Some(ref expr) = local.init {
             // Variable declarations with
             // initializers are considered
@@ -385,10 +384,10 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
 
     /// Indicates that the value of `blk` will be consumed, meaning either copied or moved
     /// depending on its type.
-    fn walk_block(&mut self, blk: &hir::Block) {
+    fn walk_block(&mut self, blk: &hir::Block<'_>) {
         debug!("walk_block(blk.hir_id={})", blk.hir_id);
 
-        for stmt in &blk.stmts {
+        for stmt in blk.stmts {
             self.walk_stmt(stmt);
         }
 
@@ -397,7 +396,11 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
         }
     }
 
-    fn walk_struct_expr(&mut self, fields: &[hir::Field], opt_with: &Option<P<hir::Expr>>) {
+    fn walk_struct_expr(
+        &mut self,
+        fields: &[hir::Field<'_>],
+        opt_with: &Option<&'hir hir::Expr<'_>>,
+    ) {
         // Consume the expressions supplying values for each field.
         for field in fields {
             self.consume_expr(&field.expr);
@@ -450,7 +453,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
     // Invoke the appropriate delegate calls for anything that gets
     // consumed or borrowed as part of the automatic adjustment
     // process.
-    fn walk_adjustment(&mut self, expr: &hir::Expr) {
+    fn walk_adjustment(&mut self, expr: &hir::Expr<'_>) {
         let adjustments = self.mc.tables.expr_adjustments(expr);
         let mut place = return_if_err!(self.mc.cat_expr_unadjusted(expr));
         for adjustment in adjustments {
@@ -487,7 +490,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
     /// after all relevant autoderefs have occurred.
     fn walk_autoref(
         &mut self,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         base_place: &mc::Place<'tcx>,
         autoref: &adjustment::AutoBorrow<'tcx>,
     ) {
@@ -509,7 +512,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
         }
     }
 
-    fn walk_arm(&mut self, discr_place: &Place<'tcx>, arm: &hir::Arm) {
+    fn walk_arm(&mut self, discr_place: &Place<'tcx>, arm: &hir::Arm<'_>) {
         self.walk_pat(discr_place, &arm.pat);
 
         if let Some(hir::Guard::If(ref e)) = arm.guard {
@@ -521,12 +524,12 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
 
     /// Walks a pat that occurs in isolation (i.e., top-level of fn argument or
     /// let binding, and *not* a match arm or nested pat.)
-    fn walk_irrefutable_pat(&mut self, discr_place: &Place<'tcx>, pat: &hir::Pat) {
+    fn walk_irrefutable_pat(&mut self, discr_place: &Place<'tcx>, pat: &hir::Pat<'_>) {
         self.walk_pat(discr_place, pat);
     }
 
     /// The core driver for walking a pattern
-    fn walk_pat(&mut self, discr_place: &Place<'tcx>, pat: &hir::Pat) {
+    fn walk_pat(&mut self, discr_place: &Place<'tcx>, pat: &hir::Pat<'_>) {
         debug!("walk_pat(discr_place={:?}, pat={:?})", discr_place, pat);
 
         let tcx = self.tcx();
@@ -565,7 +568,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
         }));
     }
 
-    fn walk_captures(&mut self, closure_expr: &hir::Expr, fn_decl_span: Span) {
+    fn walk_captures(&mut self, closure_expr: &hir::Expr<'_>, fn_decl_span: Span) {
         debug!("walk_captures({:?})", closure_expr);
 
         let closure_def_id = self.tcx().hir().local_def_id(closure_expr.hir_id);
diff --git a/src/librustc_typeck/mem_categorization.rs b/src/librustc_typeck/mem_categorization.rs
index 8bca422ca18..4f5b55e4cd6 100644
--- a/src/librustc_typeck/mem_categorization.rs
+++ b/src/librustc_typeck/mem_categorization.rs
@@ -117,7 +117,7 @@ crate trait HirNode {
     fn span(&self) -> Span;
 }
 
-impl HirNode for hir::Expr {
+impl HirNode for hir::Expr<'_> {
     fn hir_id(&self) -> hir::HirId {
         self.hir_id
     }
@@ -126,7 +126,7 @@ impl HirNode for hir::Expr {
     }
 }
 
-impl HirNode for hir::Pat {
+impl HirNode for hir::Pat<'_> {
     fn hir_id(&self) -> hir::HirId {
         self.hir_id
     }
@@ -213,11 +213,11 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         self.resolve_type_vars_or_error(hir_id, self.tables.node_type_opt(hir_id))
     }
 
-    fn expr_ty(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
+    fn expr_ty(&self, expr: &hir::Expr<'_>) -> McResult<Ty<'tcx>> {
         self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_opt(expr))
     }
 
-    crate fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
+    crate fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> McResult<Ty<'tcx>> {
         self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_adjusted_opt(expr))
     }
 
@@ -231,7 +231,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
     ///   implicit deref patterns attached (e.g., it is really
     ///   `&Some(x)`). In that case, we return the "outermost" type
     ///   (e.g., `&Option<T>).
-    crate fn pat_ty_adjusted(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
+    crate fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> McResult<Ty<'tcx>> {
         // Check for implicit `&` types wrapping the pattern; note
         // that these are never attached to binding patterns, so
         // actually this is somewhat "disjoint" from the code below
@@ -247,7 +247,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
     }
 
     /// Like `pat_ty`, but ignores implicit `&` patterns.
-    fn pat_ty_unadjusted(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
+    fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> McResult<Ty<'tcx>> {
         let base_ty = self.node_ty(pat.hir_id)?;
         debug!("pat_ty(pat={:?}) base_ty={:?}", pat, base_ty);
 
@@ -280,12 +280,12 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         Ok(ret_ty)
     }
 
-    crate fn cat_expr(&self, expr: &hir::Expr) -> McResult<Place<'tcx>> {
+    crate fn cat_expr(&self, expr: &hir::Expr<'_>) -> McResult<Place<'tcx>> {
         // This recursion helper avoids going through *too many*
         // adjustments, since *only* non-overloaded deref recurses.
         fn helper<'a, 'tcx>(
             mc: &MemCategorizationContext<'a, 'tcx>,
-            expr: &hir::Expr,
+            expr: &hir::Expr<'_>,
             adjustments: &[adjustment::Adjustment<'tcx>],
         ) -> McResult<Place<'tcx>> {
             match adjustments.split_last() {
@@ -301,7 +301,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
 
     crate fn cat_expr_adjusted(
         &self,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         previous: Place<'tcx>,
         adjustment: &adjustment::Adjustment<'tcx>,
     ) -> McResult<Place<'tcx>> {
@@ -310,7 +310,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
 
     fn cat_expr_adjusted_with<F>(
         &self,
-        expr: &hir::Expr,
+        expr: &hir::Expr<'_>,
         previous: F,
         adjustment: &adjustment::Adjustment<'tcx>,
     ) -> McResult<Place<'tcx>>
@@ -342,7 +342,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         }
     }
 
-    crate fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<Place<'tcx>> {
+    crate fn cat_expr_unadjusted(&self, expr: &hir::Expr<'_>) -> McResult<Place<'tcx>> {
         debug!("cat_expr: id={} expr={:?}", expr.hir_id, expr);
 
         let expr_ty = self.expr_ty(expr)?;
@@ -513,7 +513,11 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         ret
     }
 
-    fn cat_overloaded_place(&self, expr: &hir::Expr, base: &hir::Expr) -> McResult<Place<'tcx>> {
+    fn cat_overloaded_place(
+        &self,
+        expr: &hir::Expr<'_>,
+        base: &hir::Expr<'_>,
+    ) -> McResult<Place<'tcx>> {
         debug!("cat_overloaded_place(expr={:?}, base={:?})", expr, base);
 
         // Reconstruct the output assuming it's a reference with the
@@ -557,17 +561,27 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         Ok(ret)
     }
 
-    crate fn cat_pattern<F>(&self, place: Place<'tcx>, pat: &hir::Pat, mut op: F) -> McResult<()>
+    crate fn cat_pattern<F>(
+        &self,
+        place: Place<'tcx>,
+        pat: &hir::Pat<'_>,
+        mut op: F,
+    ) -> McResult<()>
     where
-        F: FnMut(&Place<'tcx>, &hir::Pat),
+        F: FnMut(&Place<'tcx>, &hir::Pat<'_>),
     {
         self.cat_pattern_(place, pat, &mut op)
     }
 
     // FIXME(#19596) This is a workaround, but there should be a better way to do this
-    fn cat_pattern_<F>(&self, mut place: Place<'tcx>, pat: &hir::Pat, op: &mut F) -> McResult<()>
+    fn cat_pattern_<F>(
+        &self,
+        mut place: Place<'tcx>,
+        pat: &hir::Pat<'_>,
+        op: &mut F,
+    ) -> McResult<()>
     where
-        F: FnMut(&Place<'tcx>, &hir::Pat),
+        F: FnMut(&Place<'tcx>, &hir::Pat<'_>),
     {
         // Here, `place` is the `Place` being matched and pat is the pattern it
         // is being matched against.
@@ -638,7 +652,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
                 }
             }
 
-            PatKind::Struct(_, ref field_pats, _) => {
+            PatKind::Struct(_, field_pats, _) => {
                 // S { f1: p1, ..., fN: pN }
                 for fp in field_pats {
                     let field_ty = self.pat_ty_adjusted(&fp.pat)?;
@@ -647,7 +661,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
                 }
             }
 
-            PatKind::Or(ref pats) => {
+            PatKind::Or(pats) => {
                 for pat in pats {
                     self.cat_pattern_(place.clone(), &pat, op)?;
                 }
@@ -665,7 +679,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
                 self.cat_pattern_(subplace, &subpat, op)?;
             }
 
-            PatKind::Slice(ref before, ref slice, ref after) => {
+            PatKind::Slice(before, ref slice, after) => {
                 let element_ty = match place.ty.builtin_index() {
                     Some(ty) => ty,
                     None => {