about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2019-11-28 11:49:29 +0100
committerCamille GILLOT <gillot.camille@gmail.com>2019-12-21 23:12:44 +0100
commit4dc79f1f7d8aabbed2983a91ba1027373b376a65 (patch)
treed14ce8549fc04e51e39fe1f0ae2b7c54cfb4bbe3
parentfc5deca2143a448d10a1241a777275e59448c94d (diff)
downloadrust-4dc79f1f7d8aabbed2983a91ba1027373b376a65.tar.gz
rust-4dc79f1f7d8aabbed2983a91ba1027373b376a65.zip
Use Arena inside hir::Crate.
-rw-r--r--src/librustc/arena.rs5
-rw-r--r--src/librustc/hir/intravisit.rs6
-rw-r--r--src/librustc/hir/lowering.rs61
-rw-r--r--src/librustc/hir/lowering/expr.rs10
-rw-r--r--src/librustc/hir/lowering/item.rs26
-rw-r--r--src/librustc/hir/map/collector.rs4
-rw-r--r--src/librustc/hir/map/mod.rs18
-rw-r--r--src/librustc/hir/mod.rs10
-rw-r--r--src/librustc/hir/print.rs4
-rw-r--r--src/librustc/ich/hcx.rs4
-rw-r--r--src/librustc/lint/mod.rs6
-rw-r--r--src/librustc/middle/lib_features.rs2
-rw-r--r--src/librustc_driver/pretty.rs2
-rw-r--r--src/librustc_incremental/assert_module_sources.rs2
-rw-r--r--src/librustc_interface/passes.rs17
-rw-r--r--src/librustc_interface/queries.rs7
-rw-r--r--src/librustc_lint/builtin.rs4
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs2
-rw-r--r--src/librustc_passes/dead.rs6
-rw-r--r--src/librustc_passes/hir_stats.rs4
-rw-r--r--src/librustc_typeck/check/method/suggest.rs2
-rw-r--r--src/librustdoc/visit_ast.rs4
22 files changed, 109 insertions, 97 deletions
diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index eb7a1709801..59d57c6ae24 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -93,7 +93,6 @@ macro_rules! arena_types {
                         rustc::hir::def_id::CrateNum
                     >
                 >,
-            [few] hir_forest: rustc::hir::map::Forest,
             [few] diagnostic_items: rustc_data_structures::fx::FxHashMap<
                 syntax::symbol::Symbol,
                 rustc::hir::def_id::DefId,
@@ -123,6 +122,10 @@ macro_rules! arena_types {
             [few] crate_variances: rustc::ty::CrateVariancesMap<'tcx>,
             [few] inferred_outlives_crate: rustc::ty::CratePredicatesMap<'tcx>,
             [] upvars: rustc_data_structures::fx::FxIndexMap<rustc::hir::HirId, rustc::hir::Upvar>,
+            // HIR nodes arenas
+            [few] hir_forest: rustc::hir::map::Forest<$tcx>,
+            [] attribute: syntax::ast::Attribute,
+            [] macro_def: rustc::hir::MacroDef,
         ], $tcx);
     )
 }
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index a4557a0776c..e71e05678f3 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -382,10 +382,10 @@ pub trait Visitor<'v>: Sized {
 }
 
 /// Walks the contents of a crate. See also `Crate::visit_all_items`.
-pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) {
+pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate<'v>) {
     visitor.visit_mod(&krate.module, krate.span, CRATE_HIR_ID);
-    walk_list!(visitor, visit_attribute, &krate.attrs);
-    walk_list!(visitor, visit_macro_def, &krate.exported_macros);
+    walk_list!(visitor, visit_attribute, krate.attrs);
+    walk_list!(visitor, visit_macro_def, krate.exported_macros);
 }
 
 pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef) {
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 2fd708f1ea3..a8f0c90ab3a 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -35,6 +35,7 @@
 mod expr;
 mod item;
 
+use crate::arena::Arena;
 use crate::dep_graph::DepGraph;
 use crate::hir::{self, ParamName};
 use crate::hir::HirVec;
@@ -77,7 +78,7 @@ use rustc_error_codes::*;
 
 const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
 
-pub struct LoweringContext<'a> {
+pub struct LoweringContext<'a, 'hir: 'a> {
     crate_root: Option<Symbol>,
 
     /// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
@@ -90,6 +91,9 @@ pub struct LoweringContext<'a> {
     /// librustc is independent of the parser, we use dynamic dispatch here.
     nt_to_tokenstream: NtToTokenstream,
 
+    /// Used to allocate HIR nodes
+    arena: &'hir Arena<'hir>,
+
     /// The items being lowered are collected here.
     items: BTreeMap<hir::HirId, hir::Item>,
 
@@ -240,13 +244,14 @@ impl<'a> ImplTraitContext<'a> {
     }
 }
 
