Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 8b7deda

Browse files
compiler-errorscuviper
authored andcommitted
Encode VariantIdx so we can decode variants in the right order
(cherry picked from commit ff54c80)
1 parent ec1d458 commit 8b7deda

File tree

5 files changed

+63
-27
lines changed

5 files changed

+63
-27
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
857857
)
858858
}
859859

860-
fn get_variant(self, kind: &DefKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef {
860+
fn get_variant(
861+
self,
862+
kind: DefKind,
863+
index: DefIndex,
864+
parent_did: DefId,
865+
) -> (VariantIdx, ty::VariantDef) {
861866
let adt_kind = match kind {
862867
DefKind::Variant => ty::AdtKind::Enum,
863868
DefKind::Struct => ty::AdtKind::Struct,
@@ -871,27 +876,30 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
871876
if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None };
872877
let ctor = data.ctor.map(|(kind, index)| (kind, self.local_def_id(index)));
873878

874-
ty::VariantDef::new(
875-
self.item_name(index),
876-
variant_did,
877-
ctor,
878-
data.discr,
879-
self.root
880-
.tables
881-
.children
882-
.get(self, index)
883-
.expect("fields are not encoded for a variant")
884-
.decode(self)
885-
.map(|index| ty::FieldDef {
886-
did: self.local_def_id(index),
887-
name: self.item_name(index),
888-
vis: self.get_visibility(index),
889-
})
890-
.collect(),
891-
adt_kind,
892-
parent_did,
893-
false,
894-
data.is_non_exhaustive,
879+
(
880+
data.idx,
881+
ty::VariantDef::new(
882+
self.item_name(index),
883+
variant_did,
884+
ctor,
885+
data.discr,
886+
self.root
887+
.tables
888+
.children
889+
.get(self, index)
890+
.expect("fields are not encoded for a variant")
891+
.decode(self)
892+
.map(|index| ty::FieldDef {
893+
did: self.local_def_id(index),
894+
name: self.item_name(index),
895+
vis: self.get_visibility(index),
896+
})
897+
.collect(),
898+
adt_kind,
899+
parent_did,
900+
false,
901+
data.is_non_exhaustive,
902+
),
895903
)
896904
}
897905

@@ -907,7 +915,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
907915
};
908916
let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode(self);
909917

910-
let variants = if let ty::AdtKind::Enum = adt_kind {
918+
let mut variants: Vec<_> = if let ty::AdtKind::Enum = adt_kind {
911919
self.root
912920
.tables
913921
.children
@@ -918,15 +926,22 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
918926
let kind = self.def_kind(index);
919927
match kind {
920928
DefKind::Ctor(..) => None,
921-
_ => Some(self.get_variant(&kind, index, did)),
929+
_ => Some(self.get_variant(kind, index, did)),
922930
}
923931
})
924932
.collect()
925933
} else {
926-
std::iter::once(self.get_variant(&kind, item_id, did)).collect()
934+
std::iter::once(self.get_variant(kind, item_id, did)).collect()
927935
};
928936

929-
tcx.mk_adt_def(did, adt_kind, variants, repr)
937+
variants.sort_by_key(|(idx, _)| *idx);
938+
939+
tcx.mk_adt_def(
940+
did,
941+
adt_kind,
942+
variants.into_iter().map(|(_, variant)| variant).collect(),
943+
repr,
944+
)
930945
}
931946

932947
fn get_visibility(self, id: DefIndex) -> Visibility<DefId> {

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1376,9 +1376,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
13761376
// Therefore, the loop over variants will encode its fields as the adt's children.
13771377
}
13781378

1379-
for variant in adt_def.variants().iter() {
1379+
for (idx, variant) in adt_def.variants().iter_enumerated() {
13801380
let data = VariantData {
13811381
discr: variant.discr,
1382+
idx,
13821383
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
13831384
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
13841385
};

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use rustc_span::edition::Edition;
3131
use rustc_span::hygiene::{ExpnIndex, MacroKind};
3232
use rustc_span::symbol::{Ident, Symbol};
3333
use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Span};
34+
use rustc_target::abi::VariantIdx;
3435
use rustc_target::spec::{PanicStrategy, TargetTriple};
3536

3637
use std::marker::PhantomData;
@@ -423,6 +424,7 @@ define_tables! {
423424

424425
#[derive(TyEncodable, TyDecodable)]
425426
struct VariantData {
427+
idx: VariantIdx,
426428
discr: ty::VariantDiscr,
427429
/// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
428430
ctor: Option<(CtorKind, DefIndex)>,
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#[derive(Default)]
2+
pub enum Foo {
3+
A(u32),
4+
#[default]
5+
B,
6+
C(u32),
7+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// aux-build:discr-foreign-dep.rs
2+
// build-pass
3+
4+
extern crate discr_foreign_dep;
5+
6+
fn main() {
7+
match Default::default() {
8+
discr_foreign_dep::Foo::A(_) => {}
9+
_ => {}
10+
}
11+
}

0 commit comments

Comments
 (0)