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`.
This commit is contained in:
bors 2022-04-01 21:16:41 +00:00
commit eb82facb16
11 changed files with 131 additions and 212 deletions

View File

@ -1,7 +1,8 @@
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::ty::query::Providers; use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::{DefIdTree, TyCtxt};
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
use rustc_target::spec::abi::Abi; 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 { 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.local_parent(def_id).unwrap();
let parent_id = tcx.hir().get_parent_node(hir_id); tcx.def_kind(parent_id) == DefKind::Impl
matches!( && tcx.impl_constness(parent_id) == hir::Constness::Const
tcx.hir().get(parent_id),
hir::Node::Item(hir::Item {
kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
..
})
)
} }
/// Checks whether the function has a `const` modifier or, in case it is an intrinsic, whether /// 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. /// 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 def_id = def_id.expect_local();
let node = tcx.hir().get_by_def_id(def_id); let node = tcx.hir().get_by_def_id(def_id);
if let hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) = match node {
node hir::Node::Ctor(_) => hir::Constness::Const,
{ hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness,
// Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
// foreign items cannot be evaluated at compile-time. // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); // foreign items cannot be evaluated at compile-time.
if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = tcx.hir().get_foreign_abi(hir_id) { let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
tcx.lookup_const_stability(def_id).is_some() let is_const = if let Abi::RustIntrinsic | Abi::PlatformIntrinsic =
} else { tcx.hir().get_foreign_abi(hir_id)
false {
} tcx.lookup_const_stability(def_id).is_some()
} else if let Some(fn_kind) = node.fn_kind() { } else {
if fn_kind.constness() == hir::Constness::Const { false
return true; };
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 the function itself is not annotated with `const`, it may still be a `const fn`
// if it resides in a const trait impl. // if it resides in a const trait impl.
is_parent_const_impl_raw(tcx, def_id) let is_const = is_parent_const_impl_raw(tcx, def_id);
} else { if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
matches!(node, hir::Node::Ctor(_)) } 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) { 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 };
} }

View File

@ -14,7 +14,6 @@ use rustc_data_structures::sync::{Lock, LockGuard, Lrc, OnceCell};
use rustc_data_structures::unhash::UnhashMap; use rustc_data_structures::unhash::UnhashMap;
use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, ProcMacroDerive}; 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::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash}; 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 { fn get_variant(self, kind: &EntryKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef {
let data = match kind { 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) data.decode(self)
} }
_ => bug!(), _ => bug!(),
@ -988,12 +956,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
let kind = self.kind(item_id); let kind = self.kind(item_id);
let did = self.local_def_id(item_id); let did = self.local_def_id(item_id);
let (adt_kind, repr) = match kind { let adt_kind = match kind {
EntryKind::Enum(repr) => (ty::AdtKind::Enum, repr), EntryKind::Enum => ty::AdtKind::Enum,
EntryKind::Struct(_, repr) => (ty::AdtKind::Struct, repr), EntryKind::Struct(_) => ty::AdtKind::Struct,
EntryKind::Union(_, repr) => (ty::AdtKind::Union, repr), EntryKind::Union(_) => ty::AdtKind::Union,
_ => bug!("get_adt_def called on a non-ADT {:?}", did), _ => 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 { let variants = if let ty::AdtKind::Enum = adt_kind {
self.root self.root
@ -1171,7 +1140,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
callback(exp); 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)), _ => 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 { fn module_expansion(self, id: DefIndex, sess: &Session) -> ExpnId {
match self.kind(id) { match self.kind(id) {
EntryKind::Mod(_) | EntryKind::Enum(_) | EntryKind::Trait(_) => { EntryKind::Mod(_) | EntryKind::Enum | EntryKind::Trait => {
self.get_expn_that_defined(id, sess) self.get_expn_that_defined(id, sess)
} }
_ => panic!("Expected module, found {:?}", self.local_def_id(id)), _ => 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)> { fn get_ctor_def_id_and_kind(self, node_id: DefIndex) -> Option<(DefId, CtorKind)> {
match self.kind(node_id) { match self.kind(node_id) {
EntryKind::Struct(data, _) | EntryKind::Variant(data) => { EntryKind::Struct(data) | EntryKind::Variant(data) => {
let vdata = data.decode(self); let vdata = data.decode(self);
vdata.ctor.map(|index| (self.local_def_id(index), vdata.ctor_kind)) vdata.ctor.map(|index| (self.local_def_id(index), vdata.ctor_kind))
} }
@ -1395,7 +1364,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
_ => return None, _ => return None,
} }
def_key.parent.and_then(|parent_index| match self.kind(parent_index) { 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, _ => 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 { fn is_foreign_item(self, id: DefIndex) -> bool {
match self.kind(id) { match self.kind(id) {
EntryKind::ForeignStatic | EntryKind::ForeignFn(_) => true, EntryKind::ForeignStatic | EntryKind::ForeignFn => true,
_ => false, _ => false,
} }
} }

View File

@ -153,8 +153,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
asyncness => { table } asyncness => { table }
fn_arg_names => { table } fn_arg_names => { table }
generator_kind => { 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_def => { cdata.get_adt_def(def_id.index, tcx) }
adt_destructor => { adt_destructor => {
let _ = cdata; 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_def_ids => { cdata.get_associated_item_def_ids(tcx, def_id.index) }
associated_item => { cdata.get_associated_item(def_id.index) } associated_item => { cdata.get_associated_item(def_id.index) }
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, 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) } 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)) } 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) } trait_of_item => { cdata.get_trait_of_item(def_id.index) }

View File

@ -1048,6 +1048,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}; };
record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data))); 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| { record!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
assert!(f.did.is_local()); assert!(f.did.is_local());
f.did.index 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.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
record!(self.tables.impl_constness[def_id] <- hir::Constness::Const);
self.encode_item_type(def_id); self.encode_item_type(def_id);
if variant.ctor_kind == CtorKind::Fn { if variant.ctor_kind == CtorKind::Fn {
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); 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(), 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); self.encode_item_type(def_id);
if variant.ctor_kind == CtorKind::Fn { if variant.ctor_kind == CtorKind::Fn {
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); 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); record!(self.tables.rendered_const[def_id] <- rendered);
} }
ty::AssocKind::Fn => { ty::AssocKind::Fn => {
let fn_data = if let hir::TraitItemKind::Fn(m_sig, m) = &ast_item.kind { let hir::TraitItemKind::Fn(m_sig, m) = &ast_item.kind else { bug!() };
match *m { match *m {
hir::TraitFn::Required(ref names) => { hir::TraitFn::Required(ref names) => {
record!(self.tables.fn_arg_names[def_id] <- *names) record!(self.tables.fn_arg_names[def_id] <- *names)
} }
hir::TraitFn::Provided(body) => { hir::TraitFn::Provided(body) => {
record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(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!()
}; };
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 { record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData {
fn_data,
container, container,
has_self: trait_item.fn_has_self_parameter, has_self: trait_item.fn_has_self_parameter,
}))); })));
@ -1264,22 +1264,17 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
} }
} }
ty::AssocKind::Fn => { ty::AssocKind::Fn => {
let fn_data = if let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind { let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() };
record!(self.tables.asyncness[def_id] <- sig.header.asyncness); record!(self.tables.asyncness[def_id] <- sig.header.asyncness);
record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body)); 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
// 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) {
constness: if self.tcx.is_const_fn_raw(def_id) { hir::Constness::Const
hir::Constness::Const
} else {
hir::Constness::NotConst
},
}
} else { } else {
bug!() hir::Constness::NotConst
}; };
record!(self.tables.impl_constness[def_id] <- constness);
record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData { record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData {
fn_data,
container, container,
has_self: impl_item.fn_has_self_parameter, has_self: impl_item.fn_has_self_parameter,
}))); })));
@ -1401,9 +1396,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
hir::ItemKind::Fn(ref sig, .., body) => { hir::ItemKind::Fn(ref sig, .., body) => {
record!(self.tables.asyncness[def_id] <- sig.header.asyncness); record!(self.tables.asyncness[def_id] <- sig.header.asyncness);
record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body)); record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
let data = FnData { constness: sig.header.constness }; record!(self.tables.impl_constness[def_id] <- sig.header.constness);
EntryKind::Fn
EntryKind::Fn(self.lazy(data))
} }
hir::ItemKind::Macro(ref macro_def, _) => { hir::ItemKind::Macro(ref macro_def, _) => {
EntryKind::MacroDef(self.lazy(&*macro_def.body), macro_def.macro_rules) 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); self.encode_explicit_item_bounds(def_id);
EntryKind::OpaqueTy 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, _) => { hir::ItemKind::Struct(ref struct_def, _) => {
let adt_def = self.tcx.adt_def(def_id); 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 // Encode def_ids for each field and method
// for methods, write all the stuff get_trait_method // for methods, write all the stuff get_trait_method
@ -1430,29 +1429,25 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
.ctor_hir_id() .ctor_hir_id()
.map(|ctor_hir_id| self.tcx.hir().local_def_id(ctor_hir_id).local_def_index); .map(|ctor_hir_id| self.tcx.hir().local_def_id(ctor_hir_id).local_def_index);
EntryKind::Struct( let variant = adt_def.non_enum_variant();
self.lazy(VariantData { EntryKind::Struct(self.lazy(VariantData {
ctor_kind: variant.ctor_kind, ctor_kind: variant.ctor_kind,
discr: variant.discr, discr: variant.discr,
ctor, ctor,
is_non_exhaustive: variant.is_field_list_non_exhaustive(), is_non_exhaustive: variant.is_field_list_non_exhaustive(),
}), }))
adt_def.repr(),
)
} }
hir::ItemKind::Union(..) => { hir::ItemKind::Union(..) => {
let adt_def = self.tcx.adt_def(def_id); 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( let variant = adt_def.non_enum_variant();
self.lazy(VariantData { EntryKind::Union(self.lazy(VariantData {
ctor_kind: variant.ctor_kind, ctor_kind: variant.ctor_kind,
discr: variant.discr, discr: variant.discr,
ctor: None, ctor: None,
is_non_exhaustive: variant.is_field_list_non_exhaustive(), is_non_exhaustive: variant.is_field_list_non_exhaustive(),
}), }))
adt_def.repr(),
)
} }
hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => { hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
record!(self.tables.impl_defaultness[def_id] <- defaultness); record!(self.tables.impl_defaultness[def_id] <- defaultness);
@ -1483,19 +1478,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
} }
hir::ItemKind::Trait(..) => { hir::ItemKind::Trait(..) => {
let trait_def = self.tcx.trait_def(def_id); let trait_def = self.tcx.trait_def(def_id);
let data = TraitData { record!(self.tables.trait_def[def_id] <- trait_def);
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(),
};
EntryKind::Trait(self.lazy(data)) 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::TraitAlias(..) => EntryKind::TraitAlias,
hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => { hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {
bug!("cannot encode info for item {:?}", item) bug!("cannot encode info for item {:?}", item)
} }
@ -1896,14 +1888,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
hir::ForeignItemKind::Fn(_, ref names, _) => { hir::ForeignItemKind::Fn(_, ref names, _) => {
record!(self.tables.asyncness[def_id] <- hir::IsAsync::NotAsync); record!(self.tables.asyncness[def_id] <- hir::IsAsync::NotAsync);
record!(self.tables.fn_arg_names[def_id] <- *names); record!(self.tables.fn_arg_names[def_id] <- *names);
let data = FnData { let constness = if self.tcx.is_const_fn_raw(def_id) {
constness: if self.tcx.is_const_fn_raw(def_id) { hir::Constness::Const
hir::Constness::Const } else {
} else { hir::Constness::NotConst
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(..) => { hir::ForeignItemKind::Static(..) => {
record!(self.tables.kind[def_id] <- EntryKind::ForeignStatic); record!(self.tables.kind[def_id] <- EntryKind::ForeignStatic);

View File

@ -320,11 +320,13 @@ define_tables! {
asyncness: Table<DefIndex, Lazy!(hir::IsAsync)>, asyncness: Table<DefIndex, Lazy!(hir::IsAsync)>,
fn_arg_names: Table<DefIndex, Lazy!([Ident])>, fn_arg_names: Table<DefIndex, Lazy!([Ident])>,
generator_kind: Table<DefIndex, Lazy!(hir::GeneratorKind)>, generator_kind: Table<DefIndex, Lazy!(hir::GeneratorKind)>,
trait_def: Table<DefIndex, Lazy!(ty::TraitDef)>,
trait_item_def_id: Table<DefIndex, Lazy<DefId>>, trait_item_def_id: Table<DefIndex, Lazy<DefId>>,
inherent_impls: Table<DefIndex, Lazy<[DefIndex]>>, inherent_impls: Table<DefIndex, Lazy<[DefIndex]>>,
expn_that_defined: Table<DefIndex, Lazy<ExpnId>>, expn_that_defined: Table<DefIndex, Lazy<ExpnId>>,
unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>, 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 // `def_keys` and `def_path_hashes` represent a lazy version of a
// `DefPathTable`. This allows us to avoid deserializing an entire // `DefPathTable`. This allows us to avoid deserializing an entire
// `DefPathTable` up front, since we may only ever use a few // `DefPathTable` up front, since we may only ever use a few
@ -347,19 +349,19 @@ enum EntryKind {
TypeParam, TypeParam,
ConstParam, ConstParam,
OpaqueTy, OpaqueTy,
Enum(ReprOptions), Enum,
Field, Field,
Variant(Lazy<VariantData>), Variant(Lazy<VariantData>),
Struct(Lazy<VariantData>, ReprOptions), Struct(Lazy<VariantData>),
Union(Lazy<VariantData>, ReprOptions), Union(Lazy<VariantData>),
Fn(Lazy<FnData>), Fn,
ForeignFn(Lazy<FnData>), ForeignFn,
Mod(Lazy<[ModChild]>), Mod(Lazy<[ModChild]>),
MacroDef(Lazy<ast::MacArgs>, /*macro_rules*/ bool), MacroDef(Lazy<ast::MacArgs>, /*macro_rules*/ bool),
ProcMacro(MacroKind), ProcMacro(MacroKind),
Closure, Closure,
Generator, Generator,
Trait(Lazy<TraitData>), Trait,
Impl, Impl,
AssocFn(Lazy<AssocFnData>), AssocFn(Lazy<AssocFnData>),
AssocType(AssocContainer), AssocType(AssocContainer),
@ -367,11 +369,6 @@ enum EntryKind {
TraitAlias, TraitAlias,
} }
#[derive(MetadataEncodable, MetadataDecodable)]
struct FnData {
constness: hir::Constness,
}
#[derive(TyEncodable, TyDecodable)] #[derive(TyEncodable, TyDecodable)]
struct VariantData { struct VariantData {
ctor_kind: CtorKind, ctor_kind: CtorKind,
@ -381,17 +378,6 @@ struct VariantData {
is_non_exhaustive: bool, 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 /// Describes whether the container of an associated item
/// is a trait or an impl and whether, in a trait, it has /// is a trait or an impl and whether, in a trait, it has
/// a default, or an in impl, whether it's marked "default". /// a default, or an in impl, whether it's marked "default".
@ -429,7 +415,6 @@ impl AssocContainer {
#[derive(MetadataEncodable, MetadataDecodable)] #[derive(MetadataEncodable, MetadataDecodable)]
struct AssocFnData { struct AssocFnData {
fn_data: FnData,
container: AssocContainer, container: AssocContainer,
has_self: bool, has_self: bool,
} }

View File

@ -559,7 +559,7 @@ rustc_queries! {
/// ///
/// **Do not call this function manually.** It is only meant to cache the base data for the /// **Do not call this function manually.** It is only meant to cache the base data for the
/// `is_const_fn` function. /// `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) } desc { |tcx| "checking if item is const fn: `{}`", tcx.def_path_str(key) }
separate_provide_extern separate_provide_extern
} }
@ -1329,11 +1329,6 @@ rustc_queries! {
separate_provide_extern 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) -> () { query check_item_well_formed(key: LocalDefId) -> () {
desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key.to_def_id()) } desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key.to_def_id()) }
} }

