about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-12-31 03:27:36 +0000
committerbors <bors@rust-lang.org>2019-12-31 03:27:36 +0000
commitbf2d145c62888c853db0bcfd8f5b3a6919f15502 (patch)
tree9af922d78574fe87299b511f06e14f729e74424f
parenta9dd56ff9a08d74c53d5cc22d18f126a12749608 (diff)
parentac8c0f4008d379d834fb08841f601cbe365c0c07 (diff)
downloadrust-bf2d145c62888c853db0bcfd8f5b3a6919f15502.tar.gz
rust-bf2d145c62888c853db0bcfd8f5b3a6919f15502.zip
Auto merge of #67032 - cjgillot:hirene, r=Zoxc
Allocate HIR on an arena 4/4

This is the fourth and last PR in the series started by #66931, #66936 and #66942.

The last commits should compile on their own.
The difference with the previous PR is given by https://github.com/cjgillot/rust/compare/hirene-ty...hirene

A few more cleanups may be necessary, please tell me.

r? @eddyb like the other
cc @Zoxc
-rw-r--r--src/librustc/hir/intravisit.rs4
-rw-r--r--src/librustc/hir/lowering.rs182
-rw-r--r--src/librustc/hir/lowering/expr.rs12
-rw-r--r--src/librustc/hir/lowering/item.rs92
-rw-r--r--src/librustc/hir/mod.rs35
-rw-r--r--src/librustc/hir/print.rs3
-rw-r--r--src/librustc/hir/ptr.rs128
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/middle/resolve_lifetime.rs10
-rw-r--r--src/librustc_lint/builtin.rs4
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs2
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/region_name.rs2
-rw-r--r--src/librustc_mir/monomorphize/collector.rs2
-rw-r--r--src/librustc_privacy/lib.rs2
-rw-r--r--src/librustc_typeck/astconv.rs8
-rw-r--r--src/librustc_typeck/check/coercion.rs7
-rw-r--r--src/librustc_typeck/coherence/orphan.rs2
-rw-r--r--src/librustc_typeck/collect.rs6
-rw-r--r--src/librustdoc/clean/inline.rs2
-rw-r--r--src/librustdoc/clean/mod.rs13
-rw-r--r--src/librustdoc/doctree.rs2
21 files changed, 186 insertions, 333 deletions
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index c265b53b37d..9ac63001bf3 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -672,7 +672,7 @@ pub fn walk_generic_args<'v, V: Visitor<'v>>(
     _path_span: Span,
     generic_args: &'v GenericArgs<'v>,
 ) {
-    walk_list!(visitor, visit_generic_arg, &generic_args.args);
+    walk_list!(visitor, visit_generic_arg, generic_args.args);
     walk_list!(visitor, visit_assoc_type_binding, generic_args.bindings);
 }
 
@@ -780,7 +780,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Generi
 }
 
 pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics<'v>) {
-    walk_list!(visitor, visit_generic_param, &generics.params);
+    walk_list!(visitor, visit_generic_param, generics.params);
     walk_list!(visitor, visit_where_predicate, generics.where_clause.predicates);
 }
 
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index dda25c9ba18..15eee3cad7f 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -37,8 +37,6 @@ use crate::dep_graph::DepGraph;
 use crate::hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
 use crate::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
 use crate::hir::map::{DefKey, DefPathData, Definitions};
-use crate::hir::ptr::P;
-use crate::hir::HirVec;
 use crate::hir::{self, ParamName};
 use crate::hir::{ConstArg, GenericArg};
 use crate::lint;
@@ -75,12 +73,10 @@ use syntax_pos::Span;
 use rustc_error_codes::*;
 
 macro_rules! arena_vec {
-    () => (
-        &[]
-    );
-    ($this:expr; $($x:expr),*) => (
-        $this.arena.alloc_from_iter(vec![$($x),*])
-    );
+    ($this:expr; $($x:expr),*) => ({
+        let a = [$($x),*];
+        $this.arena.alloc_from_iter(std::array::IntoIter::new(a))
+    });
 }
 
 mod expr;
@@ -540,7 +536,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c);
 
         let module = self.lower_mod(&c.module);
-        let attrs = self.arena.alloc_from_iter(self.lower_attrs(&c.attrs).into_iter());
+        let attrs = self.lower_attrs(&c.attrs);
         let body_ids = body_ids(&self.bodies);
 
         self.resolver.definitions().init_node_id_to_hir_id_mapping(self.node_id_to_hir_id);
@@ -893,7 +889,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     // in-band-lifetimes introduced by generics or where-clauses
                     // wouldn't have been added yet.
                     let generics =
-                        this.lower_generics(generics, ImplTraitContext::Universal(&mut params));
+                        this.lower_generics_mut(generics, ImplTraitContext::Universal(&mut params));
                     let res = f(this, &mut params);
                     (params, (generics, res))
                 })
@@ -914,6 +910,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
         lowered_generics.params = lowered_params.into();
 
+        let lowered_generics = lowered_generics.into_generics(self.arena);
         (lowered_generics, res)
     }
 
@@ -957,14 +954,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }
     }
 
-    fn lower_attrs_arena(&mut self, attrs: &[Attribute]) -> &'hir [Attribute] {
+    fn lower_attrs(&mut self, attrs: &[Attribute]) -> &'hir [Attribute] {
         self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)))
     }
 
-    fn lower_attrs(&mut self, attrs: &[Attribute]) -> hir::HirVec<Attribute> {
-        attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into()
-    }
-
     fn lower_attr(&mut self, attr: &Attribute) -> Attribute {
         // Note that we explicitly do not walk the path. Since we don't really
         // lower attributes (we use the AST version) there is nowhere to keep
@@ -1226,24 +1219,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             }
             TyKind::BareFn(ref f) => self.with_in_scope_lifetime_defs(&f.generic_params, |this| {
                 this.with_anonymous_lifetime_mode(AnonymousLifetimeMode::PassThrough, |this| {
-                    hir::TyKind::BareFn(
-                        this.arena.alloc(hir::BareFnTy {
-                            generic_params: this.arena.alloc_from_iter(
-                                this.lower_generic_params(
-                                    &f.generic_params,
-                                    &NodeMap::default(),
-                                    ImplTraitContext::disallowed(),
-                                )
-                                .into_iter(),
-                            ),
-                            unsafety: f.unsafety,
-                            abi: this.lower_extern(f.ext),
-                            decl: this.lower_fn_decl(&f.decl, None, false, None),
-                            param_names: this.arena.alloc_from_iter(
-                                this.lower_fn_params_to_names(&f.decl).into_iter(),
-                            ),
-                        }),
-                    )
+                    hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy {
+                        generic_params: this.lower_generic_params(
+                            &f.generic_params,
+                            &NodeMap::default(),
+                            ImplTraitContext::disallowed(),
+                        ),
+                        unsafety: f.unsafety,
+                        abi: this.lower_extern(f.ext),
+                        decl: this.lower_fn_decl(&f.decl, None, false, None),
+                        param_names: this.lower_fn_params_to_names(&f.decl),
+                    }))
                 })
             }),
             TyKind::Never => hir::TyKind::Never,
