]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_metadata/src/rmeta/encoder.rs
Rollup merge of #101435 - JakobDegen:bitwidth-tests, r=wesleywiser
[rust.git] / compiler / rustc_metadata / src / rmeta / encoder.rs
index 34d8edc30cddad783c6a4d447aa39cb5f908ddfd..039486ba02c37a466b580cfb163580f9c95a19ac 100644 (file)
@@ -1,3 +1,4 @@
+use crate::errors::{FailCreateFileEncoder, FailSeekFile, FailWriteFile};
 use crate::rmeta::def_path_hash_map::DefPathHashMapRef;
 use crate::rmeta::table::TableBuilder;
 use crate::rmeta::*;
@@ -16,7 +17,6 @@
 use rustc_hir::definitions::DefPathData;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::lang_items;
-use rustc_hir::{AnonConst, GenericParamKind};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::dependency_format::Linkage;
 use rustc_middle::middle::exported_symbols::{
@@ -1019,6 +1019,89 @@ fn should_encode_generics(def_kind: DefKind) -> bool {
     }
 }
 
+fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> bool {
+    match def_kind {
+        DefKind::Struct
+        | DefKind::Union
+        | DefKind::Enum
+        | DefKind::Variant
+        | DefKind::Ctor(..)
+        | DefKind::Field
+        | DefKind::Fn
+        | DefKind::Const
+        | DefKind::Static(..)
+        | DefKind::TyAlias
+        | DefKind::OpaqueTy
+        | DefKind::ForeignTy
+        | DefKind::Impl
+        | DefKind::AssocFn
+        | DefKind::AssocConst
+        | DefKind::Closure
+        | DefKind::Generator
+        | DefKind::ConstParam
+        | DefKind::AnonConst
+        | DefKind::InlineConst => true,
+
+        DefKind::AssocTy => {
+            let assoc_item = tcx.associated_item(def_id);
+            match assoc_item.container {
+                ty::AssocItemContainer::ImplContainer => true,
+                ty::AssocItemContainer::TraitContainer => assoc_item.defaultness(tcx).has_value(),
+            }
+        }
+        DefKind::TyParam => {
+            let hir::Node::GenericParam(param) = tcx.hir().get_by_def_id(def_id) else { bug!() };
+            let hir::GenericParamKind::Type { default, .. } = param.kind else { bug!() };
+            default.is_some()
+        }
+
+        DefKind::Trait
+        | DefKind::TraitAlias
+        | DefKind::Mod
+        | DefKind::ForeignMod
+        | DefKind::Macro(..)
+        | DefKind::Use
+        | DefKind::LifetimeParam
+        | DefKind::GlobalAsm
+        | DefKind::ExternCrate => false,
+    }
+}
+
+fn should_encode_const(def_kind: DefKind) -> bool {
+    match def_kind {
+        DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => true,
+
+        DefKind::Struct
+        | DefKind::Union
+        | DefKind::Enum
+        | DefKind::Variant
+        | DefKind::Ctor(..)
+        | DefKind::Field
+        | DefKind::Fn
+        | DefKind::Static(..)
+        | DefKind::TyAlias
+        | DefKind::OpaqueTy
+        | DefKind::ForeignTy
+        | DefKind::Impl
+        | DefKind::AssocFn
+        | DefKind::Closure
+        | DefKind::Generator
+        | DefKind::ConstParam
+        | DefKind::InlineConst
+        | DefKind::AssocTy
+        | DefKind::TyParam
+        | DefKind::Trait
+        | DefKind::TraitAlias
+        | DefKind::Mod
+        | DefKind::ForeignMod
+        | DefKind::Macro(..)
+        | DefKind::Use
+        | DefKind::LifetimeParam
+        | DefKind::GlobalAsm
+        | DefKind::ExternCrate => false,
+    }
+}
+
 impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     fn encode_attrs(&mut self, def_id: LocalDefId) {
         let mut attrs = self
@@ -1044,7 +1127,8 @@ fn encode_def_ids(&mut self) {
             let def_kind = tcx.opt_def_kind(local_id);
             let Some(def_kind) = def_kind else { continue };
             self.tables.opt_def_kind.set(def_id.index, def_kind);
-            record!(self.tables.def_span[def_id] <- tcx.def_span(def_id));
+            let def_span = tcx.def_span(local_id);
+            record!(self.tables.def_span[def_id] <- def_span);
             self.encode_attrs(local_id);
             record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id));
             if let Some(ident_span) = tcx.def_ident_span(def_id) {
@@ -1075,10 +1159,12 @@ fn encode_def_ids(&mut self) {
                     record_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives);
                 }
             }
