]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/hir/lowering/item.rs
Retire HirVec.
[rust.git] / src / librustc / hir / lowering / item.rs
index 46c944fa67881c4ae46546887f29bb07575727aa..7174addb15501df0768d4d36ccffcdbeb8d6644b 100644 (file)
@@ -1,59 +1,57 @@
-use super::LoweringContext;
+use super::AnonymousLifetimeMode;
 use super::ImplTraitContext;
 use super::ImplTraitPosition;
 use super::ImplTraitTypeIdVisitor;
-use super::AnonymousLifetimeMode;
+use super::LoweringContext;
 use super::ParamMode;
 
-use crate::hir::{self, HirVec};
-use crate::hir::ptr::P;
+use crate::arena::Arena;
+use crate::hir;
+use crate::hir::def::{DefKind, Res};
 use crate::hir::def_id::DefId;
-use crate::hir::def::{Res, DefKind};
 use crate::util::nodemap::NodeMap;
 
-use rustc_data_structures::thin_vec::ThinVec;
 use rustc_target::spec::abi;
 
-use std::collections::BTreeSet;
 use smallvec::SmallVec;
-use syntax::attr;
+use std::collections::BTreeSet;
 use syntax::ast::*;
-use syntax::visit::{self, Visitor};
+use syntax::attr;
 use syntax::source_map::{respan, DesugaringKind};
 use syntax::symbol::{kw, sym};
+use syntax::visit::{self, Visitor};
 use syntax_pos::Span;
 
 use rustc_error_codes::*;
 
-pub(super) struct ItemLowerer<'tcx, 'interner> {
-    pub(super) lctx: &'tcx mut LoweringContext<'interner>,
+pub(super) struct ItemLowerer<'a, 'lowering, 'hir> {
+    pub(super) lctx: &'a mut LoweringContext<'lowering, 'hir>,
 }
 