@@ -1419,7 +1405,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
         debug!("lower_opaque_impl_trait: lifetime_defs={:#?}", lifetime_defs,);
 
-        self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
+        self.with_hir_id_owner(opaque_ty_node_id, move |lctx| {
             let opaque_ty_item = hir::OpaqueTy {
                 generics: hir::Generics {
                     params: lifetime_defs,
@@ -1474,7 +1460,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         opaque_ty_id: NodeId,
         parent_index: DefIndex,
         bounds: hir::GenericBounds<'hir>,
-    ) -> (&'hir [hir::GenericArg<'hir>], HirVec<hir::GenericParam<'hir>>) {
+    ) -> (&'hir [hir::GenericArg<'hir>], &'hir [hir::GenericParam<'hir>]) {
         debug!(
             "lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \
              parent_index={:?}, \
@@ -1641,7 +1627,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         let ImplTraitLifetimeCollector { output_lifetimes, output_lifetime_params, .. } =
             lifetime_collector;
 
-        (self.arena.alloc_from_iter(output_lifetimes), output_lifetime_params.into())
+        (
+            self.arena.alloc_from_iter(output_lifetimes),
+            self.arena.alloc_from_iter(output_lifetime_params),
+        )
     }
 
     fn lower_qpath(
@@ -1809,8 +1798,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         p: &Path,
         param_mode: ParamMode,
         explicit_owner: Option<NodeId>,
-    ) -> hir::Path<'hir> {
-        hir::Path {
+    ) -> &'hir hir::Path<'hir> {
+        self.arena.alloc(hir::Path {
             res,
             segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| {
                 self.lower_path_segment(
@@ -1824,10 +1813,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 )
             })),
             span: p.span,
-        }
+        })
     }
 
-    fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path<'hir> {
+    fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> &'hir hir::Path<'hir> {
         let res = self.expect_full_res(id);
         let res = self.lower_res(res);
         self.lower_path_extra(res, p, param_mode, None)
@@ -1899,7 +1888,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         if !generic_args.parenthesized && !has_lifetimes {
             generic_args.args = self
                 .elided_path_lifetimes(path_span, expected_lifetimes)
-                .into_iter()
                 .map(|lt| GenericArg::Lifetime(lt))
                 .chain(generic_args.args.into_iter())
                 .collect();
@@ -1978,7 +1966,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             hir_id: Some(id),
             res: Some(self.lower_res(res)),
             infer_args,
-            args: if generic_args.is_empty() { None } else { Some(self.arena.alloc(generic_args)) },
+            args: if generic_args.is_empty() {
+                None
+            } else {
+                Some(self.arena.alloc(generic_args.into_generic_args(self.arena)))
+            },
         }
     }
 
@@ -1987,7 +1979,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         data: &AngleBracketedArgs,
         param_mode: ParamMode,
         mut itctx: ImplTraitContext<'_, 'hir>,
-    ) -> (hir::GenericArgs<'hir>, bool) {
+    ) -> (GenericArgsCtor<'hir>, bool) {
         let &AngleBracketedArgs { ref args, ref constraints, .. } = data;
         let has_non_lt_args = args.iter().any(|arg| match arg {
             ast::GenericArg::Lifetime(_) => false,
@@ -1995,7 +1987,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             ast::GenericArg::Const(_) => true,
         });
         (
-            hir::GenericArgs {
+            GenericArgsCtor {
                 args: args.iter().map(|a| self.lower_generic_arg(a, itctx.reborrow())).collect(),
                 bindings: self.arena.alloc_from_iter(
                     constraints.iter().map(|b| self.lower_assoc_ty_constraint(b, itctx.reborrow())),
@@ -2009,7 +2001,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_parenthesized_parameter_data(
         &mut self,
         data: &ParenthesizedArgs,
-    ) -> (hir::GenericArgs<'hir>, bool) {
+    ) -> (GenericArgsCtor<'hir>, bool) {
         // Switch to `PassThrough` mode for anonymous lifetimes; this
         // means that we permit things like `&Ref<T>`, where `Ref` has
         // a hidden lifetime parameter. This is needed for backwards
@@ -2024,7 +2016,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 FunctionRetTy::Ty(ty) => this.lower_ty(&ty, ImplTraitContext::disallowed()),
                 FunctionRetTy::Default(_) => this.arena.alloc(this.ty_tup(span, &[])),
             };
-            let args = hir_vec![GenericArg::Type(this.ty_tup(span, inputs))];
+            let args = smallvec![GenericArg::Type(this.ty_tup(span, inputs))];
             let binding = hir::TypeBinding {
                 hir_id: this.next_id(),
                 ident: Ident::with_dummy_span(FN_OUTPUT_NAME),
@@ -2032,7 +2024,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 kind: hir::TypeBindingKind::Equality { ty: output_ty },
             };
             (
-                hir::GenericArgs { args, bindings: arena_vec![this; binding], parenthesized: true },
+                GenericArgsCtor { args, bindings: arena_vec![this; binding], parenthesized: true },
                 false,
             )
         })
@@ -2072,7 +2064,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         )
     }
 
-    fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> hir::HirVec<Ident> {
+    fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
         // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
         // as they are not explicit in HIR/Ty function signatures.
         // (instead, the `c_variadic` flag is set to `true`)
@@ -2080,13 +2072,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         if decl.c_variadic() {
             inputs = &inputs[..inputs.len() - 1];
         }
-        inputs
-            .iter()
-            .map(|param| match param.pat.kind {
-                PatKind::Ident(_, ident, _) => ident,
-                _ => Ident::new(kw::Invalid, param.pat.span),
-            })
-            .collect()
+        self.arena.alloc_from_iter(inputs.iter().map(|param| match param.pat.kind {
+            PatKind::Ident(_, ident, _) => ident,
+            _ => Ident::new(kw::Invalid, param.pat.span),
+        }))
     }
 
     // Lowers a function declaration.
@@ -2310,12 +2299,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", this.lifetimes_to_define);
             debug!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params);
 
