about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-04-01 21:16:41 +0000
committerbors <bors@rust-lang.org>2022-04-01 21:16:41 +0000
commiteb82facb1626166188d49599a3313fc95201f556 (patch)
treecbccff501be86be4d6106d0544369909f896e413
parent297a8018b525c28ef10ee6a91d61954839b508b9 (diff)
parent15b2d1a97c9cefe41bcb61d5faef5682c112172a (diff)
downloadrust-eb82facb1626166188d49599a3313fc95201f556.tar.gz
rust-eb82facb1626166188d49599a3313fc95201f556.zip
Auto merge of #94883 - cjgillot:flat-metadata, r=oli-obk
Encode even more metadata through tables instead of EntryKind

This should move us closer to getting rid of `EntryKind`.
-rw-r--r--compiler/rustc_const_eval/src/const_eval/fn_queries.rs66
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs66
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs3
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs131
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs31
-rw-r--r--compiler/rustc_middle/src/query/mod.rs7
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs11
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs13
-rw-r--r--compiler/rustc_passes/src/check_attr.rs2
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs10
-rw-r--r--compiler/rustc_typeck/src/collect.rs3
11 files changed, 131 insertions, 212 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index 05fbbf45d7c..19a543ae777 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -1,7 +1,8 @@
 use rustc_hir as hir;
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::TyCtxt;
+use rustc_middle::ty::{DefIdTree, TyCtxt};
 use rustc_span::symbol::Symbol;
 use rustc_target::spec::abi::Abi;
 
@@ -16,44 +17,47 @@ pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Symbol> {
 }
 
 pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
-    let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
-    let parent_id = tcx.hir().get_parent_node(hir_id);
-    matches!(
-        tcx.hir().get(parent_id),
-        hir::Node::Item(hir::Item {
-            kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
-            ..
-        })
-    )
+    let parent_id = tcx.local_parent(def_id).unwrap();
+    tcx.def_kind(parent_id) == DefKind::Impl
+        && tcx.impl_constness(parent_id) == hir::Constness::Const
 }
 
 /// Checks whether the function has a `const` modifier or, in case it is an intrinsic, whether
 /// said intrinsic has a `rustc_const_{un,}stable` attribute.
-fn is_const_fn_raw(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
+fn impl_constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
     let def_id = def_id.expect_local();
     let node = tcx.hir().get_by_def_id(def_id);
 
-    if let hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) =
-        node
-    {
-        // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
-        // foreign items cannot be evaluated at compile-time.
-        let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
-        if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = tcx.hir().get_foreign_abi(hir_id) {
-            tcx.lookup_const_stability(def_id).is_some()
-        } else {
-            false
-        }
-    } else if let Some(fn_kind) = node.fn_kind() {
-        if fn_kind.constness() == hir::Constness::Const {
-            return true;
+    match node {
+        hir::Node::Ctor(_) => hir::Constness::Const,
+        hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness,
+        hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
+            // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
+            // foreign items cannot be evaluated at compile-time.
+            let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
+            let is_const = if let Abi::RustIntrinsic | Abi::PlatformIntrinsic =
+                tcx.hir().get_foreign_abi(hir_id)
+            {
+                tcx.lookup_const_stability(def_id).is_some()
+            } else {
+                false
+            };
+            if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
         }
+        _ => {
+            if let Some(fn_kind) = node.fn_kind() {
+                if fn_kind.constness() == hir::Constness::Const {
+                    return hir::Constness::Const;
+                }
 
-        // If the function itself is not annotated with `const`, it may still be a `const fn`
-        // if it resides in a const trait impl.
-        is_parent_const_impl_raw(tcx, def_id)
-    } else {
-        matches!(node, hir::Node::Ctor(_))
+                // If the function itself is not annotated with `const`, it may still be a `const fn`
+                // if it resides in a const trait impl.
+                let is_const = is_parent_const_impl_raw(tcx, def_id);
+                if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
+            } else {
+                hir::Constness::NotConst
+            }
+        }
     }
 }
 
