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 info for Adt in a single place. #107189

Merged
merged 3 commits into from
Jan 26, 2023
Merged
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
158 changes: 45 additions & 113 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ use rustc_span::symbol::{sym, Symbol};
use rustc_span::{
self, DebuggerVisualizerFile, ExternalSource, FileName, SourceFile, Span, SyntaxContext,
};
use rustc_target::abi::VariantIdx;
use std::borrow::Borrow;
use std::collections::hash_map::Entry;
use std::hash::Hash;
Expand Down Expand Up @@ -1178,8 +1177,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
}
if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind {
let params_in_repr = self.tcx.params_in_repr(def_id);
record!(self.tables.params_in_repr[def_id] <- params_in_repr);
self.encode_info_for_adt(def_id);
}
if should_encode_trait_impl_trait_tys(tcx, def_id)
&& let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
Expand All @@ -1199,46 +1197,53 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}

fn encode_enum_variant_info(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
#[instrument(level = "trace", skip(self))]
fn encode_info_for_adt(&mut self, def_id: DefId) {
let tcx = self.tcx;
let variant = &def.variant(index);
let def_id = variant.def_id;
debug!("EncodeContext::encode_enum_variant_info({:?})", def_id);

let data = VariantData {
discr: variant.discr,
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
};
let adt_def = tcx.adt_def(def_id);
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_array!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
assert!(f.did.is_local());
f.did.index
}));
if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor {
// FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`.
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(ctor_def_id));
let params_in_repr = self.tcx.params_in_repr(def_id);
record!(self.tables.params_in_repr[def_id] <- params_in_repr);

if adt_def.is_enum() {
record_array!(self.tables.children[def_id] <- iter::from_generator(||
for variant in tcx.adt_def(def_id).variants() {
yield variant.def_id.index;
// Encode constructors which take a separate slot in value namespace.
if let Some(ctor_def_id) = variant.ctor_def_id() {
yield ctor_def_id.index;
}
}
));
Comment on lines +1210 to +1218
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting 😄

} else {
// For non-enum, there is only one variant, and its def_id is the adt's.
debug_assert_eq!(adt_def.variants().len(), 1);
debug_assert_eq!(adt_def.non_enum_variant().def_id, def_id);
// Therefore, the loop over variants will encode its fields as the adt's children.
}
}

fn encode_enum_variant_ctor(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
let variant = &def.variant(index);
let Some((ctor_kind, def_id)) = variant.ctor else { return };
debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id);
for variant in adt_def.variants().iter() {
let data = VariantData {
discr: variant.discr,
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
};
record!(self.tables.variant_data[variant.def_id] <- data);

// FIXME(eddyb) encode only the `CtorKind` for constructors.
let data = VariantData {
discr: variant.discr,
ctor: Some((ctor_kind, def_id.index)),
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
};
self.tables.constness.set(variant.def_id.index, hir::Constness::Const);
record_array!(self.tables.children[variant.def_id] <- variant.fields.iter().map(|f| {
assert!(f.did.is_local());
f.did.index
}));

record!(self.tables.variant_data[def_id] <- data);
self.tables.constness.set(def_id.index, hir::Constness::Const);
if ctor_kind == CtorKind::Fn {
record!(self.tables.fn_sig[def_id] <- self.tcx.fn_sig(def_id));
if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor {
self.tables.constness.set(ctor_def_id.index, hir::Constness::Const);
let fn_sig = tcx.fn_sig(ctor_def_id);
record!(self.tables.fn_sig[ctor_def_id] <- fn_sig);
// FIXME only encode signature for ctor_def_id
record!(self.tables.fn_sig[variant.def_id] <- fn_sig);
}
}
}

Expand Down Expand Up @@ -1291,25 +1296,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}

fn encode_struct_ctor(&mut self, adt_def: ty::AdtDef<'tcx>) {
let variant = adt_def.non_enum_variant();
let Some((ctor_kind, def_id)) = variant.ctor else { return };
debug!("EncodeContext::encode_struct_ctor({:?})", def_id);

let data = VariantData {
discr: variant.discr,
ctor: Some((ctor_kind, def_id.index)),
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
};

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);
if ctor_kind == CtorKind::Fn {
record!(self.tables.fn_sig[def_id] <- self.tcx.fn_sig(def_id));
}
}

fn encode_explicit_item_bounds(&mut self, def_id: DefId) {
debug!("EncodeContext::encode_explicit_item_bounds({:?})", def_id);
let bounds = self.tcx.explicit_item_bounds(def_id);
Expand Down Expand Up @@ -1518,33 +1504,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.tables.is_type_alias_impl_trait.set(def_id.index, ());
}
}
hir::ItemKind::Enum(..) => {
let adt_def = self.tcx.adt_def(def_id);
record!(self.tables.repr_options[def_id] <- adt_def.repr());
}
hir::ItemKind::Struct(..) => {
let adt_def = self.tcx.adt_def(def_id);
record!(self.tables.repr_options[def_id] <- adt_def.repr());
self.tables.constness.set(def_id.index, hir::Constness::Const);

let variant = adt_def.non_enum_variant();
record!(self.tables.variant_data[def_id] <- VariantData {
discr: variant.discr,
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
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();
record!(self.tables.variant_data[def_id] <- VariantData {
discr: variant.discr,
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
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);
self.tables.constness.set(def_id.index, *constness);
Expand Down Expand Up @@ -1583,31 +1542,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
hir::ItemKind::Static(..)
| hir::ItemKind::Const(..)
| hir::ItemKind::Enum(..)
| hir::ItemKind::Struct(..)
| hir::ItemKind::Union(..)
| hir::ItemKind::ForeignMod { .. }
| hir::ItemKind::GlobalAsm(..)
| hir::ItemKind::TyAlias(..) => {}
};
// FIXME(eddyb) there should be a nicer way to do this.
match item.kind {
hir::ItemKind::Enum(..) => {
record_array!(self.tables.children[def_id] <- iter::from_generator(||
for variant in tcx.adt_def(def_id).variants() {
yield variant.def_id.index;
// Encode constructors which take a separate slot in value namespace.
if let Some(ctor_def_id) = variant.ctor_def_id() {
yield ctor_def_id.index;
}
}
))
}
hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
record_array!(self.tables.children[def_id] <-
self.tcx.adt_def(def_id).non_enum_variant().fields.iter().map(|f| {
assert!(f.did.is_local());
f.did.index
})
)
}
hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) => {
let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
record_array!(self.tables.children[def_id] <-
Expand Down Expand Up @@ -1635,17 +1578,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// 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.owner_id.to_def_id());
for (i, _) in def.variants().iter_enumerated() {
self.encode_enum_variant_info(def, i);
self.encode_enum_variant_ctor(def, i);
}
}
hir::ItemKind::Struct(..) => {
let def = self.tcx.adt_def(item.owner_id.to_def_id());
self.encode_struct_ctor(def);
}
hir::ItemKind::Impl { .. } => {
for &trait_item_def_id in
self.tcx.associated_item_def_ids(item.owner_id.to_def_id()).iter()
Expand Down