Encode VariantIdx so we can decode variants in the right order

This commit is contained in:
Michael Goulet 2023-05-12 05:00:59 +00:00
parent 7d59fa3d23
commit ff54c801f0
5 changed files with 58 additions and 22 deletions

View file

@ -856,7 +856,12 @@ fn get_explicit_item_bounds(
ty::EarlyBinder(&*output)
}
fn get_variant(self, kind: &DefKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef {
fn get_variant(
self,
kind: DefKind,
index: DefIndex,
parent_did: DefId,
) -> (VariantIdx, ty::VariantDef) {
let adt_kind = match kind {
DefKind::Variant => ty::AdtKind::Enum,
DefKind::Struct => ty::AdtKind::Struct,
@ -870,22 +875,25 @@ fn get_variant(self, kind: &DefKind, index: DefIndex, parent_did: DefId) -> ty::
if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None };
let ctor = data.ctor.map(|(kind, index)| (kind, self.local_def_id(index)));
ty::VariantDef::new(
self.item_name(index),
variant_did,
ctor,
data.discr,
self.get_associated_item_or_field_def_ids(index)
.map(|did| ty::FieldDef {
did,
name: self.item_name(did.index),
vis: self.get_visibility(did.index),
})
.collect(),
adt_kind,
parent_did,
false,
data.is_non_exhaustive,
(
data.idx,
ty::VariantDef::new(
self.item_name(index),
variant_did,
ctor,
data.discr,
self.get_associated_item_or_field_def_ids(index)
.map(|did| ty::FieldDef {
did,
name: self.item_name(did.index),
vis: self.get_visibility(did.index),
})
.collect(),
adt_kind,
parent_did,
false,
data.is_non_exhaustive,
),
)
}
@ -901,7 +909,7 @@ fn get_adt_def(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::AdtDef<'tcx> {
};
let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode(self);
let variants = if let ty::AdtKind::Enum = adt_kind {
let mut variants: Vec<_> = if let ty::AdtKind::Enum = adt_kind {
self.root
.tables
.module_children_non_reexports
@ -912,15 +920,22 @@ fn get_adt_def(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::AdtDef<'tcx> {
let kind = self.def_kind(index);
match kind {
DefKind::Ctor(..) => None,
_ => Some(self.get_variant(&kind, index, did)),
_ => Some(self.get_variant(kind, index, did)),
}
})
.collect()
} else {
std::iter::once(self.get_variant(&kind, item_id, did)).collect()
std::iter::once(self.get_variant(kind, item_id, did)).collect()
};
tcx.mk_adt_def(did, adt_kind, variants, repr)
variants.sort_by_key(|(idx, _)| *idx);
tcx.mk_adt_def(
did,
adt_kind,
variants.into_iter().map(|(_, variant)| variant).collect(),
repr,
)
}
fn get_visibility(self, id: DefIndex) -> Visibility<DefId> {

View file

@ -1375,9 +1375,10 @@ fn encode_info_for_adt(&mut self, local_def_id: LocalDefId) {
// Therefore, the loop over variants will encode its fields as the adt's children.
}
for variant in adt_def.variants().iter() {
for (idx, variant) in adt_def.variants().iter_enumerated() {
let data = VariantData {
discr: variant.discr,
idx,
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
};

View file

@ -31,6 +31,7 @@
use rustc_span::hygiene::{ExpnIndex, MacroKind};
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Span};
use rustc_target::abi::VariantIdx;
use rustc_target::spec::{PanicStrategy, TargetTriple};
use std::marker::PhantomData;
@ -430,6 +431,7 @@ fn encode(&self, buf: &mut FileEncoder) -> LazyTables {
#[derive(TyEncodable, TyDecodable)]
struct VariantData {
idx: VariantIdx,
discr: ty::VariantDiscr,
/// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
ctor: Option<(CtorKind, DefIndex)>,

View file

@ -0,0 +1,7 @@
#[derive(Default)]
pub enum Foo {
A(u32),
#[default]
B,
C(u32),
}

View file

@ -0,0 +1,11 @@
// aux-build:discr-foreign-dep.rs
// build-pass
extern crate discr_foreign_dep;
fn main() {
match Default::default() {
discr_foreign_dep::Foo::A(_) => {}
_ => {}
}
}