@@ -77,5 +81,5 @@ fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
 }
 
 pub fn provide(providers: &mut Providers) {
-    *providers = Providers { is_const_fn_raw, is_promotable_const_fn, ..*providers };
+    *providers = Providers { impl_constness, is_promotable_const_fn, ..*providers };
 }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 6993ffbeddf..046322a42d8 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -14,7 +14,6 @@ use rustc_data_structures::sync::{Lock, LockGuard, Lrc, OnceCell};
 use rustc_data_structures::unhash::UnhashMap;
 use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
 use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, ProcMacroDerive};
-use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
@@ -909,40 +908,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         )
     }
 
-    fn get_trait_def(self, item_id: DefIndex, sess: &Session) -> ty::TraitDef {
-        match self.kind(item_id) {
-            EntryKind::Trait(data) => {
-                let data = data.decode((self, sess));
-                ty::TraitDef::new(
-                    self.local_def_id(item_id),
-                    data.unsafety,
-                    data.paren_sugar,
-                    data.has_auto_impl,
-                    data.is_marker,
-                    data.skip_array_during_method_dispatch,
-                    data.specialization_kind,
-                    self.def_path_hash(item_id),
-                    data.must_implement_one_of,
-                )
-            }
-            EntryKind::TraitAlias => ty::TraitDef::new(
-                self.local_def_id(item_id),
-                hir::Unsafety::Normal,
-                false,
-                false,
-                false,
-                false,
-                ty::trait_def::TraitSpecializationKind::None,
-                self.def_path_hash(item_id),
-                None,
-            ),
-            _ => bug!("def-index does not refer to trait or trait alias"),
-        }
-    }
-
     fn get_variant(self, kind: &EntryKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef {
         let data = match kind {
-            EntryKind::Variant(data) | EntryKind::Struct(data, _) | EntryKind::Union(data, _) => {
+            EntryKind::Variant(data) | EntryKind::Struct(data) | EntryKind::Union(data) => {
                 data.decode(self)
             }
             _ => bug!(),
@@ -988,12 +956,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         let kind = self.kind(item_id);
         let did = self.local_def_id(item_id);
 
-        let (adt_kind, repr) = match kind {
-            EntryKind::Enum(repr) => (ty::AdtKind::Enum, repr),
-            EntryKind::Struct(_, repr) => (ty::AdtKind::Struct, repr),
-            EntryKind::Union(_, repr) => (ty::AdtKind::Union, repr),
+        let adt_kind = match kind {
+            EntryKind::Enum => ty::AdtKind::Enum,
+            EntryKind::Struct(_) => ty::AdtKind::Struct,
+            EntryKind::Union(_) => ty::AdtKind::Union,
             _ => bug!("get_adt_def called on a non-ADT {:?}", did),
         };
+        let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode(self);
 
         let variants = if let ty::AdtKind::Enum = adt_kind {
             self.root
@@ -1171,7 +1140,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                     callback(exp);
                 }
             }
-            EntryKind::Enum(..) | EntryKind::Trait(..) => {}
+            EntryKind::Enum | EntryKind::Trait => {}
             _ => bug!("`for_each_module_child` is called on a non-module: {:?}", self.def_kind(id)),
         }
     }
@@ -1186,7 +1155,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
 
     fn module_expansion(self, id: DefIndex, sess: &Session) -> ExpnId {
         match self.kind(id) {
-            EntryKind::Mod(_) | EntryKind::Enum(_) | EntryKind::Trait(_) => {
+            EntryKind::Mod(_) | EntryKind::Enum | EntryKind::Trait => {
                 self.get_expn_that_defined(id, sess)
             }
             _ => panic!("Expected module, found {:?}", self.local_def_id(id)),
@@ -1239,7 +1208,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
 
     fn get_ctor_def_id_and_kind(self, node_id: DefIndex) -> Option<(DefId, CtorKind)> {
         match self.kind(node_id) {
-            EntryKind::Struct(data, _) | EntryKind::Variant(data) => {
+            EntryKind::Struct(data) | EntryKind::Variant(data) => {
                 let vdata = data.decode(self);
                 vdata.ctor.map(|index| (self.local_def_id(index), vdata.ctor_kind))
             }
@@ -1395,7 +1364,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             _ => return None,
         }
         def_key.parent.and_then(|parent_index| match self.kind(parent_index) {
-            EntryKind::Trait(_) | EntryKind::TraitAlias => Some(self.local_def_id(parent_index)),
+            EntryKind::Trait | EntryKind::TraitAlias => Some(self.local_def_id(parent_index)),
             _ => None,
         })
     }
@@ -1449,22 +1418,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         }
     }
 
-    // This replicates some of the logic of the crate-local `is_const_fn_raw` query, because we
-    // don't serialize constness for tuple variant and tuple struct constructors.
-    fn is_const_fn_raw(self, id: DefIndex) -> bool {
-        let constness = match self.kind(id) {
-            EntryKind::AssocFn(data) => data.decode(self).fn_data.constness,
-            EntryKind::Fn(data) => data.decode(self).constness,
-            EntryKind::ForeignFn(data) => data.decode(self).constness,
-            EntryKind::Variant(..) | EntryKind::Struct(..) => hir::Constness::Const,
-            _ => hir::Constness::NotConst,
-        };
-        constness == hir::Constness::Const
-    }
-
     fn is_foreign_item(self, id: DefIndex) -> bool {
         match self.kind(id) {
-            EntryKind::ForeignStatic | EntryKind::ForeignFn(_) => true,
+            EntryKind::ForeignStatic | EntryKind::ForeignFn => true,
             _ => false,
         }
     }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 5a2c59b4601..cd3a1d72d41 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -153,8 +153,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     asyncness => { table }
     fn_arg_names => { table }
     generator_kind => { table }
+    trait_def => { table }
 
-    trait_def => { cdata.get_trait_def(def_id.index, tcx.sess) }
     adt_def => { cdata.get_adt_def(def_id.index, tcx) }
     adt_destructor => {
         let _ = cdata;
@@ -163,7 +163,6 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     associated_item_def_ids => { cdata.get_associated_item_def_ids(tcx, def_id.index) }
     associated_item => { cdata.get_associated_item(def_id.index) }
     inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
-    is_const_fn_raw => { cdata.is_const_fn_raw(def_id.index) }
     is_foreign_item => { cdata.is_foreign_item(def_id.index) }
     item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) }
     trait_of_item => { cdata.get_trait_of_item(def_id.index) }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index cb3932eba35..6c758b8e5b6 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1048,6 +1048,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         };
 
         record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
+        record!(self.tables.impl_constness[def_id] <- hir::Constness::Const);
         record!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
             assert!(f.did.is_local());
             f.did.index
@@ -1077,6 +1078,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         };
 
         record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
+        record!(self.tables.impl_constness[def_id] <- 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));
@@ -1154,7 +1156,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             is_non_exhaustive: variant.is_field_list_non_exhaustive(),
         };
 
-        record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data), adt_def.repr()));
+        record!(self.tables.repr_options[def_id] <- adt_def.repr());
+        record!(self.tables.impl_constness[def_id] <- 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));
@@ -1194,22 +1198,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 record!(self.tables.rendered_const[def_id] <- rendered);
             }
             ty::AssocKind::Fn => {
-                let fn_data = if let hir::TraitItemKind::Fn(m_sig, m) = &ast_item.kind {
-                    match *m {
-                        hir::TraitFn::Required(ref names) => {
-                            record!(self.tables.fn_arg_names[def_id] <- *names)
-                        }
-                        hir::TraitFn::Provided(body) => {
-                            record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body))
-                        }
-                    };
-                    record!(self.tables.asyncness[def_id] <- m_sig.header.asyncness);
-                    FnData { constness: hir::Constness::NotConst }
-                } else {
-                    bug!()
+                let hir::TraitItemKind::Fn(m_sig, m) = &ast_item.kind else { bug!() };
+                match *m {
+                    hir::TraitFn::Required(ref names) => {
+                        record!(self.tables.fn_arg_names[def_id] <- *names)
+                    }
+                    hir::TraitFn::Provided(body) => {
+                        record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body))
+                    }
                 };
+                record!(self.tables.asyncness[def_id] <- m_sig.header.asyncness);
+                record!(self.tables.impl_constness[def_id] <- hir::Constness::NotConst);
                 record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData {
-                    fn_data,
                     container,
                     has_self: trait_item.fn_has_self_parameter,
                 })));
@@ -1264,22 +1264,17 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 }
             }
             ty::AssocKind::Fn => {
-                let fn_data = if let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind {
-                    record!(self.tables.asyncness[def_id] <- sig.header.asyncness);
-                    record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
-                    FnData {
-                        // Can be inside `impl const Trait`, so using sig.header.constness is not reliable
-                        constness: if self.tcx.is_const_fn_raw(def_id) {
-                            hir::Constness::Const
-                        } else {
-                            hir::Constness::NotConst
-                        },
-                    }
+                let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() };
+                record!(self.tables.asyncness[def_id] <- sig.header.asyncness);
+                record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
+                // Can be inside `impl const Trait`, so using sig.header.constness is not reliable
+                let constness = if self.tcx.is_const_fn_raw(def_id) {
+                    hir::Constness::Const
                 } else {
-                    bug!()
+                    hir::Constness::NotConst
                 };
+                record!(self.tables.impl_constness[def_id] <- constness);
                 record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData {
-                    fn_data,
                     container,
                     has_self: impl_item.fn_has_self_parameter,
                 })));
@@ -1401,9 +1396,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             hir::ItemKind::Fn(ref sig, .., body) => {
                 record!(self.tables.asyncness[def_id] <- sig.header.asyncness);
                 record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
-                let data = FnData { constness: sig.header.constness };
-
-                EntryKind::Fn(self.lazy(data))
+                record!(self.tables.impl_constness[def_id] <- sig.header.constness);
+                EntryKind::Fn
             }
             hir::ItemKind::Macro(ref macro_def, _) => {
                 EntryKind::MacroDef(self.lazy(&*macro_def.body), macro_def.macro_rules)
@@ -1418,10 +1412,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 self.encode_explicit_item_bounds(def_id);
                 EntryKind::OpaqueTy
             }
-            hir::ItemKind::Enum(..) => EntryKind::Enum(self.tcx.adt_def(def_id).repr()),
+            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);
-                let variant = adt_def.non_enum_variant();
+                record!(self.tables.repr_options[def_id] <- adt_def.repr());
+                record!(self.tables.impl_constness[def_id] <- hir::Constness::Const);
 
                 // Encode def_ids for each field and method
                 // for methods, write all the stuff get_trait_method
@@ -1430,29 +1429,25 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     .ctor_hir_id()
                     .map(|ctor_hir_id| self.tcx.hir().local_def_id(ctor_hir_id).local_def_index);
 
-                EntryKind::Struct(
-                    self.lazy(VariantData {
-                        ctor_kind: variant.ctor_kind,
-                        discr: variant.discr,
-                        ctor,
-                        is_non_exhaustive: variant.is_field_list_non_exhaustive(),
-                    }),
-                    adt_def.repr(),
-                )
+                let variant = adt_def.non_enum_variant();
+                EntryKind::Struct(self.lazy(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);
-                let variant = adt_def.non_enum_variant();
+                record!(self.tables.repr_options[def_id] <- adt_def.repr());
 
-                EntryKind::Union(
-                    self.lazy(VariantData {
-                        ctor_kind: variant.ctor_kind,
-                        discr: variant.discr,
-                        ctor: None,
-                        is_non_exhaustive: variant.is_field_list_non_exhaustive(),
-                    }),
-                    adt_def.repr(),
-                )
+                let variant = adt_def.non_enum_variant();
+                EntryKind::Union(self.lazy(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, .. }) => {
                 record!(self.tables.impl_defaultness[def_id] <- defaultness);
@@ -1483,19 +1478,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             }
             hir::ItemKind::Trait(..) => {
                 let trait_def = self.tcx.trait_def(def_id);
-                let data = TraitData {
-                    unsafety: trait_def.unsafety,
-                    paren_sugar: trait_def.paren_sugar,
-                    has_auto_impl: self.tcx.trait_is_auto(def_id),
-                    is_marker: trait_def.is_marker,
-                    skip_array_during_method_dispatch: trait_def.skip_array_during_method_dispatch,
-                    specialization_kind: trait_def.specialization_kind,
-                    must_implement_one_of: trait_def.must_implement_one_of.clone(),
-                };
+                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::Trait(self.lazy(data))
+                EntryKind::TraitAlias
             }
-            hir::ItemKind::TraitAlias(..) => EntryKind::TraitAlias,
             hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {
                 bug!("cannot encode info for item {:?}", item)
             }
@@ -1896,14 +1888,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             hir::ForeignItemKind::Fn(_, ref names, _) => {
                 record!(self.tables.asyncness[def_id] <- hir::IsAsync::NotAsync);
                 record!(self.tables.fn_arg_names[def_id] <- *names);
-                let data = FnData {
-                    constness: if self.tcx.is_const_fn_raw(def_id) {
-                        hir::Constness::Const
-                    } else {
-                        hir::Constness::NotConst
-                    },
+                let constness = if self.tcx.is_const_fn_raw(def_id) {
+                    hir::Constness::Const
+                } else {
+                    hir::Constness::NotConst
                 };
-                record!(self.tables.kind[def_id] <- EntryKind::ForeignFn(self.lazy(data)));
+                record!(self.tables.impl_constness[def_id] <- constness);
+                record!(self.tables.kind[def_id] <- EntryKind::ForeignFn);
             }
             hir::ForeignItemKind::Static(..) => {
                 record!(self.tables.kind[def_id] <- EntryKind::ForeignStatic);
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 06581033129..15e8693d712 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -320,11 +320,13 @@ define_tables! {
     asyncness: Table<DefIndex, Lazy!(hir::IsAsync)>,
     fn_arg_names: Table<DefIndex, Lazy!([Ident])>,
     generator_kind: Table<DefIndex, Lazy!(hir::GeneratorKind)>,
+    trait_def: Table<DefIndex, Lazy!(ty::TraitDef)>,
 
     trait_item_def_id: Table<DefIndex, Lazy<DefId>>,
     inherent_impls: Table<DefIndex, Lazy<[DefIndex]>>,
     expn_that_defined: Table<DefIndex, Lazy<ExpnId>>,
     unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>,
+    repr_options: Table<DefIndex, Lazy<ReprOptions>>,
     // `def_keys` and `def_path_hashes` represent a lazy version of a
     // `DefPathTable`. This allows us to avoid deserializing an entire
     // `DefPathTable` up front, since we may only ever use a few
@@ -347,19 +349,19 @@ enum EntryKind {
     TypeParam,
     ConstParam,
     OpaqueTy,
-    Enum(ReprOptions),
+    Enum,
     Field,
     Variant(Lazy<VariantData>),
-    Struct(Lazy<VariantData>, ReprOptions),
-    Union(Lazy<VariantData>, ReprOptions),
-    Fn(Lazy<FnData>),
-    ForeignFn(Lazy<FnData>),
+    Struct(Lazy<VariantData>),
+    Union(Lazy<VariantData>),
+    Fn,
+    ForeignFn,
     Mod(Lazy<[ModChild]>),
     MacroDef(Lazy<ast::MacArgs>, /*macro_rules*/ bool),
     ProcMacro(MacroKind),
     Closure,
     Generator,
-    Trait(Lazy<TraitData>),
+    Trait,
     Impl,
     AssocFn(Lazy<AssocFnData>),
     AssocType(AssocContainer),
@@ -367,11 +369,6 @@ enum EntryKind {
     TraitAlias,
 }
 
-#[derive(MetadataEncodable, MetadataDecodable)]
-struct FnData {
-    constness: hir::Constness,
-}
-
 #[derive(TyEncodable, TyDecodable)]
 struct VariantData {
     ctor_kind: CtorKind,
@@ -381,17 +378,6 @@ struct VariantData {
     is_non_exhaustive: bool,
 }
 
-#[derive(TyEncodable, TyDecodable)]
-struct TraitData {
-    unsafety: hir::Unsafety,
-    paren_sugar: bool,
-    has_auto_impl: bool,
-    is_marker: bool,
-    skip_array_during_method_dispatch: bool,
-    specialization_kind: ty::trait_def::TraitSpecializationKind,
-    must_implement_one_of: Option<Box<[Ident]>>,
-}
-
 /// Describes whether the container of an associated item
 /// is a trait or an impl and whether, in a trait, it has
 /// a default, or an in impl, whether it's marked "default".
@@ -429,7 +415,6 @@ impl AssocContainer {
 
 #[derive(MetadataEncodable, MetadataDecodable)]
 struct AssocFnData {
-    fn_data: FnData,
     container: AssocContainer,
     has_self: bool,
 }
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index bf45269e06f..14c11187fc5 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -559,7 +559,7 @@ rustc_queries! {
     ///
     /// **Do not call this function manually.** It is only meant to cache the base data for the
     /// `is_const_fn` function.
-    query is_const_fn_raw(key: DefId) -> bool {
+    query impl_constness(key: DefId) -> hir::Constness {
         desc { |tcx| "checking if item is const fn: `{}`", tcx.def_path_str(key) }
         separate_provide_extern
     }
@@ -1329,11 +1329,6 @@ rustc_queries! {
         separate_provide_extern
     }
 
-    query impl_constness(def_id: DefId) -> hir::Constness {
-        desc { |tcx| "looking up whether `{}` is a const impl", tcx.def_path_str(def_id) }
-        separate_provide_extern
-    }
-
     query check_item_well_formed(key: LocalDefId) -> () {
         desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key.to_def_id()) }
     }
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 653b4908ab5..37425c91157 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -289,6 +289,11 @@ pub struct ClosureSizeProfileData<'tcx> {
 pub trait DefIdTree: Copy {
     fn parent(self, id: DefId) -> Option<DefId>;
 
+    #[inline]
+    fn local_parent(self, id: LocalDefId) -> Option<LocalDefId> {
+        Some(self.parent(id.to_def_id())?.expect_local())
+    }
+
     fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool {
         if descendant.krate != ancestor.krate {
             return false;
@@ -2256,6 +2261,12 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn is_object_safe(self, key: DefId) -> bool {
         self.object_safety_violations(key).is_empty()
     }
+
+    #[inline]
+    pub fn is_const_fn_raw(self, def_id: DefId) -> bool {
+        matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..))
+            && self.impl_constness(def_id) == hir::Constness::Const
+    }
 }
 
 /// Yields the parent function's `LocalDefId` if `def_id` is an `impl Trait` definition.
diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs
index 943f610cc0d..ca6fabf7f40 100644
--- a/compiler/rustc_middle/src/ty/trait_def.rs
+++ b/compiler/rustc_middle/src/ty/trait_def.rs
@@ -5,7 +5,6 @@ use crate::ty::{Ident, Ty, TyCtxt};
 use hir::def_id::LOCAL_CRATE;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
-use rustc_hir::definitions::DefPathHash;
 use std::iter;
 
 use rustc_data_structures::fx::FxIndexMap;
@@ -13,10 +12,8 @@ use rustc_errors::ErrorGuaranteed;
 use rustc_macros::HashStable;
 
 /// A trait's definition with type information.
-#[derive(HashStable)]
+#[derive(HashStable, Encodable, Decodable)]
 pub struct TraitDef {
-    // We already have the def_path_hash below, no need to hash it twice
-    #[stable_hasher(ignore)]
     pub def_id: DefId,
 
     pub unsafety: hir::Unsafety,
@@ -43,10 +40,6 @@ pub struct TraitDef {
     /// on this trait.
     pub specialization_kind: TraitSpecializationKind,
 
-    /// The ICH of this trait's DefPath, cached here so it doesn't have to be
-    /// recomputed all the time.
-    pub def_path_hash: DefPathHash,
-
     /// List of functions from `#[rustc_must_implement_one_of]` attribute one of which
     /// must be implemented.
     pub must_implement_one_of: Option<Box<[Ident]>>,
@@ -54,7 +47,7 @@ pub struct TraitDef {
 
 /// Whether this trait is treated specially by the standard library
 /// specialization lint.
-#[derive(HashStable, PartialEq, Clone, Copy, TyEncodable, TyDecodable)]
+#[derive(HashStable, PartialEq, Clone, Copy, Encodable, Decodable)]
 pub enum TraitSpecializationKind {
     /// The default. Specializing on this trait is not allowed.
     None,
@@ -92,7 +85,6 @@ impl<'tcx> TraitDef {
         is_marker: bool,
         skip_array_during_method_dispatch: bool,
         specialization_kind: TraitSpecializationKind,
-        def_path_hash: DefPathHash,
         must_implement_one_of: Option<Box<[Ident]>>,
     ) -> TraitDef {
         TraitDef {
@@ -103,7 +95,6 @@ impl<'tcx> TraitDef {
             is_marker,
             skip_array_during_method_dispatch,
             specialization_kind,
-            def_path_hash,
             must_implement_one_of,
         }
     }
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 8aa659fa6ac..7ad87481356 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1859,7 +1859,7 @@ impl CheckAttrVisitor<'_> {
     ) -> bool {
         match target {
             Target::Fn | Target::Method(_)
-                if self.tcx.is_const_fn_raw(self.tcx.hir().local_def_id(hir_id)) =>
+                if self.tcx.is_const_fn_raw(self.tcx.hir().local_def_id(hir_id).to_def_id()) =>
             {
                 true
             }
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 44ef0a09a65..64145bbf189 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -77,15 +77,6 @@ fn impl_defaultness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Defaultness {
     }
 }
 
-fn impl_constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
-    let item = tcx.hir().expect_item(def_id.expect_local());
-    if let hir::ItemKind::Impl(impl_) = &item.kind {
-        impl_.constness
-    } else {
-        bug!("`impl_constness` called on {:?}", item);
-    }
-}
-
 /// Calculates the `Sized` constraint.
 ///
 /// In fact, there are only a few options for the types in the constraint:
@@ -498,7 +489,6 @@ pub fn provide(providers: &mut ty::query::Providers) {
         instance_def_size_estimate,
         issue33140_self_ty,
         impl_defaultness,
-        impl_constness,
         conservative_is_privately_uninhabited: conservative_is_privately_uninhabited_raw,
         ..*providers
     };
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 700ae83e4c9..90b880adcd0 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -1218,8 +1218,6 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
     } else {
         ty::trait_def::TraitSpecializationKind::None
     };
-    let def_path_hash = tcx.def_path_hash(def_id);
-
     let must_implement_one_of = tcx
         .get_attrs(def_id)
         .iter()
@@ -1326,7 +1324,6 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
         is_marker,
         skip_array_during_method_dispatch,
         spec_kind,
-        def_path_hash,
         must_implement_one_of,
     )
 }