]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/hir/lowering.rs
Retire HirVec.
[rust.git] / src / librustc / hir / lowering.rs
index 5fca5f061caf2896fd82ed0db20bcb3d63e72426..e4836ef4eef8928ea75f65f833f461b5f270c63a 100644 (file)
@@ -38,7 +38,6 @@
 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;
@@ -46,6 +45,7 @@
 use crate::middle::cstore::CrateStore;
 use crate::session::config::nightly_options;
 use crate::session::Session;
+use crate::util::captures::Captures;
 use crate::util::common::FN_OUTPUT_NAME;
 use crate::util::nodemap::{DefIdMap, NodeMap};
 use errors::Applicability;
@@ -207,13 +207,13 @@ fn resolve_str_path(
 /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
 /// and if so, what meaning it has.
 #[derive(Debug)]
-enum ImplTraitContext<'a> {
+enum ImplTraitContext<'b, 'a> {
     /// Treat `impl Trait` as shorthand for a new universal generic parameter.
     /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
     /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
     ///
     /// Newly generated parameters should be inserted into the given `Vec`.
-    Universal(&'a mut Vec<hir::GenericParam>),
+    Universal(&'b mut Vec<hir::GenericParam<'a>>),
 
     /// Treat `impl Trait` as shorthand for a new opaque type.
     /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
@@ -238,13 +238,13 @@ enum ImplTraitPosition {
     Other,
 }
 
-impl<'a> ImplTraitContext<'a> {
+impl<'b, 'a> ImplTraitContext<'b, 'a> {
     #[inline]
     fn disallowed() -> Self {
         ImplTraitContext::Disallowed(ImplTraitPosition::Other)
     }
 
-    fn reborrow(&'b mut self) -> ImplTraitContext<'b> {
+    fn reborrow(&'c mut self) -> ImplTraitContext<'c, 'a> {
         use self::ImplTraitContext::*;
         match self {
             Universal(params) => Universal(params),
@@ -539,7 +539,7 @@ fn visit_ty(&mut self, t: &'tcx Ty) {
         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);
@@ -741,9 +741,9 @@ fn collect_in_band_defs<T, F>(
         parent_id: DefId,
         anonymous_lifetime_mode: AnonymousLifetimeMode,
         f: F,
-    ) -> (Vec<hir::GenericParam>, T)
+    ) -> (Vec<hir::GenericParam<'hir>>, T)
     where
-        F: FnOnce(&mut LoweringContext<'_, '_>) -> (Vec<hir::GenericParam>, T),
+        F: FnOnce(&mut Self) -> (Vec<hir::GenericParam<'hir>>, T),
     {
         assert!(!self.is_collecting_in_band_lifetimes);
         assert!(self.lifetimes_to_define.is_empty());
@@ -774,7 +774,7 @@ fn lifetime_to_generic_param(
         span: Span,
         hir_name: ParamName,
         parent_index: DefIndex,
-    ) -> hir::GenericParam {
+    ) -> hir::GenericParam<'hir> {
         let node_id = self.resolver.next_node_id();
 
         // Get the name we'll use to make the def-path. Note
@@ -798,8 +798,8 @@ fn lifetime_to_generic_param(
         hir::GenericParam {
             hir_id: self.lower_node_id(node_id),
             name: hir_name,
-            attrs: hir_vec![],
-            bounds: hir_vec![],
+            attrs: &[],
+            bounds: &[],
             span,
             pure_wrt_drop: false,
             kind: hir::GenericParamKind::Lifetime { kind },
@@ -849,7 +849,7 @@ fn collect_fresh_in_band_lifetime(&mut self, span: Span) -> ParamName {
     // for them.
     fn with_in_scope_lifetime_defs<T, F>(&mut self, params: &[GenericParam], f: F) -> T
     where
-        F: FnOnce(&mut LoweringContext<'_, 'hir>) -> T,
+        F: FnOnce(&mut Self) -> T,
     {
         let old_len = self.in_scope_lifetimes.len();
         let lt_def_names = params.iter().filter_map(|param| match param.kind {
@@ -876,9 +876,9 @@ fn add_in_band_defs<F, T>(
         parent_id: DefId,
         anonymous_lifetime_mode: AnonymousLifetimeMode,
         f: F,
-    ) -> (hir::Generics, T)
+    ) -> (hir::Generics<'hir>, T)
     where
-        F: FnOnce(&mut LoweringContext<'_, '_>, &mut Vec<hir::GenericParam>) -> T,
+        F: FnOnce(&mut Self, &mut Vec<hir::GenericParam<'hir>>) -> T,
     {
         let (in_band_defs, (mut lowered_generics, res)) =
             self.with_in_scope_lifetime_defs(&generics.params, |this| {
@@ -892,7 +892,7 @@ fn add_in_band_defs<F, T>(
                     // 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))
                 })
@@ -913,12 +913,13 @@ fn add_in_band_defs<F, T>(
 
         lowered_generics.params = lowered_params.into();
 
+        let lowered_generics = lowered_generics.into_generics(self.arena);
         (lowered_generics, res)
     }
 
     fn with_dyn_type_scope<T, F>(&mut self, in_scope: bool, f: F) -> T
     where
-        F: FnOnce(&mut LoweringContext<'_, '_>) -> T,
+        F: FnOnce(&mut Self) -> T,
     {
         let was_in_dyn_type = self.is_in_dyn_type;
         self.is_in_dyn_type = in_scope;
@@ -956,14 +957,10 @@ fn def_key(&mut self, id: DefId) -> DefKey {
         }
     }
 
-    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
@@ -1027,8 +1024,8 @@ fn lower_token(&mut self, token: Token) -> TokenStream {
     fn lower_assoc_ty_constraint(
         &mut self,
         constraint: &AssocTyConstraint,
-        itctx: ImplTraitContext<'_>,
-    ) -> hir::TypeBinding {
+        itctx: ImplTraitContext<'_, 'hir>,
+    ) -> hir::TypeBinding<'hir> {
         debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
 
         let kind = match constraint.kind {
@@ -1124,8 +1121,8 @@ fn lower_assoc_ty_constraint(
     fn lower_generic_arg(
         &mut self,
         arg: &ast::GenericArg,
-        itctx: ImplTraitContext<'_>,
-    ) -> hir::GenericArg {
+        itctx: ImplTraitContext<'_, 'hir>,
+    ) -> hir::GenericArg<'hir> {
         match arg {
             ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)),
             ast::GenericArg::Type(ty) => {
@@ -1180,8 +1177,8 @@ fn lower_generic_arg(
         }
     }
 
-    fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext<'_>) -> P<hir::Ty> {
-        P(self.lower_ty_direct(t, itctx))
+    fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext<'_, 'hir>) -> &'hir hir::Ty<'hir> {
+        self.arena.alloc(self.lower_ty_direct(t, itctx))
     }
 
     fn lower_path_ty(
@@ -1190,8 +1187,8 @@ fn lower_path_ty(
         qself: &Option<QSelf>,
         path: &Path,
         param_mode: ParamMode,
-        itctx: ImplTraitContext<'_>,
-    ) -> hir::Ty {
+        itctx: ImplTraitContext<'_, 'hir>,
+    ) -> hir::Ty<'hir> {
         let id = self.lower_node_id(t.id);
         let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
         let ty = self.ty_path(id, t.span, qpath);
@@ -1201,15 +1198,15 @@ fn lower_path_ty(
         ty
     }
 
-    fn ty(&mut self, span: Span, kind: hir::TyKind) -> hir::Ty {
+    fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
         hir::Ty { hir_id: self.next_id(), kind, span }
     }
 
-    fn ty_tup(&mut self, span: Span, tys: HirVec<hir::Ty>) -> hir::Ty {
+    fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
         self.ty(span, hir::TyKind::Tup(tys))
     }
 
-    fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::Ty {
+    fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_, 'hir>) -> hir::Ty<'hir> {
         let kind = match t.kind {
             TyKind::Infer => hir::TyKind::Infer,
             TyKind::Err => hir::TyKind::Err,
@@ -1225,7 +1222,7 @@ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::T
             }
             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(P(hir::BareFnTy {
+                    hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy {
                         generic_params: this.lower_generic_params(
                             &f.generic_params,
                             &NodeMap::default(),
@@ -1239,9 +1236,11 @@ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::T
                 })
             }),
             TyKind::Never => hir::TyKind::Never,
-            TyKind::Tup(ref tys) => hir::TyKind::Tup(
-                tys.iter().map(|ty| self.lower_ty_direct(ty, itctx.reborrow())).collect(),
-            ),
+            TyKind::Tup(ref tys) => {
+                hir::TyKind::Tup(self.arena.alloc_from_iter(
+                    tys.iter().map(|ty| self.lower_ty_direct(ty, itctx.reborrow())),
+                ))
+            }
             TyKind::Paren(ref ty) => {
                 return self.lower_ty_direct(ty, itctx);
             }
@@ -1253,11 +1252,11 @@ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::T
                 let res = self.lower_res(res);
                 hir::TyKind::Path(hir::QPath::Resolved(
                     None,
-                    P(hir::Path {
+                    self.arena.alloc(hir::Path {
                         res,
-                        segments: hir_vec![hir::PathSegment::from_ident(Ident::with_dummy_span(
-                            kw::SelfUpper
-                        ))],
+                        segments: arena_vec![self; hir::PathSegment::from_ident(
+                            Ident::with_dummy_span(kw::SelfUpper)
+                        )],
                         span: t.span,
                     }),
                 ))
@@ -1269,21 +1268,21 @@ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::T
             TyKind::TraitObject(ref bounds, kind) => {
                 let mut lifetime_bound = None;
                 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
-                    let bounds = bounds
-                        .iter()
-                        .filter_map(|bound| match *bound {
-                            GenericBound::Trait(ref ty, TraitBoundModifier::None) => {
-                                Some(this.lower_poly_trait_ref(ty, itctx.reborrow()))
-                            }
-                            GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
-                            GenericBound::Outlives(ref lifetime) => {
-                                if lifetime_bound.is_none() {
-                                    lifetime_bound = Some(this.lower_lifetime(lifetime));
+                    let bounds =
+                        this.arena.alloc_from_iter(bounds.iter().filter_map(
+                            |bound| match *bound {
+                                GenericBound::Trait(ref ty, TraitBoundModifier::None) => {
+                                    Some(this.lower_poly_trait_ref(ty, itctx.reborrow()))
                                 }
-                                None
-                            }
-                        })
-                        .collect();
+                                GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
+                                GenericBound::Outlives(ref lifetime) => {
+                                    if lifetime_bound.is_none() {
+                                        lifetime_bound = Some(this.lower_lifetime(lifetime));
+                                    }
+                                    None
+                                }
+                            },
+                        ));
                     let lifetime_bound =
                         lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
                     (bounds, lifetime_bound)
@@ -1316,7 +1315,7 @@ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::T
                             hir_id: self.lower_node_id(def_node_id),
                             name: ParamName::Plain(ident),
                             pure_wrt_drop: false,
-                            attrs: hir_vec![],
+                            attrs: &[],
                             bounds: hir_bounds,
                             span,
                             kind: hir::GenericParamKind::Type {
@@ -1327,10 +1326,10 @@ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::T
 
                         hir::TyKind::Path(hir::QPath::Resolved(
                             None,
-                            P(hir::Path {
+                            self.arena.alloc(hir::Path {
                                 span,
                                 res: Res::Def(DefKind::TyParam, DefId::local(def_index)),
-                                segments: hir_vec![hir::PathSegment::from_ident(ident)],
+                                segments: arena_vec![self; hir::PathSegment::from_ident(ident)],
                             }),
                         ))
                     }
@@ -1378,8 +1377,8 @@ fn lower_opaque_impl_trait(
         span: Span,
         fn_def_id: Option<DefId>,
         opaque_ty_node_id: NodeId,
-        lower_bounds: impl FnOnce(&mut LoweringContext<'_, '_>) -> hir::GenericBounds,
-    ) -> hir::TyKind {
+        lower_bounds: impl FnOnce(&mut Self) -> hir::GenericBounds<'hir>,
+    ) -> hir::TyKind<'hir> {
         debug!(
             "lower_opaque_impl_trait(fn_def_id={:?}, opaque_ty_node_id={:?}, span={:?})",
             fn_def_id, opaque_ty_node_id, span,
@@ -1409,11 +1408,11 @@ fn lower_opaque_impl_trait(
 
         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,
-                    where_clause: hir::WhereClause { predicates: hir_vec![], span },
+                    where_clause: hir::WhereClause { predicates: &[], span },
                     span,
                 },
                 bounds: hir_bounds,
@@ -1435,7 +1434,7 @@ fn lower_opaque_impl_trait(
     fn generate_opaque_type(
         &mut self,
         opaque_ty_node_id: NodeId,
-        opaque_ty_item: hir::OpaqueTy,
+        opaque_ty_item: hir::OpaqueTy<'hir>,
         span: Span,
         opaque_ty_span: Span,
     ) -> hir::HirId {
@@ -1463,8 +1462,8 @@ fn lifetimes_from_impl_trait_bounds(
         &mut self,
         opaque_ty_id: NodeId,
         parent_index: DefIndex,
-        bounds: &hir::GenericBounds,
-    ) -> (HirVec<hir::GenericArg>, HirVec<hir::GenericParam>) {
+        bounds: hir::GenericBounds<'hir>,
+    ) -> (&'hir [hir::GenericArg<'hir>], &'hir [hir::GenericParam<'hir>]) {
         debug!(
             "lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \
              parent_index={:?}, \
@@ -1482,8 +1481,8 @@ struct ImplTraitLifetimeCollector<'r, 'a, 'hir> {
             collect_elided_lifetimes: bool,
             currently_bound_lifetimes: Vec<hir::LifetimeName>,
             already_defined_lifetimes: FxHashSet<hir::LifetimeName>,
-            output_lifetimes: Vec<hir::GenericArg>,
-            output_lifetime_params: Vec<hir::GenericParam>,
+            output_lifetimes: Vec<hir::GenericArg<'hir>>,
+            output_lifetime_params: Vec<hir::GenericParam<'hir>>,
         }
 
         impl<'r, 'a, 'v, 'hir> hir::intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a, 'hir> {
@@ -1493,7 +1492,7 @@ fn nested_visit_map<'this>(
                 hir::intravisit::NestedVisitorMap::None
             }
 
-            fn visit_generic_args(&mut self, span: Span, parameters: &'v hir::GenericArgs) {
+            fn visit_generic_args(&mut self, span: Span, parameters: &'v hir::GenericArgs<'v>) {
                 // Don't collect elided lifetimes used inside of `Fn()` syntax.
                 if parameters.parenthesized {
                     let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
@@ -1505,7 +1504,7 @@ fn visit_generic_args(&mut self, span: Span, parameters: &'v hir::GenericArgs) {
                 }
             }
 
-            fn visit_ty(&mut self, t: &'v hir::Ty) {
+            fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
                 // Don't collect elided lifetimes used inside of `fn()` syntax.
                 if let hir::TyKind::BareFn(_) = t.kind {
                     let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
@@ -1525,7 +1524,7 @@ fn visit_ty(&mut self, t: &'v hir::Ty) {
 
             fn visit_poly_trait_ref(
                 &mut self,
-                trait_ref: &'v hir::PolyTraitRef,
+                trait_ref: &'v hir::PolyTraitRef<'v>,
                 modifier: hir::TraitBoundModifier,
             ) {
                 // Record the "stack height" of `for<'a>` lifetime bindings
@@ -1535,7 +1534,7 @@ fn visit_poly_trait_ref(
                 self.currently_bound_lifetimes.truncate(old_len);
             }
 
-            fn visit_generic_param(&mut self, param: &'v hir::GenericParam) {
+            fn visit_generic_param(&mut self, param: &'v hir::GenericParam<'v>) {
                 // Record the introduction of 'a in `for<'a> ...`.
                 if let hir::GenericParamKind::Lifetime { .. } = param.kind {
                     // Introduce lifetimes one at a time so that we can handle
@@ -1605,8 +1604,8 @@ fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
                         name,
                         span: lifetime.span,
                         pure_wrt_drop: false,
-                        attrs: hir_vec![],
-                        bounds: hir_vec![],
+                        attrs: &[],
+                        bounds: &[],
                         kind: hir::GenericParamKind::Lifetime { kind },
                     });
                 }
@@ -1628,9 +1627,12 @@ fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
             hir::intravisit::walk_param_bound(&mut lifetime_collector, &bound);
         }
 
+        let ImplTraitLifetimeCollector { output_lifetimes, output_lifetime_params, .. } =
+            lifetime_collector;
+
         (
-            lifetime_collector.output_lifetimes.into(),
-            lifetime_collector.output_lifetime_params.into(),
+            self.arena.alloc_from_iter(output_lifetimes),
+            self.arena.alloc_from_iter(output_lifetime_params),
         )
     }
 
@@ -1640,8 +1642,8 @@ fn lower_qpath(
         qself: &Option<QSelf>,
         p: &Path,
         param_mode: ParamMode,
-        mut itctx: ImplTraitContext<'_>,
-    ) -> hir::QPath {
+        mut itctx: ImplTraitContext<'_, 'hir>,
+    ) -> hir::QPath<'hir> {
         let qself_position = qself.as_ref().map(|q| q.position);
         let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx.reborrow()));
 
@@ -1649,12 +1651,10 @@ fn lower_qpath(
             self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err));
 
         let proj_start = p.segments.len() - partial_res.unresolved_segments();
-        let path = P(hir::Path {
+        let path = self.arena.alloc(hir::Path {
             res: self.lower_res(partial_res.base_res()),
-            segments: p.segments[..proj_start]
-                .iter()
-                .enumerate()
-                .map(|(i, segment)| {
+            segments: self.arena.alloc_from_iter(p.segments[..proj_start].iter().enumerate().map(
+                |(i, segment)| {
                     let param_mode = match (qself_position, param_mode) {
                         (Some(j), ParamMode::Optional) if i < j => {
                             // This segment is part of the trait path in a
@@ -1730,8 +1730,8 @@ fn lower_qpath(
                         itctx.reborrow(),
                         None,
                     )
-                })
-                .collect(),
+                },
+            )),
             span: p.span,
         });
 
@@ -1751,7 +1751,7 @@ fn lower_qpath(
             // e.g., `Vec` in `Vec::new` or `<I as Iterator>::Item` in
             // `<I as Iterator>::Item::default`.
             let new_id = self.next_id();
-            P(self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path)))
+            self.arena.alloc(self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path)))
         };
 
         // Anything after the base path are associated "extensions",
@@ -1765,7 +1765,7 @@ fn lower_qpath(
         //   3. `<<std::vec::Vec<T>>::IntoIter>::Item`
         // * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
         for (i, segment) in p.segments.iter().enumerate().skip(proj_start) {
-            let segment = P(self.lower_path_segment(
+            let segment = self.arena.alloc(self.lower_path_segment(
                 p.span,
                 segment,
                 param_mode,
@@ -1783,7 +1783,7 @@ fn lower_qpath(
 
             // Wrap the associated extension in another type node.
             let new_id = self.next_id();
-            ty = P(self.ty_path(new_id, p.span, qpath));
+            ty = self.arena.alloc(self.ty_path(new_id, p.span, qpath));
         }
 
         // We should've returned in the for loop above.
@@ -1801,29 +1801,25 @@ fn lower_path_extra(
         p: &Path,
         param_mode: ParamMode,
         explicit_owner: Option<NodeId>,
-    ) -> hir::Path {
+    ) -> hir::Path<'hir> {
         hir::Path {
             res,
-            segments: p
-                .segments
-                .iter()
-                .map(|segment| {
-                    self.lower_path_segment(
-                        p.span,
-                        segment,
-                        param_mode,
-                        0,
-                        ParenthesizedGenericArgs::Err,
-                        ImplTraitContext::disallowed(),
-                        explicit_owner,
-                    )
-                })
-                .collect(),
+            segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| {
+                self.lower_path_segment(
+                    p.span,
+                    segment,
+                    param_mode,
+                    0,
+                    ParenthesizedGenericArgs::Err,
+                    ImplTraitContext::disallowed(),
+                    explicit_owner,
+                )
+            })),
             span: p.span,
         }
     }
 
-    fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path {
+    fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path<'hir> {
         let res = self.expect_full_res(id);
         let res = self.lower_res(res);
         self.lower_path_extra(res, p, param_mode, None)
@@ -1836,9 +1832,9 @@ fn lower_path_segment(
         param_mode: ParamMode,
         expected_lifetimes: usize,
         parenthesized_generic_args: ParenthesizedGenericArgs,
-        itctx: ImplTraitContext<'_>,
+        itctx: ImplTraitContext<'_, 'hir>,
         explicit_owner: Option<NodeId>,
-    ) -> hir::PathSegment {
+    ) -> hir::PathSegment<'hir> {
         let (mut generic_args, infer_args) = if let Some(ref generic_args) = segment.args {
             let msg = "parenthesized type parameters may only be used with a `Fn` trait";
             match **generic_args {
@@ -1969,21 +1965,25 @@ fn lower_path_segment(
             segment.ident, segment.id, id,
         );
 
-        hir::PathSegment::new(
-            segment.ident,
-            Some(id),
-            Some(self.lower_res(res)),
-            generic_args,
+        hir::PathSegment {
+            ident: segment.ident,
+            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.into_generic_args(self.arena)))
+            },
+        }
     }
 
     fn lower_angle_bracketed_parameter_data(
         &mut self,
         data: &AngleBracketedArgs,
         param_mode: ParamMode,
-        mut itctx: ImplTraitContext<'_>,
-    ) -> (hir::GenericArgs, bool) {
+        mut itctx: ImplTraitContext<'_, 'hir>,
+    ) -> (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,
@@ -1991,12 +1991,11 @@ fn lower_angle_bracketed_parameter_data(
             ast::GenericArg::Const(_) => true,
         });
         (
-            hir::GenericArgs {
+            GenericArgsCtor {
                 args: args.iter().map(|a| self.lower_generic_arg(a, itctx.reborrow())).collect(),
-                bindings: constraints
-                    .iter()
-                    .map(|b| self.lower_assoc_ty_constraint(b, itctx.reborrow()))
-                    .collect(),
+                bindings: self.arena.alloc_from_iter(
+                    constraints.iter().map(|b| self.lower_assoc_ty_constraint(b, itctx.reborrow())),
+                ),
                 parenthesized: false,
             },
             !has_non_lt_args && param_mode == ParamMode::Optional,
@@ -2006,7 +2005,7 @@ fn lower_angle_bracketed_parameter_data(
     fn lower_parenthesized_parameter_data(
         &mut self,
         data: &ParenthesizedArgs,
-    ) -> (hir::GenericArgs, 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
@@ -2014,22 +2013,24 @@ fn lower_parenthesized_parameter_data(
         // we generally don't permit such things (see #51008).
         self.with_anonymous_lifetime_mode(AnonymousLifetimeMode::PassThrough, |this| {
             let &ParenthesizedArgs { ref inputs, ref output, span } = data;
-            let inputs = inputs
-                .iter()
-                .map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed()))
-                .collect();
+            let inputs = this.arena.alloc_from_iter(
+                inputs.iter().map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed())),
+            );
             let output_ty = match output {
                 FunctionRetTy::Ty(ty) => this.lower_ty(&ty, ImplTraitContext::disallowed()),
-                FunctionRetTy::Default(_) => P(this.ty_tup(span, hir::HirVec::new())),
+                FunctionRetTy::Default(_) => this.arena.alloc(this.ty_tup(span, &[])),
             };
-            let args = hir_vec![GenericArg::Type(this.ty_tup(span, inputs))];
+            let args = vec![GenericArg::Type(this.ty_tup(span, inputs))];
             let binding = hir::TypeBinding {
                 hir_id: this.next_id(),
                 ident: Ident::with_dummy_span(FN_OUTPUT_NAME),
                 span: output_ty.span,
                 kind: hir::TypeBindingKind::Equality { ty: output_ty },
             };
-            (hir::GenericArgs { args, bindings: hir_vec![binding], parenthesized: true }, false)
+            (
+                GenericArgsCtor { args, bindings: arena_vec![this; binding], parenthesized: true },
+                false,
+            )
         })
     }
 
@@ -2052,7 +2053,6 @@ fn lower_parenthesized_parameter_data(
                 },
             )
         });
-        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 {
@@ -2068,7 +2068,7 @@ fn lower_parenthesized_parameter_data(
         )
     }
 
-    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`)
@@ -2076,13 +2076,10 @@ fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> hir::HirVec<Ident> {
         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.
@@ -2100,10 +2097,10 @@ fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> hir::HirVec<Ident> {
     fn lower_fn_decl(
         &mut self,
         decl: &FnDecl,
-        mut in_band_ty_params: Option<(DefId, &mut Vec<hir::GenericParam>)>,
+        mut in_band_ty_params: Option<(DefId, &mut Vec<hir::GenericParam<'hir>>)>,
         impl_trait_return_allow: bool,
         make_ret_async: Option<NodeId>,
-    ) -> P<hir::FnDecl> {
+    ) -> &'hir hir::FnDecl<'hir> {
         debug!(
             "lower_fn_decl(\
             fn_decl: {:?}, \
@@ -2133,16 +2130,13 @@ fn lower_fn_decl(
             if c_variadic {
                 inputs = &inputs[..inputs.len() - 1];
             }
-            inputs
-                .iter()
-                .map(|param| {
-                    if let Some((_, ibty)) = &mut in_band_ty_params {
-                        this.lower_ty_direct(&param.ty, ImplTraitContext::Universal(ibty))
-                    } else {
-                        this.lower_ty_direct(&param.ty, ImplTraitContext::disallowed())
-                    }
-                })
-                .collect::<HirVec<_>>()
+            this.arena.alloc_from_iter(inputs.iter().map(|param| {
+                if let Some((_, ibty)) = &mut in_band_ty_params {
+                    this.lower_ty_direct(&param.ty, ImplTraitContext::Universal(ibty))
+                } else {
+                    this.lower_ty_direct(&param.ty, ImplTraitContext::disallowed())
+                }
+            }))
         });
 
         let output = if let Some(ret_id) = make_ret_async {
@@ -2163,7 +2157,7 @@ fn lower_fn_decl(
             }
         };
 
-        P(hir::FnDecl {
+        self.arena.alloc(hir::FnDecl {
             inputs,
             output,
             c_variadic,
@@ -2209,7 +2203,7 @@ fn lower_async_fn_ret_ty(
         output: &FunctionRetTy,
         fn_def_id: DefId,
         opaque_ty_node_id: NodeId,
-    ) -> hir::FunctionRetTy {
+    ) -> hir::FunctionRetTy<'hir> {
         debug!(
             "lower_async_fn_ret_ty(\
              output={:?}, \
@@ -2309,21 +2303,18 @@ fn lower_async_fn_ret_ty(
             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()
-                .cloned()
-                .map(|(span, hir_name)| {
-                    this.lifetime_to_generic_param(span, hir_name, opaque_ty_def_index)
-                })
-                .collect();
+            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)
+                }));
 
             let opaque_ty_item = hir::OpaqueTy {
                 generics: hir::Generics {
                     params: generic_params,
-                    where_clause: hir::WhereClause { predicates: hir_vec![], span },
+                    where_clause: hir::WhereClause { predicates: &[], span },
                     span,
                 },
-                bounds: hir_vec![future_bound],
+                bounds: arena_vec![this; future_bound],
                 impl_trait_fn: Some(fn_def_id),
                 origin: hir::OpaqueTyOrigin::AsyncFn,
             };
@@ -2362,22 +2353,22 @@ fn lower_async_fn_ret_ty(
                 })
             })
             .collect();
-        generic_args.extend(lifetime_params[input_lifetimes_count..].iter().map(|&(span, _)| {
+        generic_args.extend(lifetime_params[input_lifetimes_count..].iter().map(|&(span, _)|
             // Output lifetime like `'_`.
             GenericArg::Lifetime(hir::Lifetime {
                 hir_id: self.next_id(),
                 span,
                 name: hir::LifetimeName::Implicit,
-            })
-        }));
+            })));
+        let generic_args = self.arena.alloc_from_iter(generic_args);
 
         // Create the `Foo<...>` reference itself. Note that the `type
         // Foo = impl Trait` is, internally, created as a child of the
         // async fn, so the *type parameters* are inherited.  It's
         // only the lifetime parameters that we must supply.
-        let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args.into());
+        let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args);
         let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
-        hir::FunctionRetTy::Return(P(opaque_ty))
+        hir::FunctionRetTy::Return(self.arena.alloc(opaque_ty))
     }
 
     /// Transforms `-> T` into `Future<Output = T>`
@@ -2386,17 +2377,17 @@ fn lower_async_fn_output_type_to_future_bound(
         output: &FunctionRetTy,
         fn_def_id: DefId,
         span: Span,
-    ) -> hir::GenericBound {
+    ) -> hir::GenericBound<'hir> {
         // Compute the `T` in `Future<Output = T>` from the return type.
         let output_ty = match output {
             FunctionRetTy::Ty(ty) => self.lower_ty(ty, ImplTraitContext::OpaqueTy(Some(fn_def_id))),
-            FunctionRetTy::Default(ret_ty_span) => P(self.ty_tup(*ret_ty_span, hir_vec![])),
+            FunctionRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
         };
 
         // "<Output = T>"
-        let future_params = P(hir::GenericArgs {
-            args: hir_vec![],
-            bindings: hir_vec![hir::TypeBinding {
+        let future_params = self.arena.alloc(hir::GenericArgs {
+            args: &[],
+            bindings: arena_vec![self; hir::TypeBinding {
                 ident: Ident::with_dummy_span(FN_OUTPUT_NAME),
                 kind: hir::TypeBindingKind::Equality { ty: output_ty },
                 hir_id: self.next_id(),
@@ -2406,13 +2397,17 @@ fn lower_async_fn_output_type_to_future_bound(
         });
 
         // ::std::future::Future<future_params>
-        let future_path =
-            P(self.std_path(span, &[sym::future, sym::Future], Some(future_params), false));
+        let future_path = self.arena.alloc(self.std_path(
+            span,
+            &[sym::future, sym::Future],
+            Some(future_params),
+            false,
+        ));
 
         hir::GenericBound::Trait(
             hir::PolyTraitRef {
                 trait_ref: hir::TraitRef { path: future_path, hir_ref_id: self.next_id() },
-                bound_generic_params: hir_vec![],
+                bound_generic_params: &[],
                 span,
             },
             hir::TraitBoundModifier::None,
@@ -2422,8 +2417,8 @@ fn lower_async_fn_output_type_to_future_bound(
     fn lower_param_bound(
         &mut self,
         tpb: &GenericBound,
-        itctx: ImplTraitContext<'_>,
-    ) -> hir::GenericBound {
+        itctx: ImplTraitContext<'_, 'hir>,
+    ) -> hir::GenericBound<'hir> {
         match *tpb {
             GenericBound::Trait(ref ty, modifier) => hir::GenericBound::Trait(
                 self.lower_poly_trait_ref(ty, itctx),
@@ -2470,27 +2465,36 @@ fn new_named_lifetime(
         hir::Lifetime { hir_id: self.lower_node_id(id), span, name }
     }
 
-    fn lower_generic_params(
+    fn lower_generic_params_mut(
         &mut self,
         params: &[GenericParam],
         add_bounds: &NodeMap<Vec<GenericBound>>,
-        mut itctx: ImplTraitContext<'_>,
-    ) -> hir::HirVec<hir::GenericParam> {
+        mut itctx: ImplTraitContext<'_, 'hir>,
+    ) -> Vec<hir::GenericParam<'hir>> {
         params
             .iter()
             .map(|param| self.lower_generic_param(param, add_bounds, itctx.reborrow()))
             .collect()
     }
 
+    fn lower_generic_params(
+        &mut self,
+        params: &[GenericParam],
+        add_bounds: &NodeMap<Vec<GenericBound>>,
+        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(
         &mut self,
         param: &GenericParam,
         add_bounds: &NodeMap<Vec<GenericBound>>,
-        mut itctx: ImplTraitContext<'_>,
-    ) -> hir::GenericParam {
-        let mut bounds = self
+        mut itctx: ImplTraitContext<'_, 'hir>,
+    ) -> hir::GenericParam<'hir> {
+        let mut bounds: Vec<_> = self
             .with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
-                this.lower_param_bounds(&param.bounds, itctx.reborrow())
+                this.lower_param_bounds_mut(&param.bounds, itctx.reborrow()).collect()
             });
 
         let (name, kind) = match param.kind {
@@ -2526,8 +2530,8 @@ fn lower_generic_param(
             GenericParamKind::Type { ref default, .. } => {
                 let add_bounds = add_bounds.get(&param.id).map_or(&[][..], |x| &x);
                 if !add_bounds.is_empty() {
-                    let params = self.lower_param_bounds(add_bounds, itctx.reborrow()).into_iter();
-                    bounds = bounds.into_iter().chain(params).collect();
+                    let params = self.lower_param_bounds_mut(add_bounds, itctx.reborrow());
+                    bounds.extend(params);
                 }
 
                 let kind = hir::GenericParamKind::Type {
@@ -2558,12 +2562,16 @@ fn lower_generic_param(
             span: param.ident.span,
             pure_wrt_drop: attr::contains_name(&param.attrs, sym::may_dangle),
             attrs: self.lower_attrs(&param.attrs),
-            bounds,
+            bounds: self.arena.alloc_from_iter(bounds),
             kind,
         }
     }
 
-    fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext<'_>) -> hir::TraitRef {
+    fn lower_trait_ref(
+        &mut self,
+        p: &TraitRef,
+        itctx: ImplTraitContext<'_, 'hir>,
+    ) -> hir::TraitRef<'hir> {
         let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
             hir::QPath::Resolved(None, path) => path,
             qpath => bug!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
@@ -2574,8 +2582,8 @@ fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext<'_>) -> hir:
     fn lower_poly_trait_ref(
         &mut self,
         p: &PolyTraitRef,
-        mut itctx: ImplTraitContext<'_>,
-    ) -> hir::PolyTraitRef {
+        mut itctx: ImplTraitContext<'_, 'hir>,
+    ) -> hir::PolyTraitRef<'hir> {
         let bound_generic_params = self.lower_generic_params(
             &p.bound_generic_params,
             &NodeMap::default(),
@@ -2588,16 +2596,24 @@ fn lower_poly_trait_ref(
         hir::PolyTraitRef { bound_generic_params, trait_ref, span: p.span }
     }
 
-    fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext<'_>) -> hir::MutTy {
+    fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext<'_, 'hir>) -> hir::MutTy<'hir> {
         hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
     }
 
     fn lower_param_bounds(
         &mut self,
         bounds: &[GenericBound],
-        mut itctx: ImplTraitContext<'_>,
-    ) -> hir::GenericBounds {
-        bounds.iter().map(|bound| self.lower_param_bound(bound, itctx.reborrow())).collect()
+        itctx: ImplTraitContext<'_, 'hir>,
+    ) -> hir::GenericBounds<'hir> {
+        self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
+    }
+
+    fn lower_param_bounds_mut<'s>(
+        &'s mut self,
+        bounds: &'s [GenericBound],
+        mut itctx: ImplTraitContext<'s, 'hir>,
+    ) -> impl Iterator<Item = hir::GenericBound<'hir>> + Captures<'s> + Captures<'a> {
+        bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx.reborrow()))
     }
 
     fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> &'hir hir::Block<'hir> {
@@ -2834,10 +2850,10 @@ fn lower_pat_ident(
             }
             Some(res) => hir::PatKind::Path(hir::QPath::Resolved(
                 None,
-                P(hir::Path {
+                self.arena.alloc(hir::Path {
                     span: ident.span,
                     res: self.lower_res(res),
-                    segments: hir_vec![hir::PathSegment::from_ident(ident)],
+                    segments: arena_vec![self; hir::PathSegment::from_ident(ident)],
                 }),
             )),
         }
@@ -3033,7 +3049,7 @@ fn pat_std_enum(
         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 qpath = hir::QPath::Resolved(None, self.arena.alloc(path));
         let pt = if subpats.is_empty() {
             hir::PatKind::Path(qpath)
         } else {
@@ -3079,9 +3095,9 @@ fn std_path(
         &mut self,
         span: Span,
         components: &[Symbol],
-        params: Option<P<hir::GenericArgs>>,
+        params: Option<&'hir hir::GenericArgs<'hir>>,
         is_value: bool,
-    ) -> hir::Path {
+    ) -> 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);
 
@@ -3104,18 +3120,23 @@ fn std_path(
         hir::Path {
             span,
             res: res.map_id(|_| panic!("unexpected `NodeId`")),
-            segments: segments.into(),
+            segments: self.arena.alloc_from_iter(segments),
         }
     }
 
-    fn ty_path(&mut self, mut hir_id: hir::HirId, span: Span, qpath: hir::QPath) -> hir::Ty {
+    fn ty_path(
+        &mut self,
+        mut hir_id: hir::HirId,
+        span: Span,
+        qpath: hir::QPath<'hir>,
+    ) -> hir::Ty<'hir> {
         let kind = match qpath {
             hir::QPath::Resolved(None, path) => {
                 // Turn trait object paths into `TyKind::TraitObject` instead.
                 match path.res {
                     Res::Def(DefKind::Trait, _) | Res::Def(DefKind::TraitAlias, _) => {
                         let principal = hir::PolyTraitRef {
-                            bound_generic_params: hir::HirVec::new(),
+                            bound_generic_params: &[],
                             trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
                             span,
                         };
@@ -3123,7 +3144,10 @@ fn ty_path(&mut self, mut hir_id: hir::HirId, span: Span, qpath: hir::QPath) ->
                         // The original ID is taken by the `PolyTraitRef`,
                         // so the `Ty` itself needs a different one.
                         hir_id = self.next_id();
-                        hir::TyKind::TraitObject(hir_vec![principal], self.elided_dyn_bound(span))
+                        hir::TyKind::TraitObject(
+                            arena_vec![self; principal],
+                            self.elided_dyn_bound(span),
+                        )
                     }
                     _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
                 }
@@ -3276,3 +3300,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: Vec<hir::GenericArg<'hir>>,
+    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,
+        }
+    }
+}