-            if let DefKind::TyParam | DefKind::ConstParam = def_kind {
-                if let Some(default) = self.tcx.object_lifetime_default(def_id) {
-                    record!(self.tables.object_lifetime_default[def_id] <- default);
-                }
+            if should_encode_type(tcx, local_id, def_kind) {
+                record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
+            }
+            if let DefKind::TyParam = def_kind {
+                let default = self.tcx.object_lifetime_default(def_id);
+                record!(self.tables.object_lifetime_default[def_id] <- default);
             }
             if let DefKind::Trait | DefKind::TraitAlias = def_kind {
                 record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
@@ -1096,11 +1182,6 @@ fn encode_def_ids(&mut self) {
         }
     }
 
-    fn encode_item_type(&mut self, def_id: DefId) {
-        debug!("EncodeContext::encode_item_type({:?})", def_id);
-        record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
-    }
-
     fn encode_enum_variant_info(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
         let tcx = self.tcx;
         let variant = &def.variant(index);
@@ -1114,13 +1195,12 @@ fn encode_enum_variant_info(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx)
             is_non_exhaustive: variant.is_field_list_non_exhaustive(),
         };
 
-        record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
+        record!(self.tables.variant_data[def_id] <- data);
         self.tables.constness.set(def_id.index, hir::Constness::Const);
         record_array!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
             assert!(f.did.is_local());
             f.did.index
         }));
-        self.encode_item_type(def_id);
         if variant.ctor_kind == CtorKind::Fn {
             // FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`.
             if let Some(ctor_def_id) = variant.ctor_def_id {
@@ -1143,9 +1223,8 @@ fn encode_enum_variant_ctor(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx)
             is_non_exhaustive: variant.is_field_list_non_exhaustive(),
         };
 
-        record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
+        record!(self.tables.variant_data[def_id] <- data);
         self.tables.constness.set(def_id.index, hir::Constness::Const);
-        self.encode_item_type(def_id);
         if variant.ctor_kind == CtorKind::Fn {
             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
         }
@@ -1162,15 +1241,12 @@ fn encode_info_for_mod(&mut self, local_def_id: LocalDefId, md: &hir::Mod<'_>) {
         // code uses it). However, we skip encoding anything relating to child
         // items - we encode information about proc-macros later on.
         let reexports = if !self.is_proc_macro {
-            match tcx.module_reexports(local_def_id) {
-                Some(exports) => self.lazy_array(exports),
-                _ => LazyArray::empty(),
-            }
+            tcx.module_reexports(local_def_id).unwrap_or(&[])
         } else {
-            LazyArray::empty()
+            &[]
         };
 
-        record!(self.tables.kind[def_id] <- EntryKind::Mod(reexports));
+        record_array!(self.tables.module_reexports[def_id] <- reexports);
         if self.is_proc_macro {
             // Encode this here because we don't do it in encode_def_ids.
             record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id));
@@ -1198,22 +1274,6 @@ fn encode_info_for_mod(&mut self, local_def_id: LocalDefId, md: &hir::Mod<'_>) {
         }
     }
 
