1
Fork 0

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 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
ty::EarlyBinder(&*output) 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 { let adt_kind = match kind {
DefKind::Variant => ty::AdtKind::Enum, DefKind::Variant => ty::AdtKind::Enum,
DefKind::Struct => ty::AdtKind::Struct, DefKind::Struct => ty::AdtKind::Struct,
@ -870,22 +875,25 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None }; 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))); let ctor = data.ctor.map(|(kind, index)| (kind, self.local_def_id(index)));
ty::VariantDef::new( (
self.item_name(index), data.idx,
variant_did, ty::VariantDef::new(
ctor, self.item_name(index),
data.discr, variant_did,
self.get_associated_item_or_field_def_ids(index) ctor,
.map(|did| ty::FieldDef { data.discr,
did, self.get_associated_item_or_field_def_ids(index)
name: self.item_name(did.index), .map(|did| ty::FieldDef {
vis: self.get_visibility(did.index), did,
}) name: self.item_name(did.index),
.collect(), vis: self.get_visibility(did.index),
adt_kind, })
parent_did, .collect(),
false, adt_kind,
data.is_non_exhaustive, parent_did,
false,
data.is_non_exhaustive,
),
) )
} }
@ -901,7 +909,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}; };
let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode(self); 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 self.root
.tables .tables
.module_children_non_reexports .module_children_non_reexports
@ -912,15 +920,22 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
let kind = self.def_kind(index); let kind = self.def_kind(index);
match kind { match kind {
DefKind::Ctor(..) => None, DefKind::Ctor(..) => None,
_ => Some(self.get_variant(&kind, index, did)), _ => Some(self.get_variant(kind, index, did)),
} }
}) })
.collect() .collect()
} else { } 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> { fn get_visibility(self, id: DefIndex) -> Visibility<DefId> {

View file

@ -1375,9 +1375,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Therefore, the loop over variants will encode its fields as the adt's children. // 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 { let data = VariantData {
discr: variant.discr, discr: variant.discr,
idx,
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)), ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
is_non_exhaustive: variant.is_field_list_non_exhaustive(), is_non_exhaustive: variant.is_field_list_non_exhaustive(),
}; };

View file

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