-            let generic_params = lifetime_params
-                .iter()
-                .map(|(span, hir_name)| {
+            let generic_params =
+                this.arena.alloc_from_iter(lifetime_params.iter().map(|(span, hir_name)| {
                     this.lifetime_to_generic_param(*span, *hir_name, opaque_ty_def_index)
-                })
-                .collect();
+                }));
 
             let opaque_ty_item = hir::OpaqueTy {
                 generics: hir::Generics {
@@ -2395,7 +2382,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
         // "<Output = T>"
         let future_params = self.arena.alloc(hir::GenericArgs {
-            args: HirVec::new(),
+            args: &[],
             bindings: arena_vec![self; hir::TypeBinding {
                 ident: Ident::with_dummy_span(FN_OUTPUT_NAME),
                 kind: hir::TypeBindingKind::Equality { ty: output_ty },
@@ -2406,12 +2393,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         });
 
         // ::std::future::Future<future_params>
-        let future_path = self.arena.alloc(self.std_path(
-            span,
-            &[sym::future, sym::Future],
-            Some(future_params),
-            false,
-        ));
+        let future_path =
+            self.std_path(span, &[sym::future, sym::Future], Some(future_params), false);
 
         hir::GenericBound::Trait(
             hir::PolyTraitRef {
@@ -2474,16 +2457,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         hir::Lifetime { hir_id: self.lower_node_id(id), span, name }
     }
 
+    fn lower_generic_params_mut<'s>(
+        &'s mut self,
+        params: &'s [GenericParam],
+        add_bounds: &'s NodeMap<Vec<GenericBound>>,
+        mut itctx: ImplTraitContext<'s, 'hir>,
+    ) -> impl Iterator<Item = hir::GenericParam<'hir>> + Captures<'a> + Captures<'s> {
+        params
+            .iter()
+            .map(move |param| self.lower_generic_param(param, add_bounds, itctx.reborrow()))
+    }
+
     fn lower_generic_params(
         &mut self,
         params: &[GenericParam],
         add_bounds: &NodeMap<Vec<GenericBound>>,
-        mut itctx: ImplTraitContext<'_, 'hir>,
-    ) -> HirVec<hir::GenericParam<'hir>> {
-        params
-            .iter()
-            .map(|param| self.lower_generic_param(param, add_bounds, itctx.reborrow()))
-            .collect()
+        itctx: ImplTraitContext<'_, 'hir>,
+    ) -> &'hir [hir::GenericParam<'hir>] {
+        self.arena.alloc_from_iter(self.lower_generic_params_mut(params, add_bounds, itctx))
     }
 
     fn lower_generic_param(
@@ -2561,7 +2552,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             name,
             span: param.ident.span,
             pure_wrt_drop: attr::contains_name(&param.attrs, sym::may_dangle),
-            attrs: self.lower_attrs_arena(&param.attrs),
+            attrs: self.lower_attrs(&param.attrs),
             bounds: self.arena.alloc_from_iter(bounds),
             kind,
         }
@@ -2593,11 +2584,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             this.lower_trait_ref(&p.trait_ref, itctx)
         });
 
-        hir::PolyTraitRef {
-            bound_generic_params: self.arena.alloc_from_iter(bound_generic_params.into_iter()),
-            trait_ref,
-            span: p.span,
-        }
+        hir::PolyTraitRef { bound_generic_params, trait_ref, span: p.span }
     }
 
     fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext<'_, 'hir>) -> hir::MutTy<'hir> {
@@ -3053,7 +3040,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         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, self.arena.alloc(path));
+        let qpath = hir::QPath::Resolved(None, path);
         let pt = if subpats.is_empty() {
             hir::PatKind::Path(qpath)
         } else {
@@ -3101,7 +3088,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         components: &[Symbol],
         params: Option<&'hir hir::GenericArgs<'hir>>,
         is_value: bool,
-    ) -> hir::Path<'hir> {
+    ) -> &'hir hir::Path<'hir> {
         let ns = if is_value { Namespace::ValueNS } else { Namespace::TypeNS };
         let (path, res) = self.resolver.resolve_str_path(span, self.crate_root, components, ns);
 
@@ -3121,11 +3108,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             .collect();
         segments.last_mut().unwrap().args = params;
 
-        hir::Path {
+        self.arena.alloc(hir::Path {
             span,
             res: res.map_id(|_| panic!("unexpected `NodeId`")),
             segments: self.arena.alloc_from_iter(segments),
-        }
+        })
     }
 
     fn ty_path(
@@ -3209,8 +3196,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     /// `std::cell::Ref<T>`; note that implicit lifetimes in these
     /// sorts of cases are deprecated. This may therefore report a warning or an
     /// error, depending on the mode.
-    fn elided_path_lifetimes(&mut self, span: Span, count: usize) -> P<[hir::Lifetime]> {
-        (0..count).map(|_| self.elided_path_lifetime(span)).collect()
+    fn elided_path_lifetimes<'s>(
+        &'s mut self,
+        span: Span,
+        count: usize,
+    ) -> impl Iterator<Item = hir::Lifetime> + Captures<'a> + Captures<'s> + Captures<'hir> {
+        (0..count).map(move |_| self.elided_path_lifetime(span))
     }
 
     fn elided_path_lifetime(&mut self, span: Span) -> hir::Lifetime {
@@ -3304,3 +3295,24 @@ fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body<'hir>>) -> Vec<hir::BodyId>
     body_ids.sort_by_key(|b| bodies[b].value.span);
     body_ids
 }