-pub fn lower_crate(
-    sess: &Session,
-    dep_graph: &DepGraph,
-    krate: &Crate,
-    resolver: &mut dyn Resolver,
+pub fn lower_crate<'a, 'hir>(
+    sess: &'a Session,
+    dep_graph: &'a DepGraph,
+    krate: &'a Crate,
+    resolver: &'a mut dyn Resolver,
     nt_to_tokenstream: NtToTokenstream,
-) -> hir::Crate {
+    arena: &'hir Arena<'hir>,
+) -> hir::Crate<'hir> {
     // We're constructing the HIR here; we don't care what we will
     // read, since we haven't even constructed the *input* to
     // incr. comp. yet.
@@ -259,6 +264,7 @@ pub fn lower_crate(
         sess,
         resolver,
         nt_to_tokenstream,
+        arena,
         items: BTreeMap::new(),
         trait_items: BTreeMap::new(),
         impl_items: BTreeMap::new(),
@@ -382,19 +388,19 @@ impl<'a, 'b> Visitor<'a> for ImplTraitTypeIdVisitor<'b> {
     }
 }
 
-impl<'a> LoweringContext<'a> {
-    fn lower_crate(mut self, c: &Crate) -> hir::Crate {
+impl<'a, 'hir> LoweringContext<'a, 'hir> {
+    fn lower_crate(mut self, c: &Crate) -> hir::Crate<'hir> {
         /// Full-crate AST visitor that inserts into a fresh
         /// `LoweringContext` any information that may be
         /// needed from arbitrary locations in the crate,
         /// e.g., the number of lifetime generic parameters
         /// declared for every type and trait definition.
-        struct MiscCollector<'tcx, 'interner> {
-            lctx: &'tcx mut LoweringContext<'interner>,
+        struct MiscCollector<'tcx, 'lowering, 'hir> {
+            lctx: &'tcx mut LoweringContext<'lowering, 'hir>,
             hir_id_owner: Option<NodeId>,
         }
 
-        impl MiscCollector<'_, '_> {
+        impl MiscCollector<'_, '_, '_> {
             fn allocate_use_tree_hir_id_counters(
                 &mut self,
                 tree: &UseTree,
@@ -434,7 +440,7 @@ impl<'a> LoweringContext<'a> {
             }
         }
 
-        impl<'tcx, 'interner> Visitor<'tcx> for MiscCollector<'tcx, 'interner> {
+        impl<'tcx, 'lowering, 'hir> Visitor<'tcx> for MiscCollector<'tcx, 'lowering, 'hir> {
             fn visit_pat(&mut self, p: &'tcx Pat) {
                 if let PatKind::Paren(..) | PatKind::Rest = p.kind {
                     // Doesn't generate a HIR node
@@ -537,7 +543,7 @@ impl<'a> LoweringContext<'a> {
         visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c);
 
         let module = self.lower_mod(&c.module);
-        let attrs = self.lower_attrs(&c.attrs);
+        let attrs = self.arena.alloc_from_iter(self.lower_attrs(&c.attrs).into_iter());
         let body_ids = body_ids(&self.bodies);
 
         self.resolver
@@ -548,8 +554,8 @@ impl<'a> LoweringContext<'a> {
             module,
             attrs,
             span: c.span,
-            exported_macros: hir::HirVec::from(self.exported_macros),
-            non_exported_macro_attrs: hir::HirVec::from(self.non_exported_macro_attrs),
+            exported_macros: self.arena.alloc_from_iter(self.exported_macros),
+            non_exported_macro_attrs: self.arena.alloc_from_iter(self.non_exported_macro_attrs),
             items: self.items,
             trait_items: self.trait_items,
             impl_items: self.impl_items,
@@ -750,7 +756,7 @@ impl<'a> LoweringContext<'a> {
         f: F,
     ) -> (Vec<hir::GenericParam>, T)
     where
-        F: FnOnce(&mut LoweringContext<'_>) -> (Vec<hir::GenericParam>, T),
+        F: FnOnce(&mut LoweringContext<'_, '_>) -> (Vec<hir::GenericParam>, T),
     {
         assert!(!self.is_collecting_in_band_lifetimes);
         assert!(self.lifetimes_to_define.is_empty());
@@ -867,7 +873,7 @@ impl<'a> LoweringContext<'a> {
     // for them.
     fn with_in_scope_lifetime_defs<T, F>(&mut self, params: &[GenericParam], f: F) -> T
     where
-        F: FnOnce(&mut LoweringContext<'_>) -> T,
+        F: FnOnce(&mut LoweringContext<'_, '_>) -> T,
     {
         let old_len = self.in_scope_lifetimes.len();
         let lt_def_names = params.iter().filter_map(|param| match param.kind {
@@ -896,7 +902,7 @@ impl<'a> LoweringContext<'a> {
         f: F,
     ) -> (hir::Generics, T)
     where
-        F: FnOnce(&mut LoweringContext<'_>, &mut Vec<hir::GenericParam>) -> T,
+        F: FnOnce(&mut LoweringContext<'_, '_>, &mut Vec<hir::GenericParam>) -> T,
     {
         let (in_band_defs, (mut lowered_generics, res)) = self.with_in_scope_lifetime_defs(
             &generics.params,
@@ -945,7 +951,7 @@ impl<'a> LoweringContext<'a> {
 
     fn with_dyn_type_scope<T, F>(&mut self, in_scope: bool, f: F) -> T
     where
-        F: FnOnce(&mut LoweringContext<'_>) -> T,
+        F: FnOnce(&mut LoweringContext<'_, '_>) -> T,
     {
         let was_in_dyn_type = self.is_in_dyn_type;
         self.is_in_dyn_type = in_scope;
@@ -959,7 +965,7 @@ impl<'a> LoweringContext<'a> {
 
     fn with_new_scopes<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut LoweringContext<'_>) -> T,
+        F: FnOnce(&mut LoweringContext<'_, '_>) -> T,
     {
         let was_in_loop_condition = self.is_in_loop_condition;
         self.is_in_loop_condition = false;
@@ -1446,7 +1452,7 @@ impl<'a> LoweringContext<'a> {
         span: Span,
         fn_def_id: Option<DefId>,
         opaque_ty_node_id: NodeId,
-        lower_bounds: impl FnOnce(&mut LoweringContext<'_>) -> hir::GenericBounds,
+        lower_bounds: impl FnOnce(&mut LoweringContext<'_, '_>) -> hir::GenericBounds,
     ) -> hir::TyKind {
         debug!(
             "lower_opaque_impl_trait(fn_def_id={:?}, opaque_ty_node_id={:?}, span={:?})",
@@ -1563,8 +1569,8 @@ impl<'a> LoweringContext<'a> {
         // This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that
         // appear in the bounds, excluding lifetimes that are created within the bounds.
         // E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`.
-        struct ImplTraitLifetimeCollector<'r, 'a> {
-            context: &'r mut LoweringContext<'a>,
+        struct ImplTraitLifetimeCollector<'r, 'a, 'hir> {
+            context: &'r mut LoweringContext<'a, 'hir>,
             parent: DefIndex,
             opaque_ty_id: NodeId,
             collect_elided_lifetimes: bool,
@@ -1574,7 +1580,7 @@ impl<'a> LoweringContext<'a> {
             output_lifetime_params: Vec<hir::GenericParam>,
         }
 
-        impl<'r, 'a, 'v> hir::intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a> {
+        impl<'r, 'a, 'v, 'hir> hir::intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a, 'hir> {
             fn nested_visit_map<'this>(
                 &'this mut self,
             ) -> hir::intravisit::NestedVisitorMap<'this, 'v> {
@@ -2757,8 +2763,9 @@ impl<'a> LoweringContext<'a> {
         let node = match p.kind {
             PatKind::Wild => hir::PatKind::Wild,
             PatKind::Ident(ref binding_mode, ident, ref sub) => {
-                let lower_sub = |this: &mut Self| sub.as_ref().map(|x| this.lower_pat(x));
-                self.lower_pat_ident(p, binding_mode, ident, lower_sub)
+                let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s));
+                let node = self.lower_pat_ident(p, binding_mode, ident, lower_sub);
+                node
             }
             PatKind::Lit(ref e) => hir::PatKind::Lit(P(self.lower_expr(e))),
             PatKind::TupleStruct(ref path, ref pats) => {
diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index a1a37719812..08b00ce69ad 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -13,7 +13,7 @@ use syntax::symbol::{sym, Symbol};
 
 use rustc_error_codes::*;
 
-impl LoweringContext<'_> {
+impl LoweringContext<'_, '_> {
     fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> HirVec<hir::Expr> {
         exprs.iter().map(|x| self.lower_expr(x)).collect()
     }
@@ -473,7 +473,7 @@ impl LoweringContext<'_> {
         ret_ty: Option<AstP<Ty>>,
         span: Span,
         async_gen_kind: hir::AsyncGeneratorKind,
-        body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
+        body: impl FnOnce(&mut LoweringContext<'_, '_>) -> hir::Expr,
     ) -> hir::ExprKind {
         let output = match ret_ty {
             Some(ty) => FunctionRetTy::Ty(ty),
@@ -909,7 +909,7 @@ impl LoweringContext<'_> {
 
     fn with_catch_scope<T, F>(&mut self, catch_id: NodeId, f: F) -> T
     where
-        F: FnOnce(&mut LoweringContext<'_>) -> T,
+        F: FnOnce(&mut LoweringContext<'_, '_>) -> T,
     {
         let len = self.catch_scopes.len();
         self.catch_scopes.push(catch_id);
@@ -928,7 +928,7 @@ impl LoweringContext<'_> {
 
     fn with_loop_scope<T, F>(&mut self, loop_id: NodeId, f: F) -> T
     where
-        F: FnOnce(&mut LoweringContext<'_>) -> T,
+        F: FnOnce(&mut LoweringContext<'_, '_>) -> T,
     {
         // We're no longer in the base loop's condition; we're in another loop.
         let was_in_loop_condition = self.is_in_loop_condition;
@@ -953,7 +953,7 @@ impl LoweringContext<'_> {
 
     fn with_loop_condition_scope<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut LoweringContext<'_>) -> T,
+        F: FnOnce(&mut LoweringContext<'_, '_>) -> T,
     {
         let was_in_loop_condition = self.is_in_loop_condition;
         self.is_in_loop_condition = true;
diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs
index 6cae8e2cc04..a4c9394c92d 100644
--- a/src/librustc/hir/lowering/item.rs
+++ b/src/librustc/hir/lowering/item.rs
@@ -24,11 +24,11 @@ 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),
@@ -44,8 +44,8 @@ impl<'tcx, 'interner> ItemLowerer<'tcx, 'interner> {
     }
 }
 
-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 {
@@ -60,7 +60,7 @@ impl<'tcx, 'interner> Visitor<'tcx> for ItemLowerer<'tcx, 'interner> {
         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| {
@@ -85,7 +85,7 @@ impl<'tcx, 'interner> Visitor<'tcx> for ItemLowerer<'tcx, 'interner> {
         }
     }
 
-    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 };
@@ -96,7 +96,7 @@ impl<'tcx, 'interner> Visitor<'tcx> for ItemLowerer<'tcx, 'interner> {
         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 };
@@ -107,7 +107,7 @@ impl<'tcx, 'interner> Visitor<'tcx> for ItemLowerer<'tcx, 'interner> {
     }
 }
 
-impl LoweringContext<'_> {
+impl LoweringContext<'_, '_> {
     // 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
@@ -116,7 +116,7 @@ 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();
 
@@ -144,7 +144,7 @@ impl LoweringContext<'_> {
     // 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![]);
 
@@ -1055,7 +1055,7 @@ impl LoweringContext<'_> {
 
     fn lower_body(
         &mut self,
-        f: impl FnOnce(&mut LoweringContext<'_>) -> (HirVec<hir::Param>, hir::Expr),
+        f: impl FnOnce(&mut LoweringContext<'_, '_>) -> (HirVec<hir::Param>, hir::Expr),
     ) -> hir::BodyId {
         let prev_gen_kind = self.generator_kind.take();
         let (parameters, result) = f(self);
@@ -1076,7 +1076,7 @@ impl LoweringContext<'_> {
     pub(super) fn lower_fn_body(
         &mut self,
         decl: &FnDecl,
-        body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
+        body: impl FnOnce(&mut LoweringContext<'_, '_>) -> hir::Expr,
     ) -> hir::BodyId {
         self.lower_body(|this| (
             decl.inputs.iter().map(|x| this.lower_param(x)).collect(),
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index b0fa844c818..f472bc6d38e 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -22,7 +22,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 /// A visitor that walks over the HIR and collects `Node`s into a HIR map.
 pub(super) struct NodeCollector<'a, 'hir> {
     /// The crate
-    krate: &'hir Crate,
+    krate: &'hir Crate<'hir>,
 
     /// Source map
     source_map: &'a SourceMap,
@@ -99,7 +99,7 @@ where
 
 impl<'a, 'hir> NodeCollector<'a, 'hir> {
     pub(super) fn root(sess: &'a Session,
-                       krate: &'hir Crate,
+                       krate: &'hir Crate<'hir>,
                        dep_graph: &'a DepGraph,
                        definitions: &'a definitions::Definitions,
                        hir_to_node_id: &'a FxHashMap<HirId, NodeId>,
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 69e772697f8..a44dbeb0366 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -153,20 +153,20 @@ impl<'hir> Entry<'hir> {
 }
 
 /// Stores a crate and any number of inlined items from other crates.
-pub struct Forest {
-    krate: Crate,
+pub struct Forest<'hir> {
+    krate: Crate<'hir>,
     pub dep_graph: DepGraph,
 }
 
-impl Forest {
-    pub fn new(krate: Crate, dep_graph: &DepGraph) -> Forest {
+impl Forest<'hir> {
+    pub fn new(krate: Crate<'hir>, dep_graph: &DepGraph) -> Forest<'hir> {
         Forest {
             krate,
             dep_graph: dep_graph.clone(),
         }
     }
 
-    pub fn krate(&self) -> &Crate {
+    pub fn krate(&self) -> &Crate<'hir> {
         self.dep_graph.read(DepNode::new_no_params(DepKind::Krate));
         &self.krate
     }
@@ -174,7 +174,7 @@ impl Forest {
     /// This is used internally in the dependency tracking system.
     /// Use the `krate` method to ensure your dependency on the
     /// crate is tracked.
-    pub fn untracked_krate(&self) -> &Crate {
+    pub fn untracked_krate(&self) -> &Crate<'hir> {
         &self.krate
     }
 }
@@ -189,7 +189,7 @@ pub(super) type HirEntryMap<'hir> = IndexVec<DefIndex, IndexVec<ItemLocalId, Opt
 #[derive(Clone)]
 pub struct Map<'hir> {
     /// The backing storage for all the AST nodes.
-    pub forest: &'hir Forest,
+    pub forest: &'hir Forest<'hir>,
 
     /// Same as the dep_graph in forest, just available with one fewer
     /// deref. This is a gratuitous micro-optimization.
@@ -439,7 +439,7 @@ impl<'hir> Map<'hir> {
         self.lookup(id).cloned()
     }
 
-    pub fn krate(&self) -> &'hir Crate {
+    pub fn krate(&self) -> &'hir Crate<'hir> {
         self.forest.krate()
     }
 
@@ -1257,7 +1257,7 @@ impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } }
 
 pub fn map_crate<'hir>(sess: &crate::session::Session,
                        cstore: &CrateStoreDyn,
-                       forest: &'hir Forest,
+                       forest: &'hir Forest<'hir>,
                        definitions: Definitions)
                        -> Map<'hir> {
     let _prof_timer = sess.prof.generic_activity("build_hir_map");
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 368269ff200..aa2bde07e6f 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -742,13 +742,13 @@ pub struct ModuleItems {
 ///
 /// [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html
 #[derive(RustcEncodable, RustcDecodable, Debug)]
-pub struct Crate {
+pub struct Crate<'hir> {
     pub module: Mod,
-    pub attrs: HirVec<Attribute>,
+    pub attrs: &'hir [Attribute],
     pub span: Span,
-    pub exported_macros: HirVec<MacroDef>,
+    pub exported_macros: &'hir [MacroDef],
     // Attributes from non-exported macros, kept only for collecting the library feature list.
-    pub non_exported_macro_attrs: HirVec<Attribute>,
+    pub non_exported_macro_attrs: &'hir [Attribute],
 
     // N.B., we use a `BTreeMap` here so that `visit_all_items` iterates
     // over the ids in increasing order. In principle it should not
@@ -774,7 +774,7 @@ pub struct Crate {
     pub modules: BTreeMap<HirId, ModuleItems>,
 }
 
-impl Crate {
+impl Crate<'_> {
     pub fn item(&self, id: HirId) -> &Item {
         &self.items[&id]
     }
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 92ad1c38fa0..fd121f6a9b7 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -52,7 +52,7 @@ pub struct NoAnn;
 impl PpAnn for NoAnn {}
 pub const NO_ANN: &dyn PpAnn = &NoAnn;
 
-impl PpAnn for hir::Crate {
+impl PpAnn for hir::Crate<'a> {
     fn try_fetch_item(&self, item: hir::HirId) -> Option<&hir::Item> {
         Some(self.item(item))
     }
@@ -107,7 +107,7 @@ pub const INDENT_UNIT: usize = 4;
 /// it can scan the input text for comments to copy forward.
 pub fn print_crate<'a>(cm: &'a SourceMap,
                        sess: &ParseSess,
-                       krate: &hir::Crate,
+                       krate: &hir::Crate<'a>,
                        filename: FileName,
                        input: String,
                        ann: &'a dyn PpAnn) -> String {
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
index 8b35839c182..77a9bcd67a5 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc/ich/hcx.rs
@@ -56,7 +56,7 @@ pub enum NodeIdHashingMode {
 /// We could also just store a plain reference to the `hir::Crate` but we want
 /// to avoid that the crate is used to get untracked access to all of the HIR.
 #[derive(Clone, Copy)]
-struct BodyResolver<'tcx>(&'tcx hir::Crate);
+struct BodyResolver<'tcx>(&'tcx hir::Crate<'tcx>);
 
 impl<'tcx> BodyResolver<'tcx> {
     /// Returns a reference to the `hir::Body` with the given `BodyId`.
@@ -72,7 +72,7 @@ impl<'a> StableHashingContext<'a> {
     /// leaking data out of the tracking system.
     #[inline]
     pub fn new(sess: &'a Session,
-               krate: &'a hir::Crate,
+               krate: &'a hir::Crate<'a>,
                definitions: &'a Definitions,
                cstore: &'a dyn CrateStore)
                -> Self {
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 0054f149f8c..20bc1793dc1 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -90,8 +90,8 @@ macro_rules! late_lint_methods {
             fn check_body(a: &$hir hir::Body);
             fn check_body_post(a: &$hir hir::Body);
             fn check_name(a: Span, b: ast::Name);
-            fn check_crate(a: &$hir hir::Crate);
-            fn check_crate_post(a: &$hir hir::Crate);
+            fn check_crate(a: &$hir hir::Crate<$hir>);
+            fn check_crate_post(a: &$hir hir::Crate<$hir>);
             fn check_mod(a: &$hir hir::Mod, b: Span, c: hir::HirId);
             fn check_mod_post(a: &$hir hir::Mod, b: Span, c: hir::HirId);
             fn check_foreign_item(a: &$hir hir::ForeignItem);
@@ -562,7 +562,7 @@ fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap {
 
     let push = builder.levels.push(&krate.attrs, &store);
     builder.levels.register_id(hir::CRATE_HIR_ID);
-    for macro_def in &krate.exported_macros {
+    for macro_def in krate.exported_macros {
        builder.levels.register_id(macro_def.hir_id);
     }
     intravisit::walk_crate(&mut builder, krate);
diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs
index e6f8521216b..c38ab525ce4 100644
--- a/src/librustc/middle/lib_features.rs
+++ b/src/librustc/middle/lib_features.rs
@@ -157,7 +157,7 @@ impl Visitor<'tcx> for LibFeatureCollector<'tcx> {
 pub fn collect(tcx: TyCtxt<'_>) -> LibFeatures {
     let mut collector = LibFeatureCollector::new(tcx);
     let krate = tcx.hir().krate();
-    for attr in &krate.non_exported_macro_attrs {
+    for attr in krate.non_exported_macro_attrs {
         collector.visit_attribute(attr);
     }
     intravisit::walk_crate(&mut collector, krate);
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 11603f6d9c1..97e4cf72124 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -73,7 +73,7 @@ where
 }
 fn call_with_pp_support_hir<A, F>(ppmode: &PpSourceMode, tcx: TyCtxt<'_>, f: F) -> A
 where
-    F: FnOnce(&dyn HirPrinterSupport<'_>, &hir::Crate) -> A,
+    F: FnOnce(&dyn HirPrinterSupport<'_>, &hir::Crate<'_>) -> A,
 {
     match *ppmode {
         PpmNormal => {
diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs
index 1a675ea002c..8b692d84b11 100644
--- a/src/librustc_incremental/assert_module_sources.rs
+++ b/src/librustc_incremental/assert_module_sources.rs
@@ -47,7 +47,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) {
             available_cgus
         };
 
-        for attr in &tcx.hir().krate().attrs {
+        for attr in tcx.hir().krate().attrs {
             ams.check_attr(attr);
         }
     })
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 2a4bc41f850..e1c4c86d9d6 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -446,17 +446,18 @@ fn configure_and_expand_inner<'a>(
     Ok((krate, resolver))
 }
 
-pub fn lower_to_hir(
-    sess: &Session,
+pub fn lower_to_hir<'res, 'tcx>(
+    sess: &'tcx Session,
     lint_store: &lint::LintStore,
-    resolver: &mut Resolver<'_>,
-    dep_graph: &DepGraph,
-    krate: &ast::Crate,
-) -> Result<hir::map::Forest> {
+    resolver: &'res mut Resolver<'_>,
+    dep_graph: &'res DepGraph,
+    krate: &'res ast::Crate,
+    arena: &'tcx Arena<'tcx>,
+) -> Result<hir::map::Forest<'tcx>> {
     // Lower AST to HIR.
     let hir_forest = time(sess, "lowering AST -> HIR", || {
         let nt_to_tokenstream = rustc_parse::nt_to_tokenstream;
-        let hir_crate = lower_crate(sess, &dep_graph, &krate, resolver, nt_to_tokenstream);
+        let hir_crate = lower_crate(sess, &dep_graph, &krate, resolver, nt_to_tokenstream, arena);
 
         if sess.opts.debugging_opts.hir_stats {
             hir_stats::print_hir_stats(&hir_crate);
@@ -738,7 +739,7 @@ impl<'tcx> QueryContext<'tcx> {
 pub fn create_global_ctxt<'tcx>(
     compiler: &'tcx Compiler,
     lint_store: Lrc<lint::LintStore>,
-    hir_forest: &'tcx hir::map::Forest,
+    hir_forest: &'tcx hir::map::Forest<'tcx>,
     mut resolver_outputs: ResolverOutputs,
     outputs: OutputFilenames,
     crate_name: &str,
diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs
index e429b4d101a..d6de9d5f4e4 100644
--- a/src/librustc_interface/queries.rs
+++ b/src/librustc_interface/queries.rs
@@ -82,7 +82,7 @@ pub struct Queries<'tcx> {
     register_plugins: Query<(ast::Crate, Lrc<LintStore>)>,
     expansion: Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>,
     dep_graph: Query<DepGraph>,
-    lower_to_hir: Query<(&'tcx hir::map::Forest, Steal<ResolverOutputs>)>,
+    lower_to_hir: Query<(&'tcx hir::map::Forest<'tcx>, Steal<ResolverOutputs>)>,
     prepare_outputs: Query<OutputFilenames>,
     global_ctxt: Query<QueryContext<'tcx>>,
     ongoing_codegen: Query<Box<dyn Any>>,
@@ -216,7 +216,7 @@ impl<'tcx> Queries<'tcx> {
 
     pub fn lower_to_hir(
         &'tcx self,
-    ) -> Result<&Query<(&'tcx hir::map::Forest, Steal<ResolverOutputs>)>> {
+    ) -> Result<&Query<(&'tcx hir::map::Forest<'tcx>, Steal<ResolverOutputs>)>> {
         self.lower_to_hir.compute(|| {
             let expansion_result = self.expansion()?;
             let peeked = expansion_result.peek();
@@ -229,7 +229,8 @@ impl<'tcx> Queries<'tcx> {
                     lint_store,
                     resolver,
                     &*self.dep_graph()?.peek(),
-                    &krate
+                    &krate,
+                    &self.arena,
                 )
             })?;
             let hir = self.arena.alloc(hir);
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 4cf694631d0..2e4f8e7aabc 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -378,10 +378,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
         self.doc_hidden_stack.pop().expect("empty doc_hidden_stack");
     }
 
-    fn check_crate(&mut self, cx: &LateContext<'_, '_>, krate: &hir::Crate) {
+    fn check_crate(&mut self, cx: &LateContext<'_, '_>, krate: &hir::Crate<'_>) {
         self.check_missing_docs_attrs(cx, None, &krate.attrs, krate.span, "crate");
 
-        for macro_def in &krate.exported_macros {
+        for macro_def in krate.exported_macros {
             let has_doc = macro_def.attrs.iter().any(|a| has_doc(a));
             if !has_doc {
                 cx.span_lint(MISSING_DOCS,
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index d963323342c..5649789e2c5 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -342,7 +342,7 @@ impl<'tcx> EncodeContext<'tcx> {
         let vis = Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Public };
         self.encode_info_for_mod(hir::CRATE_HIR_ID, &krate.module, &krate.attrs, &vis);
         krate.visit_all_item_likes(&mut self.as_deep_visitor());
-        for macro_def in &krate.exported_macros {
+        for macro_def in krate.exported_macros {
             self.visit_macro_def(macro_def);
         }
     }
diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs
index db661e7f4d2..fb5052fedb2 100644
--- a/src/librustc_passes/dead.rs
+++ b/src/librustc_passes/dead.rs
@@ -355,7 +355,7 @@ fn has_allow_dead_code_or_lang_attr(
 //     * Implementation of a trait method
 struct LifeSeeder<'k, 'tcx> {
     worklist: Vec<hir::HirId>,
-    krate: &'k hir::Crate,
+    krate: &'k hir::Crate<'k>,
     tcx: TyCtxt<'tcx>,
     // see `MarkSymbolVisitor::struct_constructors`
     struct_constructors: FxHashMap<hir::HirId, hir::HirId>,
@@ -429,7 +429,7 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
 fn create_and_seed_worklist<'tcx>(
     tcx: TyCtxt<'tcx>,
     access_levels: &privacy::AccessLevels,
-    krate: &hir::Crate,
+    krate: &hir::Crate<'_>,
 ) -> (Vec<hir::HirId>, FxHashMap<hir::HirId, hir::HirId>) {
     let worklist = access_levels.map.iter().filter_map(|(&id, level)| {
         if level >= &privacy::AccessLevel::Reachable {
@@ -457,7 +457,7 @@ fn create_and_seed_worklist<'tcx>(
 fn find_live<'tcx>(
     tcx: TyCtxt<'tcx>,
     access_levels: &privacy::AccessLevels,
-    krate: &hir::Crate,
+    krate: &hir::Crate<'_>,
 ) -> FxHashSet<hir::HirId> {
     let (worklist, struct_constructors) = create_and_seed_worklist(tcx, access_levels, krate);
     let mut symbol_visitor = MarkSymbolVisitor {
diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs
index 66ceb4212c8..60c486b30d4 100644
--- a/src/librustc_passes/hir_stats.rs
+++ b/src/librustc_passes/hir_stats.rs
@@ -23,12 +23,12 @@ struct NodeData {
 }
 
 struct StatCollector<'k> {
-    krate: Option<&'k hir::Crate>,
+    krate: Option<&'k hir::Crate<'k>>,
     data: FxHashMap<&'static str, NodeData>,
     seen: FxHashSet<Id>,
 }
 
-pub fn print_hir_stats(krate: &hir::Crate) {
+pub fn print_hir_stats(krate: &hir::Crate<'_>) {
     let mut collector = StatCollector {
         krate: Some(krate),
         data: FxHashMap::default(),
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 9cd8c9abfd7..1ab703db83c 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -1076,7 +1076,7 @@ struct UsePlacementFinder<'tcx> {
 impl UsePlacementFinder<'tcx> {
     fn check(
         tcx: TyCtxt<'tcx>,
-        krate: &'tcx hir::Crate,
+        krate: &'tcx hir::Crate<'tcx>,
         target_module: hir::HirId,
     ) -> (Option<Span>, bool) {
         let mut finder = UsePlacementFinder {
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index aea9b7c38ef..7ec7f460987 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -72,7 +72,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
 
     pub fn visit(mut self, krate: &'tcx hir::Crate) -> Module<'tcx> {
         let mut module = self.visit_mod_contents(krate.span,
-                                              &krate.attrs,
+                                              krate.attrs,
                                               &Spanned { span: syntax_pos::DUMMY_SP,
                                                         node: hir::VisibilityKind::Public },
                                               hir::CRATE_HIR_ID,
@@ -213,7 +213,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         }
     }
 
-    fn visit_mod_contents(&mut self, span: Span, attrs: &'tcx hir::HirVec<ast::Attribute>,
+    fn visit_mod_contents(&mut self, span: Span, attrs: &'tcx [ast::Attribute],
                               vis: &'tcx hir::Visibility, id: hir::HirId,
                               m: &'tcx hir::Mod,
                               name: Option<ast::Name>) -> Module<'tcx> {