View File

@ -289,6 +289,11 @@ pub struct ClosureSizeProfileData<'tcx> {
pub trait DefIdTree: Copy { pub trait DefIdTree: Copy {
fn parent(self, id: DefId) -> Option<DefId>; 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 { fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool {
if descendant.krate != ancestor.krate { if descendant.krate != ancestor.krate {
return false; return false;
@ -2256,6 +2261,12 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn is_object_safe(self, key: DefId) -> bool { pub fn is_object_safe(self, key: DefId) -> bool {
self.object_safety_violations(key).is_empty() 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. /// Yields the parent function's `LocalDefId` if `def_id` is an `impl Trait` definition.

View File

@ -5,7 +5,6 @@ use crate::ty::{Ident, Ty, TyCtxt};
use hir::def_id::LOCAL_CRATE; use hir::def_id::LOCAL_CRATE;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::definitions::DefPathHash;
use std::iter; use std::iter;
use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::FxIndexMap;
@ -13,10 +12,8 @@ use rustc_errors::ErrorGuaranteed;
use rustc_macros::HashStable; use rustc_macros::HashStable;
/// A trait's definition with type information. /// A trait's definition with type information.
#[derive(HashStable)] #[derive(HashStable, Encodable, Decodable)]
pub struct TraitDef { 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 def_id: DefId,
pub unsafety: hir::Unsafety, pub unsafety: hir::Unsafety,
@ -43,10 +40,6 @@ pub struct TraitDef {
/// on this trait. /// on this trait.
pub specialization_kind: TraitSpecializationKind, 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 /// List of functions from `#[rustc_must_implement_one_of]` attribute one of which
/// must be implemented. /// must be implemented.
pub must_implement_one_of: Option<Box<[Ident]>>, 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 /// Whether this trait is treated specially by the standard library
/// specialization lint. /// specialization lint.
#[derive(HashStable, PartialEq, Clone, Copy, TyEncodable, TyDecodable)] #[derive(HashStable, PartialEq, Clone, Copy, Encodable, Decodable)]
pub enum TraitSpecializationKind { pub enum TraitSpecializationKind {
/// The default. Specializing on this trait is not allowed. /// The default. Specializing on this trait is not allowed.
None, None,
@ -92,7 +85,6 @@ impl<'tcx> TraitDef {
is_marker: bool, is_marker: bool,
skip_array_during_method_dispatch: bool, skip_array_during_method_dispatch: bool,
specialization_kind: TraitSpecializationKind, specialization_kind: TraitSpecializationKind,
def_path_hash: DefPathHash,
must_implement_one_of: Option<Box<[Ident]>>, must_implement_one_of: Option<Box<[Ident]>>,
) -> TraitDef { ) -> TraitDef {
TraitDef { TraitDef {
@ -103,7 +95,6 @@ impl<'tcx> TraitDef {
is_marker, is_marker,
skip_array_during_method_dispatch, skip_array_during_method_dispatch,
specialization_kind, specialization_kind,
def_path_hash,
must_implement_one_of, must_implement_one_of,
} }
} }

View File

@ -1859,7 +1859,7 @@ impl CheckAttrVisitor<'_> {
) -> bool { ) -> bool {
match target { match target {
Target::Fn | Target::Method(_) 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 true
} }

View File

@ -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. /// Calculates the `Sized` constraint.
/// ///
/// In fact, there are only a few options for the types in the 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, instance_def_size_estimate,
issue33140_self_ty, issue33140_self_ty,
impl_defaultness, impl_defaultness,
impl_constness,
conservative_is_privately_uninhabited: conservative_is_privately_uninhabited_raw, conservative_is_privately_uninhabited: conservative_is_privately_uninhabited_raw,
..*providers ..*providers
}; };

View File

@ -1218,8 +1218,6 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
} else { } else {
ty::trait_def::TraitSpecializationKind::None ty::trait_def::TraitSpecializationKind::None
}; };
let def_path_hash = tcx.def_path_hash(def_id);
let must_implement_one_of = tcx let must_implement_one_of = tcx
.get_attrs(def_id) .get_attrs(def_id)
.iter() .iter()
@ -1326,7 +1324,6 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
is_marker, is_marker,
skip_array_during_method_dispatch, skip_array_during_method_dispatch,
spec_kind, spec_kind,
def_path_hash,
must_implement_one_of, must_implement_one_of,
) )
} }