mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
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 @@ fn load_proc_macro(self, id: DefIndex, sess: &Session) -> SyntaxExtension {
|
||||
)
|
||||
}
|
||||
|
||||
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,
|
||||
@@ -871,27 +876,30 @@ 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.root
|
||||
.tables
|
||||
.children
|
||||
.get(self, index)
|
||||
.expect("fields are not encoded for a variant")
|
||||
.decode(self)
|
||||
.map(|index| ty::FieldDef {
|
||||
did: self.local_def_id(index),
|
||||
name: self.item_name(index),
|
||||
vis: self.get_visibility(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.root
|
||||
.tables
|
||||
.children
|
||||
.get(self, index)
|
||||
.expect("fields are not encoded for a variant")
|
||||
.decode(self)
|
||||
.map(|index| ty::FieldDef {
|
||||
did: self.local_def_id(index),
|
||||
name: self.item_name(index),
|
||||
vis: self.get_visibility(index),
|
||||
})
|
||||
.collect(),
|
||||
adt_kind,
|
||||
parent_did,
|
||||
false,
|
||||
data.is_non_exhaustive,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -907,7 +915,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
|
||||
.children
|
||||
@@ -918,15 +926,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> {
|
||||
|
||||
@@ -1376,9 +1376,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(),
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
@@ -423,6 +424,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)>,
|
||||
|
||||
@@ -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