+
+/// Helper struct for delayed construction of GenericArgs.
+struct GenericArgsCtor<'hir> {
+    args: SmallVec<[hir::GenericArg<'hir>; 4]>,
+    bindings: &'hir [hir::TypeBinding<'hir>],
+    parenthesized: bool,
+}
+
+impl GenericArgsCtor<'hir> {
+    fn is_empty(&self) -> bool {
+        self.args.is_empty() && self.bindings.is_empty() && !self.parenthesized
+    }
+
+    fn into_generic_args(self, arena: &'hir Arena<'hir>) -> hir::GenericArgs<'hir> {
+        hir::GenericArgs {
+            args: arena.alloc_from_iter(self.args),
+            bindings: self.bindings,
+            parenthesized: self.parenthesized,
+        }
+    }
+}
diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index 067a076d829..3911f09a227 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -464,7 +464,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> {
         hir::Arm {
             hir_id: self.next_id(),
-            attrs: self.lower_attrs_arena(&arm.attrs),
+            attrs: self.lower_attrs(&arm.attrs),
             pat: self.lower_pat(&arm.pat),
             guard: match arm.guard {
                 Some(ref x) => Some(hir::Guard::If(self.lower_expr(x))),
@@ -827,7 +827,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let is_unit = fields.is_empty();
         let struct_path = [sym::ops, path];
         let struct_path = self.std_path(span, &struct_path, None, is_unit);
-        let struct_path = hir::QPath::Resolved(None, self.arena.alloc(struct_path));
+        let struct_path = hir::QPath::Resolved(None, struct_path);
 
         if is_unit {
             hir::ExprKind::Path(struct_path)
@@ -1336,7 +1336,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         assoc_fn_name: &str,
         args: &'hir [hir::Expr<'hir>],
     ) -> hir::ExprKind<'hir> {
-        let ty_path = self.arena.alloc(self.std_path(span, ty_path_components, None, false));
+        let ty_path = self.std_path(span, ty_path_components, None, false);
         let ty =
             self.arena.alloc(self.ty_path(ty_path_id, span, hir::QPath::Resolved(None, ty_path)));
         let fn_seg = self.arena.alloc(hir::PathSegment::from_ident(Ident::from_str(assoc_fn_name)));
@@ -1354,11 +1354,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         attrs: AttrVec,
     ) -> hir::Expr<'hir> {
         let path = self.std_path(span, components, params, true);
-        self.expr(
-            span,
-            hir::ExprKind::Path(hir::QPath::Resolved(None, self.arena.alloc(path))),
-            attrs,
-        )
+        self.expr(span, hir::ExprKind::Path(hir::QPath::Resolved(None, path)), attrs)
     }
 
     pub(super) fn expr_ident(
diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs
index 2fd59c4a1b1..6f1088de6c2 100644
--- a/src/librustc/hir/lowering/item.rs
+++ b/src/librustc/hir/lowering/item.rs
@@ -5,6 +5,7 @@ use super::ImplTraitTypeIdVisitor;
 use super::LoweringContext;
 use super::ParamMode;
 
+use crate::arena::Arena;
 use crate::hir;
 use crate::hir::def::{DefKind, Res};
 use crate::hir::def_id::DefId;
@@ -225,7 +226,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item<'hir>> {
         let mut ident = i.ident;
         let mut vis = self.lower_visibility(&i.vis, None);
-        let attrs = self.lower_attrs_arena(&i.attrs);
+        let attrs = self.lower_attrs(&i.attrs);
 
         if let ItemKind::MacroDef(ref def) = i.kind {
             if !def.legacy || attr::contains_name(&i.attrs, sym::macro_export) {
@@ -506,7 +507,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         let new_id = this.lower_node_id(new_node_id);
                         let res = this.lower_res(res);
                         let path = this.lower_path_extra(res, &path, ParamMode::Explicit, None);
-                        let kind = hir::ItemKind::Use(this.arena.alloc(path), hir::UseKind::Single);
+                        let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
                         let vis = this.rebuild_vis(&vis);
 
                         this.insert_item(hir::Item {
@@ -521,15 +522,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 }
 
                 let path = self.lower_path_extra(ret_res, &path, ParamMode::Explicit, None);
-                let path = self.arena.alloc(path);
                 hir::ItemKind::Use(path, hir::UseKind::Single)
             }
             UseTreeKind::Glob => {
-                let path = self.arena.alloc(self.lower_path(
-                    id,
-                    &Path { segments, span: path.span },
-                    ParamMode::Explicit,
-                ));
+                let path =
+                    self.lower_path(id, &Path { segments, span: path.span }, ParamMode::Explicit);
                 hir::ItemKind::Use(path, hir::UseKind::Glob)
             }
             UseTreeKind::Nested(ref trees) => {
@@ -617,7 +614,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err);
                 let res = self.lower_res(res);
                 let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit, None);
-                let path = self.arena.alloc(path);
                 hir::ItemKind::Use(path, hir::UseKind::ListStem)
             }
         }
@@ -626,7 +622,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     /// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated
     /// many times in the HIR tree; for each occurrence, we need to assign distinct
     /// `NodeId`s. (See, e.g., #56128.)
-    fn rebuild_use_path(&mut self, path: &hir::Path<'hir>) -> hir::Path<'hir> {
+    fn rebuild_use_path(&mut self, path: &hir::Path<'hir>) -> &'hir hir::Path<'hir> {
         debug!("rebuild_use_path(path = {:?})", path);
         let segments =
             self.arena.alloc_from_iter(path.segments.iter().map(|seg| hir::PathSegment {
@@ -636,7 +632,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 args: None,
                 infer_args: seg.infer_args,
             }));
-        hir::Path { span: path.span, res: path.res, segments }
+        self.arena.alloc(hir::Path { span: path.span, res: path.res, segments })
     }
 
     fn rebuild_vis(&mut self, vis: &hir::Visibility<'hir>) -> hir::Visibility<'hir> {
@@ -646,7 +642,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
             hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
                 hir::VisibilityKind::Restricted {
-                    path: self.arena.alloc(self.rebuild_use_path(path)),
+                    path: self.rebuild_use_path(path),
                     hir_id: self.next_id(),
                 }
             }
@@ -659,7 +655,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         hir::ForeignItem {
             hir_id: self.lower_node_id(i.id),
             ident: i.ident,
-            attrs: self.lower_attrs_arena(&i.attrs),
+            attrs: self.lower_attrs(&i.attrs),
             kind: match i.kind {
                 ForeignItemKind::Fn(ref fdec, ref generics) => {
                     let (generics, (fn_dec, fn_args)) = self.add_in_band_defs(
@@ -674,7 +670,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             )
                         },
                     );
-                    let fn_args = self.arena.alloc_from_iter(fn_args.into_iter());
 
                     hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
                 }
@@ -703,7 +698,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
     fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
         hir::Variant {
-            attrs: self.lower_attrs_arena(&v.attrs),
+            attrs: self.lower_attrs(&v.attrs),
             data: self.lower_variant_data(&v.data),
             disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
             id: self.lower_node_id(v.id),
@@ -751,7 +746,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             },
             vis: self.lower_visibility(&f.vis, None),
             ty,
-            attrs: self.lower_attrs_arena(&f.attrs),
+            attrs: self.lower_attrs(&f.attrs),
         }
     }
 
@@ -772,7 +767,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }
             AssocItemKind::Fn(ref sig, None) => {
                 let names = self.lower_fn_params_to_names(&sig.decl);
-                let names: &[Ident] = self.arena.alloc_from_iter(names.into_iter());
                 let (generics, sig) =
                     self.lower_method_sig(&i.generics, sig, trait_item_def_id, false, None);
                 (generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Required(names)))