-    fn encode_field(
-        &mut self,
-        adt_def: ty::AdtDef<'tcx>,
-        variant_index: VariantIdx,
-        field_index: usize,
-    ) {
-        let variant = &adt_def.variant(variant_index);
-        let field = &variant.fields[field_index];
-
-        let def_id = field.did;
-        debug!("EncodeContext::encode_field({:?})", def_id);
-
-        record!(self.tables.kind[def_id] <- EntryKind::Field);
-        self.encode_item_type(def_id);
-    }
-
     fn encode_struct_ctor(&mut self, adt_def: ty::AdtDef<'tcx>, def_id: DefId) {
         debug!("EncodeContext::encode_struct_ctor({:?})", def_id);
         let tcx = self.tcx;
@@ -1227,9 +1287,8 @@ fn encode_struct_ctor(&mut self, adt_def: ty::AdtDef<'tcx>, def_id: DefId) {
         };
 
         record!(self.tables.repr_options[def_id] <- adt_def.repr());
+        record!(self.tables.variant_data[def_id] <- data);
         self.tables.constness.set(def_id.index, hir::Constness::Const);
-        record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data)));
-        self.encode_item_type(def_id);
         if variant.ctor_kind == CtorKind::Fn {
             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
         }
@@ -1250,18 +1309,10 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) {
         let ast_item = tcx.hir().expect_trait_item(def_id.expect_local());
         self.tables.impl_defaultness.set(def_id.index, ast_item.defaultness);
         let trait_item = tcx.associated_item(def_id);
+        self.tables.assoc_container.set(def_id.index, trait_item.container);
 
         match trait_item.kind {
-            ty::AssocKind::Const => {
-                let rendered = rustc_hir_pretty::to_string(
-                    &(&self.tcx.hir() as &dyn intravisit::Map<'_>),
-                    |s| s.print_trait_item(ast_item),
-                );
-
-                record!(self.tables.kind[def_id] <- EntryKind::AssocConst(ty::AssocItemContainer::TraitContainer));
-                record!(self.tables.mir_const_qualif[def_id] <- mir::ConstQualifs::default());
-                record!(self.tables.rendered_const[def_id] <- rendered);
-            }
+            ty::AssocKind::Const => {}
             ty::AssocKind::Fn => {
                 let hir::TraitItemKind::Fn(m_sig, m) = &ast_item.kind else { bug!() };
                 match *m {
@@ -1274,24 +1325,9 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) {
                 };
                 self.tables.asyncness.set(def_id.index, m_sig.header.asyncness);
                 self.tables.constness.set(def_id.index, hir::Constness::NotConst);
-                record!(self.tables.kind[def_id] <- EntryKind::AssocFn {
-                    container: ty::AssocItemContainer::TraitContainer,
-                    has_self: trait_item.fn_has_self_parameter,
-                });
             }
             ty::AssocKind::Type => {
                 self.encode_explicit_item_bounds(def_id);
-                record!(self.tables.kind[def_id] <- EntryKind::AssocType(ty::AssocItemContainer::TraitContainer));
-            }
-        }
-        match trait_item.kind {
-            ty::AssocKind::Const | ty::AssocKind::Fn => {
-                self.encode_item_type(def_id);
-            }
-            ty::AssocKind::Type => {
-                if ast_item.defaultness.has_value() {
-                    self.encode_item_type(def_id);
-                }
             }
         }
         if trait_item.kind == ty::AssocKind::Fn {
@@ -1306,20 +1342,9 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) {
         let ast_item = self.tcx.hir().expect_impl_item(def_id.expect_local());
         self.tables.impl_defaultness.set(def_id.index, ast_item.defaultness);
         let impl_item = self.tcx.associated_item(def_id);
+        self.tables.assoc_container.set(def_id.index, impl_item.container);
 
         match impl_item.kind {
-            ty::AssocKind::Const => {
-                if let hir::ImplItemKind::Const(_, body_id) = ast_item.kind {
-                    let qualifs = self.tcx.at(ast_item.span).mir_const_qualif(def_id);
-                    let const_data = self.encode_rendered_const_for_body(body_id);
-
-                    record!(self.tables.kind[def_id] <- EntryKind::AssocConst(ty::AssocItemContainer::ImplContainer));
-                    record!(self.tables.mir_const_qualif[def_id] <- qualifs);
-                    record!(self.tables.rendered_const[def_id] <- const_data);
-                } else {
-                    bug!()
-                }
-            }
             ty::AssocKind::Fn => {
                 let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() };
                 self.tables.asyncness.set(def_id.index, sig.header.asyncness);
@@ -1331,16 +1356,9 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) {
                     hir::Constness::NotConst
                 };
                 self.tables.constness.set(def_id.index, constness);
-                record!(self.tables.kind[def_id] <- EntryKind::AssocFn {
-                    container: ty::AssocItemContainer::ImplContainer,
-                    has_self: impl_item.fn_has_self_parameter,
-                });
-            }
-            ty::AssocKind::Type => {
-                record!(self.tables.kind[def_id] <- EntryKind::AssocType(ty::AssocItemContainer::ImplContainer));
             }
+            ty::AssocKind::Const | ty::AssocKind::Type => {}
         }
-        self.encode_item_type(def_id);
         if let Some(trait_item_def_id) = impl_item.trait_item_def_id {
             self.tables.trait_item_def_id.set(def_id.index, trait_item_def_id.into());
         }
@@ -1357,40 +1375,43 @@ fn encode_mir(&mut self) {
             return;
         }
 
-        let keys_and_jobs = self
-            .tcx
-            .mir_keys(())
-            .iter()
-            .filter_map(|&def_id| {
-                let (encode_const, encode_opt) = should_encode_mir(self.tcx, def_id);
-                if encode_const || encode_opt {
-                    Some((def_id, encode_const, encode_opt))
-                } else {
-                    None
-                }
-            })
-            .collect::<Vec<_>>();
-        for (def_id, encode_const, encode_opt) in keys_and_jobs.into_iter() {
+        let tcx = self.tcx;
+
+        let keys_and_jobs = tcx.mir_keys(()).iter().filter_map(|&def_id| {
+            let (encode_const, encode_opt) = should_encode_mir(tcx, def_id);
+            if encode_const || encode_opt { Some((def_id, encode_const, encode_opt)) } else { None }
+        });
+        for (def_id, encode_const, encode_opt) in keys_and_jobs {
             debug_assert!(encode_const || encode_opt);
 
             debug!("EntryBuilder::encode_mir({:?})", def_id);
             if encode_opt {
-                record!(self.tables.optimized_mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id));
+                record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id));
             }
             if encode_const {
-                record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- self.tcx.mir_for_ctfe(def_id));
+                record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- tcx.mir_for_ctfe(def_id));
 
                 // FIXME(generic_const_exprs): this feels wrong to have in `encode_mir`
