Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encode even more metadata through tables instead of EntryKind #94883

Merged
merged 4 commits into from
Apr 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 35 additions & 31 deletions compiler/rustc_const_eval/src/const_eval/fn_queries.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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
}
}
}
}

Expand All @@ -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 };
}
66 changes: 11 additions & 55 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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!(),
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)),
}
}
Expand All @@ -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)),
Expand Down Expand Up @@ -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))
}
Expand Down Expand Up @@ -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,
})
}
Expand Down Expand Up @@ -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,
}
}
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) }
Expand Down
Loading