Encode VariantIdx so we can decode variants in the right order
(cherry picked from commit ff54c801f0)
This commit is contained in:
committed by
Josh Stone
parent
ec1d458777
commit
8b7deda58d
@@ -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> {
|
||||||
|
|||||||
@@ -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(),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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(_) => {}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user