-                let abstract_const = self.tcx.thir_abstract_const(def_id);
+                let abstract_const = tcx.thir_abstract_const(def_id);
                 if let Ok(Some(abstract_const)) = abstract_const {
                     record!(self.tables.thir_abstract_const[def_id.to_def_id()] <- abstract_const);
                 }
+
+                if should_encode_const(tcx.def_kind(def_id)) {
+                    let qualifs = tcx.mir_const_qualif(def_id);
+                    record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs);
+                    let body_id = tcx.hir().maybe_body_owned_by(def_id);
+                    if let Some(body_id) = body_id {
+                        let const_data = self.encode_rendered_const_for_body(body_id);
+                        record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data);
+                    }
+                }
             }
-            record!(self.tables.promoted_mir[def_id.to_def_id()] <- self.tcx.promoted_mir(def_id));
+            record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id));
 
             let instance =
                 ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id.to_def_id()));
-            let unused = self.tcx.unused_generic_params(instance);
+            let unused = tcx.unused_generic_params(instance);
             if !unused.is_empty() {
                 record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
             }
@@ -1453,38 +1474,27 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
 
         debug!("EncodeContext::encode_info_for_item({:?})", def_id);
 
-        let entry_kind = match item.kind {
-            hir::ItemKind::Static(..) => EntryKind::Static,
-            hir::ItemKind::Const(_, body_id) => {
-                let qualifs = self.tcx.at(item.span).mir_const_qualif(def_id);
-                let const_data = self.encode_rendered_const_for_body(body_id);
-                record!(self.tables.mir_const_qualif[def_id] <- qualifs);
-                record!(self.tables.rendered_const[def_id] <- const_data);
-                EntryKind::Const
-            }
+        match item.kind {
             hir::ItemKind::Fn(ref sig, .., body) => {
                 self.tables.asyncness.set(def_id.index, sig.header.asyncness);
                 record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
                 self.tables.constness.set(def_id.index, sig.header.constness);
-                EntryKind::Fn
             }
             hir::ItemKind::Macro(ref macro_def, _) => {
-                EntryKind::MacroDef(self.lazy(&*macro_def.body), macro_def.macro_rules)
+                if macro_def.macro_rules {
+                    self.tables.macro_rules.set(def_id.index, ());
+                }
+                record!(self.tables.macro_definition[def_id] <- &*macro_def.body);
             }
             hir::ItemKind::Mod(ref m) => {
                 return self.encode_info_for_mod(item.def_id, m);
             }
-            hir::ItemKind::ForeignMod { .. } => EntryKind::ForeignMod,
-            hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm,
-            hir::ItemKind::TyAlias(..) => EntryKind::Type,
             hir::ItemKind::OpaqueTy(..) => {
                 self.encode_explicit_item_bounds(def_id);
-                EntryKind::OpaqueTy
             }
             hir::ItemKind::Enum(..) => {
                 let adt_def = self.tcx.adt_def(def_id);
                 record!(self.tables.repr_options[def_id] <- adt_def.repr());
-                EntryKind::Enum
             }
             hir::ItemKind::Struct(ref struct_def, _) => {
                 let adt_def = self.tcx.adt_def(def_id);
@@ -1499,24 +1509,24 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
                     .map(|ctor_hir_id| self.tcx.hir().local_def_id(ctor_hir_id).local_def_index);
 
                 let variant = adt_def.non_enum_variant();
-                EntryKind::Struct(self.lazy(VariantData {
+                record!(self.tables.variant_data[def_id] <- VariantData {
                     ctor_kind: variant.ctor_kind,
                     discr: variant.discr,
                     ctor,
                     is_non_exhaustive: variant.is_field_list_non_exhaustive(),
-                }))
+                });
             }
             hir::ItemKind::Union(..) => {
                 let adt_def = self.tcx.adt_def(def_id);
                 record!(self.tables.repr_options[def_id] <- adt_def.repr());
 
                 let variant = adt_def.non_enum_variant();
-                EntryKind::Union(self.lazy(VariantData {
+                record!(self.tables.variant_data[def_id] <- VariantData {
                     ctor_kind: variant.ctor_kind,
                     discr: variant.discr,
                     ctor: None,
                     is_non_exhaustive: variant.is_field_list_non_exhaustive(),
-                }))
+                });
             }
             hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
                 self.tables.impl_defaultness.set(def_id.index, *defaultness);
@@ -1542,26 +1552,24 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
 
                 let polarity = self.tcx.impl_polarity(def_id);
                 self.tables.impl_polarity.set(def_id.index, polarity);
-
-                EntryKind::Impl
             }
             hir::ItemKind::Trait(..) => {
                 let trait_def = self.tcx.trait_def(def_id);
                 record!(self.tables.trait_def[def_id] <- trait_def);
-
-                EntryKind::Trait
             }
             hir::ItemKind::TraitAlias(..) => {
                 let trait_def = self.tcx.trait_def(def_id);
                 record!(self.tables.trait_def[def_id] <- trait_def);
-
-                EntryKind::TraitAlias
             }
             hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {
                 bug!("cannot encode info for item {:?}", item)
             }
+            hir::ItemKind::Static(..)
+            | hir::ItemKind::Const(..)
+            | hir::ItemKind::ForeignMod { .. }
+            | hir::ItemKind::GlobalAsm(..)
+            | hir::ItemKind::TyAlias(..) => {}
         };