-impl<'tcx, 'interner> ItemLowerer<'tcx, 'interner> {
+impl<'a, 'lowering, 'hir> ItemLowerer<'a, 'lowering, 'hir> {
     fn with_trait_impl_ref<F>(&mut self, trait_impl_ref: &Option<TraitRef>, f: F)
     where
         F: FnOnce(&mut Self),
     {
         let old = self.lctx.is_in_trait_impl;
-        self.lctx.is_in_trait_impl = if let &None = trait_impl_ref {
-            false
-        } else {
-            true
-        };
+        self.lctx.is_in_trait_impl = if let &None = trait_impl_ref { false } else { true };
         f(self);
         self.lctx.is_in_trait_impl = old;
     }
 }
 
-impl<'tcx, 'interner> Visitor<'tcx> for ItemLowerer<'tcx, 'interner> {
-    fn visit_mod(&mut self, m: &'tcx Mod, _s: Span, _attrs: &[Attribute], n: NodeId) {
+impl<'a, 'lowering, 'hir> Visitor<'a> for ItemLowerer<'a, 'lowering, 'hir> {
+    fn visit_mod(&mut self, m: &'a Mod, _s: Span, _attrs: &[Attribute], n: NodeId) {
         let hir_id = self.lctx.lower_node_id(n);
 
-        self.lctx.modules.insert(hir_id, hir::ModuleItems {
-            items: BTreeSet::new(),
-            trait_items: BTreeSet::new(),
-            impl_items: BTreeSet::new(),
-        });
+        self.lctx.modules.insert(
+            hir_id,
+            hir::ModuleItems {
+                items: BTreeSet::new(),
+                trait_items: BTreeSet::new(),
+                impl_items: BTreeSet::new(),
+            },
+        );
 
         let old = self.lctx.current_module;
         self.lctx.current_module = hir_id;
@@ -61,7 +59,7 @@ fn visit_mod(&mut self, m: &'tcx Mod, _s: Span, _attrs: &[Attribute], n: NodeId)
         self.lctx.current_module = old;
     }
 
-    fn visit_item(&mut self, item: &'tcx Item) {
+    fn visit_item(&mut self, item: &'a Item) {
         let mut item_hir_id = None;
         self.lctx.with_hir_id_owner(item.id, |lctx| {
             lctx.without_in_scope_lifetime_defs(|lctx| {
@@ -76,9 +74,7 @@ fn visit_item(&mut self, item: &'tcx Item) {
             self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
                 let this = &mut ItemLowerer { lctx: this };
                 if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.kind {
-                    this.with_trait_impl_ref(opt_trait_ref, |this| {
-                        visit::walk_item(this, item)
-                    });
+                    this.with_trait_impl_ref(opt_trait_ref, |this| visit::walk_item(this, item));
                 } else {
                     visit::walk_item(this, item);
                 }
@@ -86,7 +82,7 @@ fn visit_item(&mut self, item: &'tcx Item) {
         }
     }
 
-    fn visit_trait_item(&mut self, item: &'tcx AssocItem) {
+    fn visit_trait_item(&mut self, item: &'a AssocItem) {
         self.lctx.with_hir_id_owner(item.id, |lctx| {
             let hir_item = lctx.lower_trait_item(item);
             let id = hir::TraitItemId { hir_id: hir_item.hir_id };
@@ -97,7 +93,7 @@ fn visit_trait_item(&mut self, item: &'tcx AssocItem) {
         visit::walk_trait_item(self, item);
     }
 
-    fn visit_impl_item(&mut self, item: &'tcx AssocItem) {
+    fn visit_impl_item(&mut self, item: &'a AssocItem) {
         self.lctx.with_hir_id_owner(item.id, |lctx| {
             let hir_item = lctx.lower_impl_item(item);
             let id = hir::ImplItemId { hir_id: hir_item.hir_id };
@@ -108,7 +104,7 @@ fn visit_impl_item(&mut self, item: &'tcx AssocItem) {
     }
 }
 
-impl LoweringContext<'_> {
+impl<'hir> LoweringContext<'_, 'hir> {
     // Same as the method above, but accepts `hir::GenericParam`s
     // instead of `ast::GenericParam`s.
     // This should only be used with generics that have already had their
@@ -117,15 +113,13 @@ impl LoweringContext<'_> {
     fn with_parent_item_lifetime_defs<T>(
         &mut self,
         parent_hir_id: hir::HirId,
-        f: impl FnOnce(&mut LoweringContext<'_>) -> T,
+        f: impl FnOnce(&mut LoweringContext<'_, '_>) -> T,
     ) -> T {
         let old_len = self.in_scope_lifetimes.len();
 
         let parent_generics = match self.items.get(&parent_hir_id).unwrap().kind {
             hir::ItemKind::Impl(_, _, _, ref generics, ..)
-            | hir::ItemKind::Trait(_, _, ref generics, ..) => {
-                &generics.params[..]
-            }
+            | hir::ItemKind::Trait(_, _, ref generics, ..) => &generics.params[..],
             _ => &[],
         };
         let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
@@ -145,7 +139,7 @@ fn with_parent_item_lifetime_defs<T>(
     // from their surrounding environment.
     fn without_in_scope_lifetime_defs<T>(
         &mut self,
-        f: impl FnOnce(&mut LoweringContext<'_>) -> T,
+        f: impl FnOnce(&mut LoweringContext<'_, '_>) -> T,
     ) -> T {
         let old_in_scope_lifetimes = std::mem::replace(&mut self.in_scope_lifetimes, vec![]);
 
@@ -162,10 +156,12 @@ fn without_in_scope_lifetime_defs<T>(
         res
     }
 
-    pub(super) fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
+    pub(super) fn lower_mod(&mut self, m: &Mod) -> hir::Mod<'hir> {
         hir::Mod {
             inner: m.inner,
-            item_ids: m.items.iter().flat_map(|x| self.lower_item_id(x)).collect(),
+            item_ids: self
+                .arena
+                .alloc_from_iter(m.items.iter().flat_map(|x| self.lower_item_id(x))),
         }
     }
 
@@ -177,8 +173,7 @@ pub(super) fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
                 vec
             }
             ItemKind::MacroDef(..) => SmallVec::new(),
-            ItemKind::Fn(..) |
-            ItemKind::Impl(.., None, _, _) => smallvec![i.id],
+            ItemKind::Fn(..) | ItemKind::Impl(.., None, _, _) => smallvec![i.id],
             ItemKind::Static(ref ty, ..) => {
                 let mut ids = smallvec![i.id];
                 if self.sess.features_untracked().impl_trait_in_bindings {
@@ -186,7 +181,7 @@ pub(super) fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
                     visitor.visit_ty(ty);
                 }
                 ids
-            },
+            }
             ItemKind::Const(ref ty, ..) => {
                 let mut ids = smallvec![i.id];
                 if self.sess.features_untracked().impl_trait_in_bindings {
@@ -194,39 +189,41 @@ pub(super) fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
                     visitor.visit_ty(ty);
                 }
                 ids
-            },
+            }
             _ => smallvec![i.id],
         };
 
-        node_ids.into_iter().map(|node_id| hir::ItemId {
-            id: self.allocate_hir_id_counter(node_id)
-        }).collect()
+        node_ids
+            .into_iter()
+            .map(|node_id| hir::ItemId { id: self.allocate_hir_id_counter(node_id) })
+            .collect()
     }
 
     fn lower_item_id_use_tree(
         &mut self,
         tree: &UseTree,
         base_id: NodeId,
-        vec: &mut SmallVec<[NodeId; 1]>
+        vec: &mut SmallVec<[NodeId; 1]>,
     ) {
         match tree.kind {
-            UseTreeKind::Nested(ref nested_vec) => for &(ref nested, id) in nested_vec {
-                vec.push(id);
-                self.lower_item_id_use_tree(nested, id, vec);
-            },
+            UseTreeKind::Nested(ref nested_vec) => {
+                for &(ref nested, id) in nested_vec {
+                    vec.push(id);
+                    self.lower_item_id_use_tree(nested, id, vec);
+                }
+            }
             UseTreeKind::Glob => {}
             UseTreeKind::Simple(_, id1, id2) => {
-                for (_, &id) in self.expect_full_res_from_use(base_id)
-                                    .skip(1)
-                                    .zip([id1, id2].iter())
+                for (_, &id) in
+                    self.expect_full_res_from_use(base_id).skip(1).zip([id1, id2].iter())
                 {
                     vec.push(id);
                 }
-            },
+            }
         }
     }
 
-    pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
+    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(&i.attrs);
@@ -245,21 +242,14 @@ pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
                     legacy: def.legacy,
                 });
             } else {
-                self.non_exported_macro_attrs.extend(attrs.into_iter());
+                self.non_exported_macro_attrs.extend(attrs.iter().cloned());
             }
             return None;
         }
 
-        let kind = self.lower_item_kind(i.span, i.id, &mut ident, &attrs, &mut vis, &i.kind);
+        let kind = self.lower_item_kind(i.span, i.id, &mut ident, attrs, &mut vis, &i.kind);
 
-        Some(hir::Item {
-            hir_id: self.lower_node_id(i.id),
-            ident,
-            attrs,
-            kind,
-            vis,
-            span: i.span,
-        })
+        Some(hir::Item { hir_id: self.lower_node_id(i.id), ident, attrs, kind, vis, span: i.span })
     }
 
     fn lower_item_kind(
@@ -267,47 +257,39 @@ fn lower_item_kind(
         span: Span,
         id: NodeId,
         ident: &mut Ident,
-        attrs: &hir::HirVec<Attribute>,
-        vis: &mut hir::Visibility,
+        attrs: &'hir [Attribute],
+        vis: &mut hir::Visibility<'hir>,
         i: &ItemKind,
-    ) -> hir::ItemKind {
+    ) -> hir::ItemKind<'hir> {
         match *i {
             ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name),
             ItemKind::Use(ref use_tree) => {
                 // Start with an empty prefix.
-                let prefix = Path {
-                    segments: vec![],
-                    span: use_tree.span,
-                };
+                let prefix = Path { segments: vec![], span: use_tree.span };
 
                 self.lower_use_tree(use_tree, &prefix, id, vis, ident, attrs)
             }
             ItemKind::Static(ref t, m, ref e) => {
-                hir::ItemKind::Static(
-                    self.lower_ty(
-                        t,
-                        if self.sess.features_untracked().impl_trait_in_bindings {
-                            ImplTraitContext::OpaqueTy(None)
-                        } else {
-                            ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
-                        }
-                    ),
-                    m,
-                    self.lower_const_body(span, Some(e)),
-                )
+                let ty = self.lower_ty(
+                    t,
+                    if self.sess.features_untracked().impl_trait_in_bindings {
+                        ImplTraitContext::OpaqueTy(None)
+                    } else {
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
+                    },
+                );
+                hir::ItemKind::Static(ty, m, self.lower_const_body(span, Some(e)))
             }
             ItemKind::Const(ref t, ref e) => {
-                hir::ItemKind::Const(
-                    self.lower_ty(
-                        t,
-                        if self.sess.features_untracked().impl_trait_in_bindings {
-                            ImplTraitContext::OpaqueTy(None)
-                        } else {
-                            ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
-                        }
-                    ),
-                    self.lower_const_body(span, Some(e))
-                )
+                let ty = self.lower_ty(
+                    t,
+                    if self.sess.features_untracked().impl_trait_in_bindings {
+                        ImplTraitContext::OpaqueTy(None)
+                    } else {
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
+                    },
+                );
+                hir::ItemKind::Const(ty, self.lower_const_body(span, Some(e)))
             }
             ItemKind::Fn(FnSig { ref decl, header }, ref generics, ref body) => {
                 let fn_def_id = self.resolver.definitions().local_def_id(id);
@@ -318,23 +300,21 @@ fn lower_item_kind(
                     // `impl Future<Output = T>` here because lower_body
                     // only cares about the input argument patterns in the function
                     // declaration (decl), not the return types.
-                    let body_id = this.lower_maybe_async_body(
-                        span,
-                        &decl,
-                        header.asyncness.node,
-                        Some(body),
-                    );
+                    let body_id =
+                        this.lower_maybe_async_body(span, &decl, header.asyncness.node, Some(body));
 
                     let (generics, decl) = this.add_in_band_defs(
                         generics,
                         fn_def_id,
                         AnonymousLifetimeMode::PassThrough,
-                        |this, idty| this.lower_fn_decl(
-                            &decl,
-                            Some((fn_def_id, idty)),
-                            true,
-                            header.asyncness.node.opt_return_id()
-                        ),
+                        |this, idty| {
+                            this.lower_fn_decl(
+                                &decl,
+                                Some((fn_def_id, idty)),
+                                true,
+                                header.asyncness.node.opt_return_id(),
+                            )
+                        },
                     );
                     let sig = hir::FnSig { decl, header: this.lower_fn_header(header) };
                     hir::ItemKind::Fn(sig, generics, body_id)
@@ -348,7 +328,7 @@ fn lower_item_kind(
                     let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
                     let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
                     hir::ItemKind::TyAlias(ty, generics)
-                },
+                }
                 Some(bounds) => {
                     let ty = hir::OpaqueTy {
                         generics: self.lower_generics(generics, ImplTraitContext::OpaqueTy(None)),
@@ -358,19 +338,15 @@ fn lower_item_kind(
                     };
                     hir::ItemKind::OpaqueTy(ty)
                 }
-            }
-            ItemKind::Enum(ref enum_definition, ref generics) => {
-                hir::ItemKind::Enum(
-                    hir::EnumDef {
-                        variants: enum_definition
-                            .variants
-                            .iter()
-                            .map(|x| self.lower_variant(x))
-                            .collect(),
-                    },
-                    self.lower_generics(generics, ImplTraitContext::disallowed()),
-                )
             },
+            ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum(
+                hir::EnumDef {
+                    variants: self.arena.alloc_from_iter(
+                        enum_definition.variants.iter().map(|x| self.lower_variant(x)),
+                    ),
+                },
+                self.lower_generics(generics, ImplTraitContext::disallowed()),
+            ),
             ItemKind::Struct(ref struct_def, ref generics) => {
                 let struct_def = self.lower_variant_data(struct_def);
                 hir::ItemKind::Struct(
@@ -421,8 +397,10 @@ fn lower_item_kind(
 
                         if let Some(ref trait_ref) = trait_ref {
                             if let Res::Def(DefKind::Trait, def_id) = trait_ref.path.res {
-                                this.trait_impls.entry(def_id).or_default().push(
-                                    lowered_trait_impl_id);
+                                this.trait_impls
+                                    .entry(def_id)
+                                    .or_default()
+                                    .push(lowered_trait_impl_id);
                             }
                         }
 
@@ -432,15 +410,12 @@ fn lower_item_kind(
                     },
                 );
 
-                let new_impl_items = self.with_in_scope_lifetime_defs(
-                    &ast_generics.params,
-                    |this| {
-                        impl_items
-                            .iter()
-                            .map(|item| this.lower_impl_item_ref(item))
-                            .collect()
-                    },
-                );
+                let new_impl_items =
+                    self.with_in_scope_lifetime_defs(&ast_generics.params, |this| {
+                        this.arena.alloc_from_iter(
+                            impl_items.iter().map(|item| this.lower_impl_item_ref(item)),
+                        )
+                    });
 
                 hir::ItemKind::Impl(
                     unsafety,
@@ -454,10 +429,9 @@ fn lower_item_kind(
             }
             ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
                 let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed());
-                let items = items
-                    .iter()
-                    .map(|item| self.lower_trait_item_ref(item))
-                    .collect();
+                let items = self
+                    .arena
+                    .alloc_from_iter(items.iter().map(|item| self.lower_trait_item_ref(item)));
                 hir::ItemKind::Trait(
                     is_auto,
                     unsafety,
@@ -470,8 +444,9 @@ fn lower_item_kind(
                 self.lower_generics(generics, ImplTraitContext::disallowed()),
                 self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
             ),
-            ItemKind::MacroDef(..)
-            | ItemKind::Mac(..) => bug!("`TyMac` should have been expanded by now"),
+            ItemKind::MacroDef(..) | ItemKind::Mac(..) => {
+                bug!("`TyMac` should have been expanded by now")
+            }
         }
 
         // [1] `defaultness.has_value()` is never called for an `impl`, always `true` in order to
@@ -483,30 +458,22 @@ fn lower_use_tree(
         tree: &UseTree,
         prefix: &Path,
         id: NodeId,
-        vis: &mut hir::Visibility,
+        vis: &mut hir::Visibility<'hir>,
         ident: &mut Ident,
-        attrs: &hir::HirVec<Attribute>,
-    ) -> hir::ItemKind {
+        attrs: &'hir [Attribute],
+    ) -> hir::ItemKind<'hir> {
         debug!("lower_use_tree(tree={:?})", tree);
         debug!("lower_use_tree: vis = {:?}", vis);
 
         let path = &tree.prefix;
-        let segments = prefix
-            .segments
-            .iter()
-            .chain(path.segments.iter())
-            .cloned()
-            .collect();
+        let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();
 
         match tree.kind {
             UseTreeKind::Simple(rename, id1, id2) => {
                 *ident = tree.ident();
 
                 // First, apply the prefix to the path.
-                let mut path = Path {
-                    segments,
-                    span: path.span,
-                };
+                let mut path = Path { segments, span: path.span };
 
                 // Correctly resolve `self` imports.
                 if path.segments.len() > 1
@@ -539,34 +506,29 @@ fn lower_use_tree(
                     self.with_hir_id_owner(new_node_id, |this| {
                         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(P(path), hir::UseKind::Single);
+                        let path = this.lower_path_extra(res, &path, ParamMode::Explicit, None);
+                        let kind = hir::ItemKind::Use(this.arena.alloc(path), hir::UseKind::Single);
                         let vis = this.rebuild_vis(&vis);
 
-                        this.insert_item(
-                            hir::Item {
-                                hir_id: new_id,
-                                ident,
-                                attrs: attrs.into_iter().cloned().collect(),
-                                kind,
-                                vis,
-                                span,
-                            },
-                        );
+                        this.insert_item(hir::Item {
+                            hir_id: new_id,
+                            ident,
+                            attrs,
+                            kind,
+                            vis,
+                            span,
+                        });
                     });
                 }
 
-                let path = P(self.lower_path_extra(ret_res, &path, ParamMode::Explicit, None));
+                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 = P(self.lower_path(
+                let path = self.arena.alloc(self.lower_path(
                     id,
-                    &Path {
-                        segments,
-                        span: path.span,
-                    },
+                    &Path { segments, span: path.span },
                     ParamMode::Explicit,
                 ));
                 hir::ItemKind::Use(path, hir::UseKind::Glob)
@@ -596,10 +558,7 @@ fn lower_use_tree(
                 // for that we return the `{}` import (called the
                 // `ListStem`).
 
-                let prefix = Path {
-                    segments,
-                    span: prefix.span.to(path.span),
-                };
+                let prefix = Path { segments, span: prefix.span.to(path.span) };
 
                 // Add all the nested `PathListItem`s to the HIR.
                 for &(ref use_tree, id) in trees {
@@ -621,23 +580,17 @@ fn lower_use_tree(
                         let mut vis = this.rebuild_vis(&vis);
                         let mut ident = *ident;
 
-                        let kind = this.lower_use_tree(use_tree,
-                                                       &prefix,
-                                                       id,
-                                                       &mut vis,
-                                                       &mut ident,
-                                                       attrs);
-
-                        this.insert_item(
-                            hir::Item {
-                                hir_id: new_hir_id,
-                                ident,
-                                attrs: attrs.into_iter().cloned().collect(),
-                                kind,
-                                vis,
-                                span: use_tree.span,
-                            },
-                        );
+                        let kind =
+                            this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);
+
+                        this.insert_item(hir::Item {
+                            hir_id: new_hir_id,
+                            ident,
+                            attrs,
+                            kind,
+                            vis,
+                            span: use_tree.span,
+                        });
                     });
                 }
 
@@ -652,9 +605,9 @@ fn lower_use_tree(
                 // unused, failing the check that HirIds are "densely
                 // assigned".
                 match vis.node {
-                    hir::VisibilityKind::Public |
-                    hir::VisibilityKind::Crate(_) |
-                    hir::VisibilityKind::Inherited => {
+                    hir::VisibilityKind::Public
+                    | hir::VisibilityKind::Crate(_)
+                    hir::VisibilityKind::Inherited => {
                         *vis = respan(prefix.span.shrink_to_lo(), hir::VisibilityKind::Inherited);
                     }
                     hir::VisibilityKind::Restricted { .. } => {
@@ -664,7 +617,8 @@ fn lower_use_tree(
 
                 let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err);
                 let res = self.lower_res(res);
-                let path = P(self.lower_path_extra(res, &prefix, ParamMode::Explicit, None));
+                let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit, None);
+                let path = self.arena.alloc(path);
                 hir::ItemKind::Use(path, hir::UseKind::ListStem)
             }
         }
@@ -673,30 +627,27 @@ fn lower_use_tree(
     /// 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::Path {
+    fn rebuild_use_path(&mut self, path: &hir::Path<'hir>) -> hir::Path<'hir> {
         debug!("rebuild_use_path(path = {:?})", path);
-        let segments = path.segments.iter().map(|seg| hir::PathSegment {
-            ident: seg.ident,
-            hir_id: seg.hir_id.map(|_| self.next_id()),
-            res: seg.res,
-            args: None,
-            infer_args: seg.infer_args,
-        }).collect();
-        hir::Path {
-            span: path.span,
-            res: path.res,
-            segments,
-        }
+        let segments =
+            self.arena.alloc_from_iter(path.segments.iter().map(|seg| hir::PathSegment {
+                ident: seg.ident,
+                hir_id: seg.hir_id.map(|_| self.next_id()),
+                res: seg.res,
+                args: None,
+                infer_args: seg.infer_args,
+            }));
+        hir::Path { span: path.span, res: path.res, segments }
     }
 
-    fn rebuild_vis(&mut self, vis: &hir::Visibility) -> hir::Visibility {
+    fn rebuild_vis(&mut self, vis: &hir::Visibility<'hir>) -> hir::Visibility<'hir> {
         let vis_kind = match vis.node {
             hir::VisibilityKind::Public => hir::VisibilityKind::Public,
             hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
             hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
             hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
                 hir::VisibilityKind::Restricted {
-                    path: P(self.rebuild_use_path(path)),
+                    path: self.arena.alloc(self.rebuild_use_path(path)),
                     hir_id: self.next_id(),
                 }
             }
@@ -704,7 +655,7 @@ fn rebuild_vis(&mut self, vis: &hir::Visibility) -> hir::Visibility {
         respan(vis.span, vis_kind)
     }
 
-    fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
+    fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem<'hir> {
         let def_id = self.resolver.definitions().local_def_id(i.id);
         hir::ForeignItem {
             hir_id: self.lower_node_id(i.id),
@@ -728,8 +679,8 @@ fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
                     hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
                 }
                 ForeignItemKind::Static(ref t, m) => {
-                    hir::ForeignItemKind::Static(
-                        self.lower_ty(t, ImplTraitContext::disallowed()), m)
+                    let ty = self.lower_ty(t, ImplTraitContext::disallowed());
+                    hir::ForeignItemKind::Static(ty, m)
                 }
                 ForeignItemKind::Ty => hir::ForeignItemKind::Type,
                 ForeignItemKind::Macro(_) => panic!("macro shouldn't exist here"),
@@ -739,21 +690,18 @@ fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
         }
     }
 
-    fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
+    fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod<'hir> {
         hir::ForeignMod {
             abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
-            items: fm.items
-                .iter()
-                .map(|x| self.lower_foreign_item(x))
-                .collect(),
+            items: self.arena.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item(x))),
         }
     }
 
-    fn lower_global_asm(&mut self, ga: &GlobalAsm) -> P<hir::GlobalAsm> {
-        P(hir::GlobalAsm { asm: ga.asm })
+    fn lower_global_asm(&mut self, ga: &GlobalAsm) -> &'hir hir::GlobalAsm {
+        self.arena.alloc(hir::GlobalAsm { asm: ga.asm })
     }
 
-    fn lower_variant(&mut self, v: &Variant) -> hir::Variant {
+    fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
         hir::Variant {
             attrs: self.lower_attrs(&v.attrs),
             data: self.lower_variant_data(&v.data),
@@ -764,38 +712,32 @@ fn lower_variant(&mut self, v: &Variant) -> hir::Variant {
         }
     }
 
-    fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
+    fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData<'hir> {
         match *vdata {
             VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct(
-                fields.iter().enumerate().map(|f| self.lower_struct_field(f)).collect(),
+                self.arena
+                    .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_struct_field(f))),
                 recovered,
             ),
-            VariantData::Tuple(ref fields, id) => {
-                hir::VariantData::Tuple(
-                    fields
-                        .iter()
-                        .enumerate()
-                        .map(|f| self.lower_struct_field(f))
-                        .collect(),
-                    self.lower_node_id(id),
-                )
-            },
-            VariantData::Unit(id) => {
-                hir::VariantData::Unit(self.lower_node_id(id))
-            },
+            VariantData::Tuple(ref fields, id) => hir::VariantData::Tuple(
+                self.arena
+                    .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_struct_field(f))),
+                self.lower_node_id(id),
+            ),
+            VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id)),
         }
     }
 
-    fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField {
+    fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField<'hir> {
         let ty = if let TyKind::Path(ref qself, ref path) = f.ty.kind {
             let t = self.lower_path_ty(
                 &f.ty,
                 qself,
                 path,
                 ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124)
-                ImplTraitContext::disallowed()
+                ImplTraitContext::disallowed(),
             );
-            P(t)
+            self.arena.alloc(t)
         } else {
             self.lower_ty(&f.ty, ImplTraitContext::disallowed())
         };
@@ -813,52 +755,43 @@ fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::Stru
         }
     }
 
-    fn lower_trait_item(&mut self, i: &AssocItem) -> hir::TraitItem {
+    fn lower_trait_item(&mut self, i: &AssocItem) -> hir::TraitItem<'hir> {
         let trait_item_def_id = self.resolver.definitions().local_def_id(i.id);
 
         let (generics, kind) = match i.kind {
-            AssocItemKind::Const(ref ty, ref default) => (
-                self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
-                hir::TraitItemKind::Const(
-                    self.lower_ty(ty, ImplTraitContext::disallowed()),
-                    default
-                        .as_ref()
-                        .map(|x| self.lower_const_body(i.span, Some(x))),
-                ),
-            ),
+            AssocItemKind::Const(ref ty, ref default) => {
+                let generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed());
+                let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
+                (
+                    generics,
+                    hir::TraitItemKind::Const(
+                        ty,
+                        default.as_ref().map(|x| self.lower_const_body(i.span, Some(x))),
+                    ),
+                )
+            }
             AssocItemKind::Fn(ref sig, None) => {
                 let names = self.lower_fn_params_to_names(&sig.decl);
-                let (generics, sig) = self.lower_method_sig(
-                    &i.generics,
-                    sig,
-                    trait_item_def_id,
-                    false,
-                    None,
-                );
+                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)))
             }
             AssocItemKind::Fn(ref sig, Some(ref body)) => {
                 let body_id = self.lower_fn_body_block(i.span, &sig.decl, Some(body));
-                let (generics, sig) = self.lower_method_sig(
-                    &i.generics,
-                    sig,
-                    trait_item_def_id,
-                    false,
-                    None,
-                );
+                let (generics, sig) =
+                    self.lower_method_sig(&i.generics, sig, trait_item_def_id, false, None);
                 (generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Provided(body_id)))
             }
             AssocItemKind::TyAlias(ref bounds, ref default) => {
+                let ty = default.as_ref().map(|x| self.lower_ty(x, ImplTraitContext::disallowed()));
                 let generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed());
                 let kind = hir::TraitItemKind::Type(
                     self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
-                    default
-                        .as_ref()
-                        .map(|x| self.lower_ty(x, ImplTraitContext::disallowed())),
+                    ty,
                 );
 
                 (generics, kind)
-            },
+            }
             AssocItemKind::Macro(..) => bug!("macro item shouldn't exist at this point"),
         };
 
@@ -874,18 +807,11 @@ fn lower_trait_item(&mut self, i: &AssocItem) -> hir::TraitItem {
 
     fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
         let (kind, has_default) = match i.kind {
-            AssocItemKind::Const(_, ref default) => {
-                (hir::AssocItemKind::Const, default.is_some())
+            AssocItemKind::Const(_, ref default) => (hir::AssocItemKind::Const, default.is_some()),
+            AssocItemKind::TyAlias(_, ref default) => (hir::AssocItemKind::Type, default.is_some()),
+            AssocItemKind::Fn(ref sig, ref default) => {
+                (hir::AssocItemKind::Method { has_self: sig.decl.has_self() }, default.is_some())
             }
-            AssocItemKind::TyAlias(_, ref default) => {
-                (hir::AssocItemKind::Type, default.is_some())
-            }
-            AssocItemKind::Fn(ref sig, ref default) => (
-                hir::AssocItemKind::Method {
-                    has_self: sig.decl.has_self(),
-                },
-                default.is_some(),
-            ),
             AssocItemKind::Macro(..) => unimplemented!(),
         };
         hir::TraitItemRef {
@@ -898,21 +824,22 @@ fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
     }
 
     /// Construct `ExprKind::Err` for the given `span`.
-    fn expr_err(&mut self, span: Span) -> hir::Expr {
-        self.expr(span, hir::ExprKind::Err, ThinVec::new())
+    fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> {
+        self.expr(span, hir::ExprKind::Err, AttrVec::new())
     }
 
-    fn lower_impl_item(&mut self, i: &AssocItem) -> hir::ImplItem {
+    fn lower_impl_item(&mut self, i: &AssocItem) -> hir::ImplItem<'hir> {
         let impl_item_def_id = self.resolver.definitions().local_def_id(i.id);
 
         let (generics, kind) = match i.kind {
-            AssocItemKind::Const(ref ty, ref expr) => (
-                self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
-                hir::ImplItemKind::Const(
-                    self.lower_ty(ty, ImplTraitContext::disallowed()),
-                    self.lower_const_body(i.span, expr.as_deref()),
-                ),
-            ),
+            AssocItemKind::Const(ref ty, ref expr) => {
+                let generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed());
+                let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
+                (
+                    generics,
+                    hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())),
+                )
+            }
             AssocItemKind::Fn(ref sig, ref body) => {
                 self.current_item = Some(i.span);
                 let body_id = self.lower_maybe_async_body(
@@ -936,7 +863,8 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> hir::ImplItem {
                 let generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed());
                 let kind = match ty {
                     None => {
-                        hir::ImplItemKind::TyAlias(P(self.ty(i.span, hir::TyKind::Err)))
+                        let ty = self.arena.alloc(self.ty(i.span, hir::TyKind::Err));
+                        hir::ImplItemKind::TyAlias(ty)
                     }
                     Some(ty) => match ty.kind.opaque_top_hack() {
                         None => {
@@ -947,10 +875,10 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> hir::ImplItem {
                             let bs = self.lower_param_bounds(bs, ImplTraitContext::disallowed());
                             hir::ImplItemKind::OpaqueTy(bs)
                         }
-                    }
+                    },
                 };
                 (generics, kind)
-            },
+            }
             AssocItemKind::Macro(..) => bug!("`TyMac` should have been expanded by now"),
         };
 
@@ -968,7 +896,7 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> hir::ImplItem {
         // [1] since `default impl` is not yet implemented, this is always true in impls
     }
 
-    fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
+    fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef<'hir> {
         hir::ImplItemRef {
             id: hir::ImplItemId { hir_id: self.lower_node_id(i.id) },
             ident: i.ident,
@@ -977,16 +905,15 @@ fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
             defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
             kind: match &i.kind {
                 AssocItemKind::Const(..) => hir::AssocItemKind::Const,
-                AssocItemKind::TyAlias(_, ty) => match ty
-                    .as_deref()
-                    .and_then(|ty| ty.kind.opaque_top_hack())
-                {
-                    None => hir::AssocItemKind::Type,
-                    Some(_) => hir::AssocItemKind::OpaqueTy,
-                },
-                AssocItemKind::Fn(sig, _) => hir::AssocItemKind::Method {
-                    has_self: sig.decl.has_self(),
-                },
+                AssocItemKind::TyAlias(_, ty) => {
+                    match ty.as_deref().and_then(|ty| ty.kind.opaque_top_hack()) {
+                        None => hir::AssocItemKind::Type,
+                        Some(_) => hir::AssocItemKind::OpaqueTy,
+                    }
+                }
+                AssocItemKind::Fn(sig, _) => {
+                    hir::AssocItemKind::Method { has_self: sig.decl.has_self() }
+                }
                 AssocItemKind::Macro(..) => unimplemented!(),
             },
         }
@@ -1003,7 +930,7 @@ fn lower_visibility(
         &mut self,
         v: &Visibility,
         explicit_owner: Option<NodeId>,
-    ) -> hir::Visibility {
+    ) -> hir::Visibility<'hir> {
         let node = match v.node {
             VisibilityKind::Public => hir::VisibilityKind::Public,
             VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
@@ -1017,7 +944,7 @@ fn lower_visibility(
                 let res = self.expect_full_res(id);
                 let res = self.lower_res(res);
                 hir::VisibilityKind::Restricted {
-                    path: P(self.lower_path_extra(
+                    path: self.arena.alloc(self.lower_path_extra(
                         res,
                         path,
                         ParamMode::Explicit,
@@ -1025,7 +952,7 @@ fn lower_visibility(
                     )),
                     hir_id: lowered_id,
                 }
-            },
+            }
             VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
         };
         respan(v.span, node)
@@ -1033,9 +960,7 @@ fn lower_visibility(
 
     fn lower_defaultness(&self, d: Defaultness, has_value: bool) -> hir::Defaultness {
         match d {
-            Defaultness::Default => hir::Defaultness::Default {
-                has_value: has_value,
-            },
+            Defaultness::Default => hir::Defaultness::Default { has_value: has_value },
             Defaultness::Final => {
                 assert!(has_value);
                 hir::Defaultness::Final
@@ -1043,12 +968,12 @@ fn lower_defaultness(&self, d: Defaultness, has_value: bool) -> hir::Defaultness
         }
     }
 
-    fn record_body(&mut self, params: HirVec<hir::Param>, value: hir::Expr) -> hir::BodyId {
-        let body = hir::Body {
-            generator_kind: self.generator_kind,
-            params,
-            value,
-        };
+    fn record_body(
+        &mut self,
+        params: &'hir [hir::Param<'hir>],
+        value: hir::Expr<'hir>,
+    ) -> hir::BodyId {
+        let body = hir::Body { generator_kind: self.generator_kind, params, value };
         let id = body.id();
         self.bodies.insert(id, body);
         id
@@ -1056,7 +981,7 @@ fn record_body(&mut self, params: HirVec<hir::Param>, value: hir::Expr) -> hir::
 
     fn lower_body(
         &mut self,
-        f: impl FnOnce(&mut LoweringContext<'_>) -> (HirVec<hir::Param>, hir::Expr),
+        f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
     ) -> hir::BodyId {
         let prev_gen_kind = self.generator_kind.take();
         let (parameters, result) = f(self);
@@ -1065,7 +990,7 @@ fn lower_body(
         body_id
     }
 
-    fn lower_param(&mut self, param: &Param) -> hir::Param {
+    fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
         hir::Param {
             attrs: self.lower_attrs(&param.attrs),
             hir_id: self.lower_node_id(param.id),
@@ -1077,12 +1002,14 @@ fn lower_param(&mut self, param: &Param) -> hir::Param {
     pub(super) fn lower_fn_body(
         &mut self,
         decl: &FnDecl,
-        body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
+        body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
     ) -> hir::BodyId {
-        self.lower_body(|this| (
-            decl.inputs.iter().map(|x| this.lower_param(x)).collect(),
-            body(this),
-        ))
+        self.lower_body(|this| {
+            (
+                this.arena.alloc_from_iter(decl.inputs.iter().map(|x| this.lower_param(x))),
+                body(this),
+            )
+        })
     }
 
     fn lower_fn_body_block(
@@ -1094,7 +1021,7 @@ fn lower_fn_body_block(
         self.lower_fn_body(decl, |this| this.lower_block_expr_opt(span, body))
     }
 
-    fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr {
+    fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> {
         match block {
             Some(block) => self.lower_block_expr(block),
             None => self.expr_err(span),
@@ -1102,10 +1029,15 @@ fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Ex
     }
 
     pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {
-        self.lower_body(|this| (hir_vec![], match expr {
-            Some(expr) => this.lower_expr(expr),
-            None => this.expr_err(span),
-        }))
+        self.lower_body(|this| {
+            (
+                &[],
+                match expr {
+                    Some(expr) => this.lower_expr_mut(expr),
+                    None => this.expr_err(span),
+                },
+            )
+        })
     }
 
     fn lower_maybe_async_body(
@@ -1121,8 +1053,8 @@ fn lower_maybe_async_body(
         };
 
         self.lower_body(|this| {
-            let mut parameters: Vec<hir::Param> = Vec::new();
-            let mut statements: Vec<hir::Stmt> = Vec::new();
+            let mut parameters: Vec<hir::Param<'_>> = Vec::new();
+            let mut statements: Vec<hir::Stmt<'_>> = Vec::new();
 
             // Async function parameters are lowered into the closure body so that they are
             // captured and so that the drop order matches the equivalent non-async functions.
@@ -1163,26 +1095,26 @@ fn lower_maybe_async_body(
                 // Check if this is a binding pattern, if so, we can optimize and avoid adding a
                 // `let <pat> = __argN;` statement. In this case, we do not rename the parameter.
                 let (ident, is_simple_parameter) = match parameter.pat.kind {
-                    hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, _) =>
-                        (ident, true),
+                    hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, _) => {
+                        (ident, true)
+                    }
                     _ => {
                         // Replace the ident for bindings that aren't simple.
                         let name = format!("__arg{}", index);
                         let ident = Ident::from_str(&name);
 
                         (ident, false)
-                    },
+                    }
                 };
 
-                let desugared_span =
-                    this.mark_span_with_reason(DesugaringKind::Async, span, None);
+                let desugared_span = this.mark_span_with_reason(DesugaringKind::Async, span, None);
 
                 // Construct a parameter representing `__argN: <ty>` to replace the parameter of the
                 // async function.
                 //
                 // If this is the simple case, this parameter will end up being the same as the
                 // original parameter, but with a different pattern id.
-                let mut stmt_attrs = ThinVec::new();
+                let mut stmt_attrs = AttrVec::new();
                 stmt_attrs.extend(parameter.attrs.iter().cloned());
                 let (new_parameter_pat, new_parameter_id) = this.pat_ident(desugared_span, ident);
                 let new_parameter = hir::Param {
@@ -1192,7 +1124,6 @@ fn lower_maybe_async_body(
                     span: parameter.span,
                 };
 
-
                 if is_simple_parameter {
                     // If this is the simple case, then we only insert one statement that is
                     // `let <pat> = <pat>;`. We re-use the original argument's pattern so that
@@ -1201,9 +1132,9 @@ fn lower_maybe_async_body(
                     let stmt = this.stmt_let_pat(
                         stmt_attrs,
                         desugared_span,
-                        Some(P(expr)),
+                        Some(this.arena.alloc(expr)),
                         parameter.pat,
-                        hir::LocalSource::AsyncFn
+                        hir::LocalSource::AsyncFn,
                     );
                     statements.push(stmt);
                 } else {
@@ -1223,14 +1154,17 @@ fn lower_maybe_async_body(
                     // because the user may have specified a `ref mut` binding in the next
                     // statement.
                     let (move_pat, move_id) = this.pat_ident_binding_mode(
-                        desugared_span, ident, hir::BindingAnnotation::Mutable);
+                        desugared_span,
+                        ident,
+                        hir::BindingAnnotation::Mutable,
+                    );
                     let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id);
                     let move_stmt = this.stmt_let_pat(
-                        ThinVec::new(),
+                        AttrVec::new(),
                         desugared_span,
-                        Some(P(move_expr)),
+                        Some(this.arena.alloc(move_expr)),
                         move_pat,
-                        hir::LocalSource::AsyncFn
+                        hir::LocalSource::AsyncFn,
                     );
 
                     // Construct the `let <pat> = __argN;` statement. We re-use the original
@@ -1239,9 +1173,9 @@ fn lower_maybe_async_body(
                     let pattern_stmt = this.stmt_let_pat(
                         stmt_attrs,
                         desugared_span,
-                        Some(P(pattern_expr)),
+                        Some(this.arena.alloc(pattern_expr)),
                         parameter.pat,
-                        hir::LocalSource::AsyncFn
+                        hir::LocalSource::AsyncFn,
                     );
 
                     statements.push(move_stmt);
@@ -1263,15 +1197,12 @@ fn lower_maybe_async_body(
                     let user_body = this.lower_block_expr_opt(body_span, body);
 
                     // Transform into `drop-temps { <user-body> }`, an expression:
-                    let desugared_span = this.mark_span_with_reason(
-                        DesugaringKind::Async,
-                        user_body.span,
-                        None,
-                    );
+                    let desugared_span =
+                        this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);
                     let user_body = this.expr_drop_temps(
                         desugared_span,
-                        P(user_body),
-                        ThinVec::new(),
+                        this.arena.alloc(user_body),
+                        AttrVec::new(),
                     );
 
                     // As noted above, create the final block like
@@ -1285,12 +1216,18 @@ fn lower_maybe_async_body(
                     // ```
                     let body = this.block_all(
                         desugared_span,
-                        statements.into(),
-                        Some(P(user_body)),
+                        this.arena.alloc_from_iter(statements),
+                        Some(user_body),
                     );
-                    this.expr_block(P(body), ThinVec::new())
-                });
-            (HirVec::from(parameters), this.expr(body_span, async_expr, ThinVec::new()))
+
+                    this.expr_block(body, AttrVec::new())
+                },
+            );
+
+            (
+                this.arena.alloc_from_iter(parameters),
+                this.expr(body_span, async_expr, AttrVec::new()),
+            )
         })
     }
 
@@ -1301,18 +1238,20 @@ fn lower_method_sig(
         fn_def_id: DefId,
         impl_trait_return_allow: bool,
         is_async: Option<NodeId>,
-    ) -> (hir::Generics, hir::FnSig) {
+    ) -> (hir::Generics<'hir>, hir::FnSig<'hir>) {
         let header = self.lower_fn_header(sig.header);
         let (generics, decl) = self.add_in_band_defs(
             generics,
             fn_def_id,
             AnonymousLifetimeMode::PassThrough,
-            |this, idty| this.lower_fn_decl(
-                &sig.decl,
-                Some((fn_def_id, idty)),
-                impl_trait_return_allow,
-                is_async,
-            ),
+            |this, idty| {
+                this.lower_fn_decl(
+                    &sig.decl,
+                    Some((fn_def_id, idty)),
+                    impl_trait_return_allow,
+                    is_async,
+                )
+            },
         );
         (generics, hir::FnSig { header, decl })
     }
@@ -1342,16 +1281,10 @@ pub(super) fn lower_extern(&mut self, ext: Extern) -> abi::Abi {
     }
 
     fn error_on_invalid_abi(&self, abi: StrLit) {
-        struct_span_err!(
-            self.sess,
-            abi.span,
-            E0703,
-            "invalid ABI: found `{}`",
-            abi.symbol
-        )
-        .span_label(abi.span, "invalid ABI")
-        .help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
-        .emit();
+        struct_span_err!(self.sess, abi.span, E0703, "invalid ABI: found `{}`", abi.symbol)
+            .span_label(abi.span, "invalid ABI")
+            .help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
+            .emit();
     }
 
     fn lower_asyncness(&mut self, a: IsAsync) -> hir::IsAsync {
@@ -1361,12 +1294,11 @@ fn lower_asyncness(&mut self, a: IsAsync) -> hir::IsAsync {
         }
     }
 
-    pub(super) fn lower_generics(
+    pub(super) fn lower_generics_mut(
         &mut self,
         generics: &Generics,
-        itctx: ImplTraitContext<'_>)
-        -> hir::Generics
-    {
+        itctx: ImplTraitContext<'_, '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
@@ -1389,7 +1321,8 @@ pub(super) fn lower_generics(
                                 if path.segments.len() == 1
                                     && bound_pred.bound_generic_params.is_empty() =>
                             {
-                                if let Some(Res::Def(DefKind::TyParam, def_id)) = self.resolver
+                                if let Some(Res::Def(DefKind::TyParam, def_id)) = self
+                                    .resolver
                                     .get_partial_res(bound_pred.bounded_ty.id)
                                     .map(|d| d.base_res())
                                 {
@@ -1400,7 +1333,8 @@ pub(super) fn lower_generics(
                                             match param.kind {
                                                 GenericParamKind::Type { .. } => {
                                                     if node_id == param.id {
-                                                        add_bounds.entry(param.id)
+                                                        add_bounds
+                                                            .entry(param.id)
                                                             .or_default()
                                                             .push(bound.clone());
                                                         continue 'next_bound;
@@ -1420,29 +1354,34 @@ pub(super) fn lower_generics(
             }
         }
 
-        hir::Generics {
-            params: self.lower_generic_params(&generics.params, &add_bounds, itctx),
+        GenericsCtor {
+            params: self.lower_generic_params_mut(&generics.params, &add_bounds, itctx),
             where_clause: self.lower_where_clause(&generics.where_clause),
             span: generics.span,
         }
     }
 
-    fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause {
-        self.with_anonymous_lifetime_mode(
-            AnonymousLifetimeMode::ReportError,
-            |this| {
-                hir::WhereClause {
-                    predicates: wc.predicates
-                        .iter()
-                        .map(|predicate| this.lower_where_predicate(predicate))
-                        .collect(),
-                    span: wc.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 {
+                predicates: this.arena.alloc_from_iter(
+                    wc.predicates.iter().map(|predicate| this.lower_where_predicate(predicate)),
+                ),
+                span: wc.span,
+            }
+        })
     }
 
-    fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate {
+    fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
         match *pred {
             WherePredicate::BoundPredicate(WhereBoundPredicate {
                 ref bound_generic_params,
@@ -1450,32 +1389,27 @@ fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicat
                 ref bounds,
                 span,
             }) => {
-                self.with_in_scope_lifetime_defs(
-                    &bound_generic_params,
-                    |this| {
-                        hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
-                            bound_generic_params: this.lower_generic_params(
-                                bound_generic_params,
-                                &NodeMap::default(),
-                                ImplTraitContext::disallowed(),
-                            ),
-                            bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::disallowed()),
-                            bounds: bounds
-                                .iter()
-                                .filter_map(|bound| match *bound {
-                                    // Ignore `?Trait` bounds.
-                                    // They were copied into type parameters already.
-                                    GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
-                                    _ => Some(this.lower_param_bound(
-                                        bound,
-                                        ImplTraitContext::disallowed(),
-                                    )),
-                                })
-                                .collect(),
-                            span,
-                        })
-                    },
-                )
+                self.with_in_scope_lifetime_defs(&bound_generic_params, |this| {
+                    hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
+                        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| {
+                            match *bound {
+                                // Ignore `?Trait` bounds.
+                                // They were copied into type parameters already.
+                                GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
+                                _ => Some(
+                                    this.lower_param_bound(bound, ImplTraitContext::disallowed()),
+                                ),
+                            }
+                        })),
+                        span,
+                    })
+                })
             }
             WherePredicate::RegionPredicate(WhereRegionPredicate {
                 ref lifetime,
@@ -1486,19 +1420,31 @@ fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicat
                 lifetime: self.lower_lifetime(lifetime),
                 bounds: self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
             }),
-            WherePredicate::EqPredicate(WhereEqPredicate {
-                id,
-                ref lhs_ty,
-                ref rhs_ty,
-                span,
-            }) => {
+            WherePredicate::EqPredicate(WhereEqPredicate { id, ref lhs_ty, ref rhs_ty, span }) => {
                 hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
                     hir_id: self.lower_node_id(id),
                     lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::disallowed()),
                     rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::disallowed()),
                     span,
                 })
-            },
+            }
+        }
+    }
+}
+
+/// Helper struct for delayed construction of Generics.
+pub(super) struct GenericsCtor<'hir> {
+    pub(super) params: Vec<hir::GenericParam<'hir>>,
+    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,
         }
     }
 }