@@ -799,7 +793,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         hir::TraitItem {
             hir_id: self.lower_node_id(i.id),
             ident: i.ident,
-            attrs: self.lower_attrs_arena(&i.attrs),
+            attrs: self.lower_attrs(&i.attrs),
             generics,
             kind,
             span: i.span,
@@ -886,7 +880,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         hir::ImplItem {
             hir_id: self.lower_node_id(i.id),
             ident: i.ident,
-            attrs: self.lower_attrs_arena(&i.attrs),
+            attrs: self.lower_attrs(&i.attrs),
             generics,
             vis: self.lower_visibility(&i.vis, None),
             defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
@@ -945,12 +939,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 let res = self.expect_full_res(id);
                 let res = self.lower_res(res);
                 hir::VisibilityKind::Restricted {
-                    path: self.arena.alloc(self.lower_path_extra(
-                        res,
-                        path,
-                        ParamMode::Explicit,
-                        explicit_owner,
-                    )),
+                    path: self.lower_path_extra(res, path, ParamMode::Explicit, explicit_owner),
                     hir_id: lowered_id,
                 }
             }
@@ -993,7 +982,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
     fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
         hir::Param {
-            attrs: self.lower_attrs_arena(&param.attrs),
+            attrs: self.lower_attrs(&param.attrs),
             hir_id: self.lower_node_id(param.id),
             pat: self.lower_pat(&param.pat),
             span: param.span,
@@ -1133,7 +1122,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     let stmt = this.stmt_let_pat(
                         stmt_attrs,
                         desugared_span,
-                        Some(this.arena.alloc(expr)),
+                        Some(expr),
                         parameter.pat,
                         hir::LocalSource::AsyncFn,
                     );
@@ -1163,7 +1152,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     let move_stmt = this.stmt_let_pat(
                         AttrVec::new(),
                         desugared_span,
-                        Some(this.arena.alloc(move_expr)),
+                        Some(move_expr),
                         move_pat,
                         hir::LocalSource::AsyncFn,
                     );
@@ -1174,7 +1163,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     let pattern_stmt = this.stmt_let_pat(
                         stmt_attrs,
                         desugared_span,
-                        Some(this.arena.alloc(pattern_expr)),
+                        Some(pattern_expr),
                         parameter.pat,
                         hir::LocalSource::AsyncFn,
                     );
@@ -1295,11 +1284,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
         }
     }
 
-    pub(super) fn lower_generics(
+    pub(super) fn lower_generics_mut(
         &mut self,
         generics: &Generics,
         itctx: ImplTraitContext<'_, 'hir>,
-    ) -> hir::Generics<'hir> {
+    ) -> GenericsCtor<'hir> {
         // Collect `?Trait` bounds in where clause and move them to parameter definitions.
         // FIXME: this could probably be done with less rightward drift. It also looks like two
         // control paths where `report_error` is called are the only paths that advance to after the
@@ -1355,13 +1344,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }
         }
 
-        hir::Generics {
-            params: self.lower_generic_params(&generics.params, &add_bounds, itctx),
+        GenericsCtor {
+            params: self.lower_generic_params_mut(&generics.params, &add_bounds, itctx).collect(),
             where_clause: self.lower_where_clause(&generics.where_clause),
             span: generics.span,
         }
     }
 
+    pub(super) fn lower_generics(
+        &mut self,
+        generics: &Generics,
+        itctx: ImplTraitContext<'_, 'hir>,
+    ) -> hir::Generics<'hir> {
+        let generics_ctor = self.lower_generics_mut(generics, itctx);
+        generics_ctor.into_generics(self.arena)
+    }
+
     fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause<'hir> {
         self.with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
             hir::WhereClause {
@@ -1383,13 +1381,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }) => {
                 self.with_in_scope_lifetime_defs(&bound_generic_params, |this| {
                     hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
-                        bound_generic_params: this.arena.alloc_from_iter(
-                            this.lower_generic_params(
-                                bound_generic_params,
-                                &NodeMap::default(),
-                                ImplTraitContext::disallowed(),
-                            )
-                            .into_iter(),
+                        bound_generic_params: this.lower_generic_params(
+                            bound_generic_params,
+                            &NodeMap::default(),
+                            ImplTraitContext::disallowed(),
                         ),
                         bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::disallowed()),
                         bounds: this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| {
@@ -1426,3 +1421,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
         }
     }
 }
+
+/// Helper struct for delayed construction of Generics.
+pub(super) struct GenericsCtor<'hir> {
+    pub(super) params: SmallVec<[hir::GenericParam<'hir>; 4]>,
+    where_clause: hir::WhereClause<'hir>,
+    span: Span,
+}
+
+impl GenericsCtor<'hir> {
+    pub(super) fn into_generics(self, arena: &'hir Arena<'hir>) -> hir::Generics<'hir> {
+        hir::Generics {
+            params: arena.alloc_from_iter(self.params),
+            where_clause: self.where_clause,
+            span: self.span,
+        }
+    }
+}
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 13ae89e77b2..f56c9f8e72c 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -10,7 +10,6 @@ pub use self::UnsafeSource::*;
 
 use crate::hir::def::{DefKind, Res};
 use crate::hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
-use crate::hir::ptr::P;
 use crate::mir::mono::Linkage;
 use crate::ty::query::Providers;
 use crate::ty::AdtKind;
@@ -35,21 +34,6 @@ use syntax_pos::source_map::{SourceMap, Spanned};
 use syntax_pos::symbol::{kw, sym, Symbol};
 use syntax_pos::{MultiSpan, Span, DUMMY_SP};
 
