Rollup merge of #133702 - RalfJung:single-variant, r=oli-obk
Variants::Single: do not use invalid VariantIdx for uninhabited enums ~~Stacked on top of https://github.com/rust-lang/rust/pull/133681, only the last commit is new.~~ Currently, `Variants::Single` for an empty enum contains a `VariantIdx` of 0; looking that up in the enum variant list will ICE. That's quite confusing. So let's fix that by adding a new `Variants::Empty` case for types that have 0 variants. try-job: i686-msvc
This commit is contained in:
commit
2a43ce03fb
33 changed files with 186 additions and 165 deletions
|
@ -392,7 +392,7 @@ pub enum UndefinedBehaviorInfo<'tcx> {
|
|||
/// A discriminant of an uninhabited enum variant is written.
|
||||
UninhabitedEnumVariantWritten(VariantIdx),
|
||||
/// An uninhabited enum variant is projected.
|
||||
UninhabitedEnumVariantRead(VariantIdx),
|
||||
UninhabitedEnumVariantRead(Option<VariantIdx>),
|
||||
/// Trying to set discriminant to the niched variant, but the value does not match.
|
||||
InvalidNichedEnumVariantWritten { enum_ty: Ty<'tcx> },
|
||||
/// ABI-incompatible argument types.
|
||||
|
|
|
@ -734,21 +734,22 @@ where
|
|||
let layout = match this.variants {
|
||||
Variants::Single { index }
|
||||
// If all variants but one are uninhabited, the variant layout is the enum layout.
|
||||
if index == variant_index &&
|
||||
// Don't confuse variants of uninhabited enums with the enum itself.
|
||||
// For more details see https://github.com/rust-lang/rust/issues/69763.
|
||||
this.fields != FieldsShape::Primitive =>
|
||||
if index == variant_index =>
|
||||
{
|
||||
this.layout
|
||||
}
|
||||
|
||||
Variants::Single { index } => {
|
||||
Variants::Single { .. } | Variants::Empty => {
|
||||
// Single-variant and no-variant enums *can* have other variants, but those are
|
||||
// uninhabited. Produce a layout that has the right fields for that variant, so that
|
||||
// the rest of the compiler can project fields etc as usual.
|
||||
|
||||
let tcx = cx.tcx();
|
||||
let typing_env = cx.typing_env();
|
||||
|
||||
// Deny calling for_variant more than once for non-Single enums.
|
||||
if let Ok(original_layout) = tcx.layout_of(typing_env.as_query_input(this.ty)) {
|
||||
assert_eq!(original_layout.variants, Variants::Single { index });
|
||||
assert_eq!(original_layout.variants, this.variants);
|
||||
}
|
||||
|
||||
let fields = match this.ty.kind() {
|
||||
|
@ -902,6 +903,7 @@ where
|
|||
),
|
||||
|
||||
ty::Coroutine(def_id, args) => match this.variants {
|
||||
Variants::Empty => unreachable!(),
|
||||
Variants::Single { index } => TyMaybeWithLayout::Ty(
|
||||
args.as_coroutine()
|
||||
.state_tys(def_id, tcx)
|
||||
|
@ -927,6 +929,7 @@ where
|
|||
let field = &def.variant(index).fields[FieldIdx::from_usize(i)];
|
||||
TyMaybeWithLayout::Ty(field.ty(tcx, args))
|
||||
}
|
||||
Variants::Empty => panic!("there is no field in Variants::Empty types"),
|
||||
|
||||
// Discriminant field for enums (where applicable).
|
||||
Variants::Multiple { tag, .. } => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue