Encode VariantIdx so we can decode variants in the right order
This commit is contained in:
parent
7d59fa3d23
commit
ff54c801f0
5 changed files with 58 additions and 22 deletions
|
@ -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> {
|
||||||
|
|
|
@ -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(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)>,
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#[derive(Default)]
|
||||||
|
pub enum Foo {
|
||||||
|
A(u32),
|
||||||
|
#[default]
|
||||||
|
B,
|
||||||
|
C(u32),
|
||||||
|
}
|
11
tests/ui/enum-discriminant/discr-foreign.rs
Normal file
11
tests/ui/enum-discriminant/discr-foreign.rs
Normal 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(_) => {}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue