Encode VariantIdx so we can decode variants in the right order

(cherry picked from commit ff54c801f0)
This commit is contained in:
Michael Goulet
2023-05-12 05:00:59 +00:00
committed by Josh Stone
parent ec1d458777
commit 8b7deda58d
5 changed files with 63 additions and 27 deletions
+41 -26
View File
@@ -857,7 +857,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
) )
} }
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,
@@ -871,27 +876,30 @@ 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.root ctor,
.tables data.discr,
.children self.root
.get(self, index) .tables
.expect("fields are not encoded for a variant") .children
.decode(self) .get(self, index)
.map(|index| ty::FieldDef { .expect("fields are not encoded for a variant")
did: self.local_def_id(index), .decode(self)
name: self.item_name(index), .map(|index| ty::FieldDef {
vis: self.get_visibility(index), did: self.local_def_id(index),
}) name: self.item_name(index),
.collect(), vis: self.get_visibility(index),
adt_kind, })
parent_did, .collect(),
false, adt_kind,
data.is_non_exhaustive, parent_did,
false,
data.is_non_exhaustive,
),
) )
} }
@@ -907,7 +915,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
.children .children
@@ -918,15 +926,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> {
+2 -1
View File
@@ -1376,9 +1376,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(),
}; };
+2
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;
@@ -423,6 +424,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)>,
@@ -0,0 +1,7 @@
#[derive(Default)]
pub enum Foo {
A(u32),
#[default]
B,
C(u32),
}
@@ -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(_) => {}
_ => {}
}
}