-/// HIR doesn't commit to a concrete storage type and has its own alias for a vector.
-/// It can be `Vec`, `P<[T]>` or potentially `Box<[T]>`, or some other container with similar
-/// behavior. Unlike AST, HIR is mostly a static structure, so we can use an owned slice instead
-/// of `Vec` to avoid keeping extra capacity.
-pub type HirVec<T> = P<[T]>;
-
-macro_rules! hir_vec {
-    ($elem:expr; $n:expr) => (
-        $crate::hir::HirVec::from(vec![$elem; $n])
-    );
-    ($($x:expr),*) => (
-        $crate::hir::HirVec::from(vec![$($x),*])
-    );
-}
-
 pub mod check_attr;
 pub mod def;
 pub mod def_id;
@@ -59,7 +43,6 @@ pub mod lowering;
 pub mod map;
 pub mod pat_util;
 pub mod print;
-pub mod ptr;
 pub mod upvars;
 
 /// Uniquely identifies a node in the HIR of the current crate. It is
@@ -415,7 +398,7 @@ impl GenericArg<'_> {
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct GenericArgs<'hir> {
     /// The generic arguments for this path segment.
-    pub args: HirVec<GenericArg<'hir>>,
+    pub args: &'hir [GenericArg<'hir>],
     /// Bindings (equality constraints) on associated types, if present.
     /// E.g., `Foo<A = Bar>`.
     pub bindings: &'hir [TypeBinding<'hir>],
@@ -427,7 +410,7 @@ pub struct GenericArgs<'hir> {
 
 impl GenericArgs<'_> {
     pub const fn none() -> Self {
-        Self { args: HirVec::new(), bindings: &[], parenthesized: false }
+        Self { args: &[], bindings: &[], parenthesized: false }
     }
 
     pub fn is_empty(&self) -> bool {
@@ -436,7 +419,7 @@ impl GenericArgs<'_> {
 
     pub fn inputs(&self) -> &[Ty<'_>] {
         if self.parenthesized {
-            for arg in &self.args {
+            for arg in self.args {
                 match arg {
                     GenericArg::Lifetime(_) => {}
                     GenericArg::Type(ref ty) => {
@@ -458,7 +441,7 @@ impl GenericArgs<'_> {
         // presence of this method will be a constant reminder.
         let mut own_counts: GenericParamCount = Default::default();
 
-        for arg in &self.args {
+        for arg in self.args {
             match arg {
                 GenericArg::Lifetime(_) => own_counts.lifetimes += 1,
                 GenericArg::Type(_) => own_counts.types += 1,
@@ -555,7 +538,7 @@ pub struct GenericParamCount {
 /// of a function, enum, trait, etc.
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Generics<'hir> {
-    pub params: HirVec<GenericParam<'hir>>,
+    pub params: &'hir [GenericParam<'hir>],
     pub where_clause: WhereClause<'hir>,
     pub span: Span,
 }
@@ -563,7 +546,7 @@ pub struct Generics<'hir> {
 impl Generics<'hir> {
     pub const fn empty() -> Generics<'hir> {
         Generics {
-            params: HirVec::new(),
+            params: &[],
             where_clause: WhereClause { predicates: &[], span: DUMMY_SP },
             span: DUMMY_SP,
         }
@@ -575,7 +558,7 @@ impl Generics<'hir> {
         // presence of this method will be a constant reminder.
         let mut own_counts: GenericParamCount = Default::default();
 
-        for param in &self.params {
+        for param in self.params {
             match param.kind {
                 GenericParamKind::Lifetime { .. } => own_counts.lifetimes += 1,
                 GenericParamKind::Type { .. } => own_counts.types += 1,
@@ -587,7 +570,7 @@ impl Generics<'hir> {
     }
 
     pub fn get_named(&self, name: Symbol) -> Option<&GenericParam<'_>> {
-        for param in &self.params {
+        for param in self.params {
             if name == param.name.ident().name {
                 return Some(param);
             }
@@ -2128,7 +2111,7 @@ pub struct InlineAsmOutput {
 }
 
 // NOTE(eddyb) This is used within MIR as well, so unlike the rest of the HIR,
-// it needs to be `Clone` and use plain `Vec<T>` instead of `HirVec<T>`.
+// it needs to be `Clone` and use plain `Vec<T>` instead of arena-allocated slice.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable, PartialEq)]
 pub struct InlineAsmInner {
     pub asm: Symbol,
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 61afdab3e1c..ae760d22f75 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::HirVec;
 use crate::hir::{GenericArg, GenericParam, GenericParamKind};
 use crate::hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier};
 
@@ -2097,7 +2096,7 @@ impl<'a> State<'a> {
             self.print_generic_params(generic_params);
         }
         let generics = hir::Generics {
-            params: HirVec::new(),
+            params: &[],
             where_clause: hir::WhereClause { predicates: &[], span: syntax_pos::DUMMY_SP },
             span: syntax_pos::DUMMY_SP,
         };
diff --git a/src/librustc/hir/ptr.rs b/src/librustc/hir/ptr.rs
deleted file mode 100644
index b43817c9601..00000000000
--- a/src/librustc/hir/ptr.rs
+++ /dev/null
@@ -1,128 +0,0 @@
-// HACK(eddyb) this is a copy of `syntax::ptr`, minus the mutation (the HIR is
-// frozen anyway). The only reason for doing this instead of replacing `P<T>`
-// with `Box<T>` in HIR, is that `&Box<[T]>` doesn't implement `IntoIterator`.
-
-use std::fmt::{self, Debug, Display};
-use std::iter::FromIterator;
-use std::ops::Deref;
-use std::{slice, vec};
-
-use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
-
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-/// An owned smart pointer.
-#[derive(PartialEq, Eq)]
-pub struct P<T: ?Sized> {
-    ptr: Box<T>,
-}
-
-/// Construct a `P<T>` from a `T` value.
-#[allow(non_snake_case)]
-pub fn P<T: 'static>(value: T) -> P<T> {
-    P { ptr: box value }
-}
-
-impl<T: ?Sized> Deref for P<T> {
-    type Target = T;
-
-    fn deref(&self) -> &T {
-        &self.ptr
-    }
-}
-
-impl<T: ?Sized + Debug> Debug for P<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        Debug::fmt(&self.ptr, f)
-    }
-}
-
-impl<T: Display> Display for P<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        Display::fmt(&**self, f)
-    }
-}
-
-impl<T: 'static + Decodable> Decodable for P<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<P<T>, D::Error> {
-        Decodable::decode(d).map(P)
-    }
-}
-
-impl<T: Encodable> Encodable for P<T> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        (**self).encode(s)
-    }
-}
-
-impl<T> P<[T]> {
-    pub const fn new() -> P<[T]> {
-        // HACK(eddyb) bypass the lack of a `const fn` to create an empty `Box<[T]>`
-        // (as trait methods, `default` in this case, can't be `const fn` yet).
-        P {
-            ptr: unsafe {
-                use std::ptr::NonNull;
-                std::mem::transmute(NonNull::<[T; 0]>::dangling() as NonNull<[T]>)
-            },
-        }
-    }
-
-    #[inline(never)]
-    pub fn from_vec(v: Vec<T>) -> P<[T]> {
-        P { ptr: v.into_boxed_slice() }
-    }
-
-    // HACK(eddyb) used by HIR lowering in a few places still.
-    // NOTE: do not make this more public than `pub(super)`,
-    // and do not make this into an `IntoIterator` impl.
-    pub(super) fn into_iter(self) -> vec::IntoIter<T> {
-        self.ptr.into_vec().into_iter()
-    }
-}
-
-impl<T> Default for P<[T]> {
-    /// Creates an empty `P<[T]>`.
-    fn default() -> P<[T]> {
-        P::new()
-    }
-}
-
-impl<T> From<Vec<T>> for P<[T]> {
-    fn from(v: Vec<T>) -> Self {
-        P::from_vec(v)
-    }
-}
-
-impl<T> FromIterator<T> for P<[T]> {
-    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> P<[T]> {
-        P::from_vec(iter.into_iter().collect())
-    }
-}
-
-impl<'a, T> IntoIterator for &'a P<[T]> {
-    type Item = &'a T;
-    type IntoIter = slice::Iter<'a, T>;
-    fn into_iter(self) -> Self::IntoIter {
-        self.ptr.into_iter()
-    }
-}
-
-impl<T: Encodable> Encodable for P<[T]> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        Encodable::encode(&**self, s)
-    }
-}
-
-impl<T: Decodable> Decodable for P<[T]> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<P<[T]>, D::Error> {
-        Ok(P::from_vec(Decodable::decode(d)?))
-    }
-}
-
-impl<CTX, T> HashStable<CTX> for P<T>
-where
-    T: ?Sized + HashStable<CTX>,
-{
-    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
-        (**self).hash_stable(hcx, hasher);
-    }
-}
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 76588dfa5e2..4e7913b8dfc 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -28,6 +28,7 @@
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 #![feature(arbitrary_self_types)]
+#![feature(array_value_iter)]
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 29e3bcfe6a1..5f8a58636c0 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -657,7 +657,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 let mut elision = None;
                 let mut lifetimes = FxHashMap::default();
                 let mut non_lifetime_count = 0;