-        record!(self.tables.kind[def_id] <- entry_kind);
         // FIXME(eddyb) there should be a nicer way to do this.
         match item.kind {
             hir::ItemKind::Enum(..) => record_array!(self.tables.children[def_id] <-
@@ -1589,18 +1597,6 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
             }
             _ => {}
         }
-        match item.kind {
-            hir::ItemKind::Static(..)
-            | hir::ItemKind::Const(..)
-            | hir::ItemKind::Fn(..)
-            | hir::ItemKind::TyAlias(..)
-            | hir::ItemKind::OpaqueTy(..)
-            | hir::ItemKind::Enum(..)
-            | hir::ItemKind::Struct(..)
-            | hir::ItemKind::Union(..)
-            | hir::ItemKind::Impl { .. } => self.encode_item_type(def_id),
-            _ => {}
-        }
         if let hir::ItemKind::Fn(..) = item.kind {
             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
             if tcx.is_intrinsic(def_id) {
@@ -1612,12 +1608,43 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
                 record!(self.tables.impl_trait_ref[def_id] <- trait_ref);
             }
         }
-    }
+        // In some cases, along with the item itself, we also
+        // encode some sub-items. Usually we want some info from the item
+        // so it's easier to do that here then to wait until we would encounter
+        // normally in the visitor walk.
+        match item.kind {
+            hir::ItemKind::Enum(..) => {
+                let def = self.tcx.adt_def(item.def_id.to_def_id());
+                for (i, variant) in def.variants().iter_enumerated() {
+                    self.encode_enum_variant_info(def, i);
 
-    fn encode_info_for_generic_param(&mut self, def_id: DefId, kind: EntryKind, encode_type: bool) {
-        record!(self.tables.kind[def_id] <- kind);
-        if encode_type {
-            self.encode_item_type(def_id);
+                    if let Some(_ctor_def_id) = variant.ctor_def_id {
+                        self.encode_enum_variant_ctor(def, i);
+                    }
+                }
+            }
+            hir::ItemKind::Struct(ref struct_def, _) => {
+                let def = self.tcx.adt_def(item.def_id.to_def_id());
+                // If the struct has a constructor, encode it.
+                if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
+                    let ctor_def_id = self.tcx.hir().local_def_id(ctor_hir_id);
+                    self.encode_struct_ctor(def, ctor_def_id.to_def_id());
+                }
+            }
+            hir::ItemKind::Impl { .. } => {
+                for &trait_item_def_id in
+                    self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
+                {
+                    self.encode_info_for_impl_item(trait_item_def_id);
+                }
+            }
+            hir::ItemKind::Trait(..) => {
+                for &item_def_id in self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
+                {
+                    self.encode_info_for_trait_item(item_def_id);
+                }
+            }
+            _ => {}
         }
     }
 
@@ -1632,34 +1659,16 @@ fn encode_info_for_closure(&mut self, hir_id: hir::HirId) {
             ty::Generator(..) => {
                 let data = self.tcx.generator_kind(def_id).unwrap();
                 let generator_diagnostic_data = typeck_result.get_generator_diagnostic_data();
-                record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::Generator);
                 record!(self.tables.generator_kind[def_id.to_def_id()] <- data);
                 record!(self.tables.generator_diagnostic_data[def_id.to_def_id()]  <- generator_diagnostic_data);
             }
 
-            ty::Closure(..) => {
-                record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::Closure);
+            ty::Closure(_, substs) => {
+                record!(self.tables.fn_sig[def_id.to_def_id()] <- substs.as_closure().sig());
             }
 
             _ => bug!("closure that is neither generator nor closure"),
         }
-        self.encode_item_type(def_id.to_def_id());
-        if let ty::Closure(def_id, substs) = *ty.kind() {
-            record!(self.tables.fn_sig[def_id] <- substs.as_closure().sig());
-        }
-    }
-
-    fn encode_info_for_anon_const(&mut self, id: hir::HirId) {
-        let def_id = self.tcx.hir().local_def_id(id);
-        debug!("EncodeContext::encode_info_for_anon_const({:?})", def_id);
-        let body_id = self.tcx.hir().body_owned_by(def_id);
-        let const_data = self.encode_rendered_const_for_body(body_id);
-        let qualifs = self.tcx.mir_const_qualif(def_id);
-
-        record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::AnonConst);
-        record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs);
-        record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data);
-        self.encode_item_type(def_id.to_def_id());
     }
 
     fn encode_native_libraries(&mut self) -> LazyArray<NativeLib> {
@@ -1757,7 +1766,7 @@ fn encode_proc_macros(&mut self) -> Option<ProcMacroData> {
 
                 let def_id = id.to_def_id();
                 self.tables.opt_def_kind.set(def_id.index, DefKind::Macro(macro_kind));
-                record!(self.tables.kind[def_id] <- EntryKind::ProcMacro(macro_kind));
+                self.tables.proc_macro.set(def_id.index, macro_kind);
                 self.encode_attrs(id);
                 record!(self.tables.def_keys[def_id] <- def_key);
                 record!(self.tables.def_ident_span[def_id] <- span);
@@ -1995,18 +2004,11 @@ fn encode_info_for_foreign_item(&mut self, def_id: DefId, nitem: &hir::ForeignIt
                     hir::Constness::NotConst
                 };
                 self.tables.constness.set(def_id.index, constness);
-                record!(self.tables.kind[def_id] <- EntryKind::ForeignFn);
-            }
-            hir::ForeignItemKind::Static(..) => {
-                record!(self.tables.kind[def_id] <- EntryKind::ForeignStatic);
-            }
-            hir::ForeignItemKind::Type => {
-                record!(self.tables.kind[def_id] <- EntryKind::ForeignType);
+                record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
             }
+            hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => {}
         }