-                for param in &generics.params {
+                for param in generics.params {
                     match param.kind {
                         GenericParamKind::Lifetime { .. } => {
                             let (name, reg) = Region::early(&self.tcx.hir(), &mut index, &param);
@@ -899,7 +899,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
 
     fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
         check_mixed_explicit_and_in_band_defs(self.tcx, &generics.params);
-        for param in &generics.params {
+        for param in generics.params {
             match param.kind {
                 GenericParamKind::Lifetime { .. } => {}
                 GenericParamKind::Type { ref default, .. } => {
@@ -1996,7 +1996,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         debug!("visit_segment_args: object_lifetime_defaults={:?}", object_lifetime_defaults);
 
         let mut i = 0;
-        for arg in &generic_args.args {
+        for arg in generic_args.args {
             match arg {
                 GenericArg::Lifetime(_) => {}
                 GenericArg::Type(ty) => {
@@ -2789,7 +2789,7 @@ fn insert_late_bound_lifetimes(
     let mut appears_in_where_clause = AllCollector::default();
     appears_in_where_clause.visit_generics(generics);
 
-    for param in &generics.params {
+    for param in generics.params {
         if let hir::GenericParamKind::Lifetime { .. } = param.kind {
             if !param.bounds.is_empty() {
                 // `'a: 'b` means both `'a` and `'b` are referenced
@@ -2809,7 +2809,7 @@ fn insert_late_bound_lifetimes(
     // - appear in the inputs
     // - do not appear in the where-clauses
     // - are not implicitly captured by `impl Trait`
-    for param in &generics.params {
+    for param in generics.params {
         match param.kind {
             hir::GenericParamKind::Lifetime { .. } => { /* fall through */ }
 
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 0f7bdaaf582..9cf49f8ab4b 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -841,7 +841,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
         match it.kind {
             hir::ItemKind::Fn(.., ref generics, _) => {
                 if let Some(no_mangle_attr) = attr::find_by_name(&it.attrs, sym::no_mangle) {
-                    for param in &generics.params {
+                    for param in generics.params {
                         match param.kind {
                             GenericParamKind::Lifetime { .. } => {}
                             GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
@@ -1663,7 +1663,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements {
             let mut bound_count = 0;
             let mut lint_spans = Vec::new();
 
-            for param in &hir_generics.params {
+            for param in hir_generics.params {
                 let has_lifetime_bounds = param.bounds.iter().any(|bound| {
                     if let hir::GenericBound::Outlives(_) = bound { true } else { false }
                 });
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index 0fe53011d4f..b14c9c0eb59 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -1569,7 +1569,7 @@ impl EncodeContext<'tcx> {
     }
 
     fn encode_info_for_generics(&mut self, generics: &hir::Generics<'tcx>) {
-        for param in &generics.params {
+        for param in generics.params {
             let def_id = self.tcx.hir().local_def_id(param.hir_id);
             match param.kind {
                 GenericParamKind::Lifetime { .. } => continue,
diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs
index 2c480b8e9dc..33a37ecb7f5 100644
--- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs
@@ -619,7 +619,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         args: &'hir hir::GenericArgs<'hir>,
         search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>,
     ) -> Option<&'hir hir::Lifetime> {
-        for (kind, hir_arg) in substs.iter().zip(&args.args) {
+        for (kind, hir_arg) in substs.iter().zip(args.args) {
             match (kind.unpack(), hir_arg) {
                 (GenericArgKind::Lifetime(r), hir::GenericArg::Lifetime(lt)) => {
                     if r.to_region_vid() == needle_fr {
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 0a783337ad1..844bebdf7b8 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -1132,7 +1132,7 @@ fn create_mono_items_for_default_impls<'tcx>(
 ) {
     match item.kind {
         hir::ItemKind::Impl(_, _, _, ref generics, .., ref impl_item_refs) => {
-            for param in &generics.params {
+            for param in generics.params {
                 match param.kind {
                     hir::GenericParamKind::Lifetime { .. } => {}
                     hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => {
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index c00f5752e1b..d666c80b899 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -1653,7 +1653,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
     }
 
     fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
-        for param in &generics.params {
+        for param in generics.params {
             for bound in param.bounds {
                 self.check_generic_bound(bound);
             }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index f3ac159a3aa..569be6e1a55 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -5,8 +5,7 @@
 use crate::hir::def::{CtorOf, DefKind, Res};
 use crate::hir::def_id::DefId;
 use crate::hir::print;
-use crate::hir::ptr::P;
-use crate::hir::{self, ExprKind, GenericArg, GenericArgs, HirVec};
+use crate::hir::{self, ExprKind, GenericArg, GenericArgs};
 use crate::lint;
 use crate::middle::lang_items::SizedTraitLangItem;
 use crate::middle::resolve_lifetime as rl;
@@ -255,8 +254,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         seg: &hir::PathSegment<'_>,
         is_method_call: bool,
     ) -> bool {
-        let empty_args =
-            P(hir::GenericArgs { args: HirVec::new(), bindings: &[], parenthesized: false });
+        let empty_args = hir::GenericArgs::none();
         let suppress_mismatch = Self::check_impl_trait(tcx, seg, &def);
         Self::check_generic_arg_count(
             tcx,
@@ -2278,7 +2276,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let mut has_err = false;
         for segment in segments {
             let (mut err_for_lt, mut err_for_ty, mut err_for_ct) = (false, false, false);
-            for arg in &segment.generic_args().args {
+            for arg in segment.generic_args().args {
                 let (span, kind) = match arg {
                     hir::GenericArg::Lifetime(lt) => {
                         if err_for_lt {
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 1df6a495343..552e6a57c1d 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -54,7 +54,6 @@ use crate::check::{FnCtxt, Needs};
 use errors::DiagnosticBuilder;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
-use rustc::hir::ptr::P;
 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc::infer::{Coercion, InferOk, InferResult};
 use rustc::traits::{self, ObligationCause, ObligationCauseCode};
@@ -1377,12 +1376,6 @@ impl AsCoercionSite for hir::Expr<'_> {
     }
 }
 
-impl AsCoercionSite for P<hir::Expr<'_>> {
-    fn as_coercion_site(&self) -> &hir::Expr<'_> {
-        self
-    }
-}
-
 impl<'a, T> AsCoercionSite for &'a T
 where
     T: AsCoercionSite,
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index e1a78fffa90..b387a5d1520 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -83,7 +83,7 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> {
                 }
                 Err(traits::OrphanCheckErr::UncoveredTy(param_ty, local_type)) => {
                     let mut sp = sp;
-                    for param in &generics.params {
+                    for param in generics.params {
                         if param.name.ident().to_string() == param_ty.to_string() {
                             sp = param.span;
                         }
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 9604a9ade92..1e3e6d77b92 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -117,7 +117,7 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
     }
 
     fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
-        for param in &generics.params {
+        for param in generics.params {
             match param.kind {
                 hir::GenericParamKind::Lifetime { .. } => {}
                 hir::GenericParamKind::Type { default: Some(_), .. } => {
@@ -860,7 +860,7 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
             outer_index: ty::INNERMOST,
             has_late_bound_regions: None,
         };
-        for param in &generics.params {
+        for param in generics.params {
             if let GenericParamKind::Lifetime { .. } = param.kind {
                 if tcx.is_late_bound(param.hir_id) {
                     return Some(param.span);
@@ -2102,7 +2102,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
 
     // Collect the predicates that were written inline by the user on each
     // type parameter (e.g., `<T: Foo>`).
-    for param in &ast_generics.params {
+    for param in ast_generics.params {
         if let GenericParamKind::Type { .. } = param.kind {
             let name = param.name.ident().name;
             let param_ty = ty::ParamTy::new(index, name).to_ty(tcx);
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 35e26819b10..e12d9affdfa 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -474,7 +474,7 @@ fn build_macro(cx: &DocContext<'_>, did: DefId, name: ast::Name) -> clean::ItemE
     let imported_from = cx.tcx.original_crate_name(did.krate);
     match cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())) {
         LoadedMacro::MacroDef(def, _) => {
-            let matchers: hir::HirVec<Span> = if let ast::ItemKind::MacroDef(ref def) = def.kind {
+            let matchers: Vec<Span> = if let ast::ItemKind::MacroDef(ref def) = def.kind {
                 let tts: Vec<_> = def.body.inner_tokens().into_trees().collect();
                 tts.chunks(4).map(|arm| arm[0].span()).collect()
             } else {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index db17d23c910..defdeb52186 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -12,7 +12,6 @@ pub mod utils;
 use rustc::hir;
 use rustc::hir::def::{CtorKind, DefKind, Res};
 use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
-use rustc::hir::ptr::P;
 use rustc::infer::region_constraints::{Constraint, RegionConstraintData};
 use rustc::middle::lang_items;
 use rustc::middle::resolve_lifetime as rl;
@@ -74,12 +73,6 @@ impl<T: Clean<U>, U> Clean<U> for &T {
     }
 }
 
-impl<T: Clean<U>, U> Clean<U> for P<T> {
-    fn clean(&self, cx: &DocContext<'_>) -> U {
-        (**self).clean(cx)
-    }
-}
-
 impl<T: Clean<U>, U> Clean<U> for Rc<T> {
     fn clean(&self, cx: &DocContext<'_>) -> U {
         (**self).clean(cx)
@@ -101,12 +94,6 @@ where
     }
 }
 
-impl<T: Clean<U>, U> Clean<Vec<U>> for P<[T]> {
-    fn clean(&self, cx: &DocContext<'_>) -> Vec<U> {
-        self.iter().map(|x| x.clean(cx)).collect()
-    }
-}
-
 impl Clean<ExternalCrate> for CrateNum {
     fn clean(&self, cx: &DocContext<'_>) -> ExternalCrate {
         let root = DefId { krate: *self, index: CRATE_DEF_INDEX };
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 46eddede0d5..07a3f663145 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -230,7 +230,7 @@ pub struct Macro<'hir> {
     pub def_id: hir::def_id::DefId,
     pub attrs: &'hir [ast::Attribute],
     pub whence: Span,
-    pub matchers: hir::HirVec<Span>,
+    pub matchers: Vec<Span>,
     pub imported_from: Option<Name>,
 }