-        self.encode_item_type(def_id);
         if let hir::ForeignItemKind::Fn(..) = nitem.kind {
-            record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
             if tcx.is_intrinsic(def_id) {
                 self.tables.is_intrinsic.set(def_id.index, ());
             }
@@ -2025,17 +2027,12 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
         intravisit::walk_expr(self, ex);
         self.encode_info_for_expr(ex);
     }
-    fn visit_anon_const(&mut self, c: &'tcx AnonConst) {
-        intravisit::walk_anon_const(self, c);
-        self.encode_info_for_anon_const(c.hir_id);
-    }
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
         intravisit::walk_item(self, item);
         match item.kind {
             hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {} // ignore these
             _ => self.encode_info_for_item(item.def_id.to_def_id(), item),
         }
-        self.encode_addl_info_for_item(item);
     }
     fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem<'tcx>) {
         intravisit::walk_foreign_item(self, ni);
@@ -2048,29 +2045,13 @@ fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
 }
 
 impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
-    fn encode_fields(&mut self, adt_def: ty::AdtDef<'tcx>) {
-        for (variant_index, variant) in adt_def.variants().iter_enumerated() {
-            for (field_index, _field) in variant.fields.iter().enumerate() {
-                self.encode_field(adt_def, variant_index, field_index);
-            }
-        }
-    }
-
     fn encode_info_for_generics(&mut self, generics: &hir::Generics<'tcx>) {
         for param in generics.params {
             let def_id = self.tcx.hir().local_def_id(param.hir_id);
             match param.kind {
-                GenericParamKind::Lifetime { .. } => continue,
-                GenericParamKind::Type { default, .. } => {
-                    self.encode_info_for_generic_param(
-                        def_id.to_def_id(),
-                        EntryKind::TypeParam,
-                        default.is_some(),
-                    );
-                }
-                GenericParamKind::Const { ref default, .. } => {
+                hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => {}
+                hir::GenericParamKind::Const { ref default, .. } => {
                     let def_id = def_id.to_def_id();
-                    self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true);
                     if default.is_some() {
                         record!(self.tables.const_param_default[def_id] <- self.tcx.const_param_default(def_id))
                     }
@@ -2084,68 +2065,6 @@ fn encode_info_for_expr(&mut self, expr: &hir::Expr<'_>) {
             self.encode_info_for_closure(expr.hir_id);
         }
     }
-
-    /// In some cases, along with the item itself, we also
-    /// encode some sub-items. Usually we want some info from the item
-    /// so it's easier to do that here then to wait until we would encounter
-    /// normally in the visitor walk.
-    fn encode_addl_info_for_item(&mut self, item: &hir::Item<'_>) {
-        match item.kind {
-            hir::ItemKind::Static(..)
-            | hir::ItemKind::Const(..)
-            | hir::ItemKind::Fn(..)
-            | hir::ItemKind::Macro(..)
-            | hir::ItemKind::Mod(..)
-            | hir::ItemKind::ForeignMod { .. }
-            | hir::ItemKind::GlobalAsm(..)
-            | hir::ItemKind::ExternCrate(..)
-            | hir::ItemKind::Use(..)
-            | hir::ItemKind::TyAlias(..)
-            | hir::ItemKind::OpaqueTy(..)
-            | hir::ItemKind::TraitAlias(..) => {
-                // no sub-item recording needed in these cases
-            }
-            hir::ItemKind::Enum(..) => {
-                let def = self.tcx.adt_def(item.def_id.to_def_id());
-                self.encode_fields(def);
-
-                for (i, variant) in def.variants().iter_enumerated() {
-                    self.encode_enum_variant_info(def, i);
-
-                    if let Some(_ctor_def_id) = variant.ctor_def_id {
-                        self.encode_enum_variant_ctor(def, i);
-                    }
-                }
-            }
-            hir::ItemKind::Struct(ref struct_def, _) => {
-                let def = self.tcx.adt_def(item.def_id.to_def_id());
-                self.encode_fields(def);
-
-                // If the struct has a constructor, encode it.
-                if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
-                    let ctor_def_id = self.tcx.hir().local_def_id(ctor_hir_id);
-                    self.encode_struct_ctor(def, ctor_def_id.to_def_id());
-                }
-            }
-            hir::ItemKind::Union(..) => {
-                let def = self.tcx.adt_def(item.def_id.to_def_id());
-                self.encode_fields(def);
-            }
-            hir::ItemKind::Impl { .. } => {
-                for &trait_item_def_id in
-                    self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
-                {
-                    self.encode_info_for_impl_item(trait_item_def_id);
-                }
-            }
-            hir::ItemKind::Trait(..) => {
-                for &item_def_id in self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
-                {
-                    self.encode_info_for_trait_item(item_def_id);
-                }
-            }
-        }
-    }
 }
 
 /// Used to prefetch queries which will be needed later by metadata encoding.
@@ -2268,7 +2187,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path) {
 
 fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
     let mut encoder = opaque::FileEncoder::new(path)
-        .unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to create file encoder: {}", err)));
+        .unwrap_or_else(|err| tcx.sess.emit_fatal(FailCreateFileEncoder { err }));
     encoder.emit_raw_bytes(METADATA_HEADER);
 
     // Will be filled with the root position after encoding everything.
@@ -2313,10 +2232,10 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
     // Encode the root position.
     let header = METADATA_HEADER.len();
     file.seek(std::io::SeekFrom::Start(header as u64))
-        .unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to seek the file: {}", err)));
+        .unwrap_or_else(|err| tcx.sess.emit_fatal(FailSeekFile { err }));
     let pos = root.position.get();
     file.write_all(&[(pos >> 24) as u8, (pos >> 16) as u8, (pos >> 8) as u8, (pos >> 0) as u8])
-        .unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to write to the file: {}", err)));
+        .unwrap_or_else(|err| tcx.sess.emit_fatal(FailWriteFile { err }));
 
     // Return to the position where we are before writing the root position.
     file.seek(std::io::SeekFrom::Start(pos_before_seek)).unwrap();