make no-variant types a dedicated Variants variant
This commit is contained in:
parent
21de42bf8d
commit
e023590de4
53 changed files with 246 additions and 495 deletions
|
@ -734,23 +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 == Some(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 } => {
|
||||
// `Single` variant enums *can* have other variants, but those are uninhabited.
|
||||
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() {
|
||||
|
@ -760,7 +759,7 @@ where
|
|||
_ => bug!("`ty_and_layout_for_variant` on unexpected type {}", this.ty),
|
||||
};
|
||||
tcx.mk_layout(LayoutData {
|
||||
variants: Variants::Single { index: Some(variant_index) },
|
||||
variants: Variants::Single { index: variant_index },
|
||||
fields: match NonZero::new(fields) {
|
||||
Some(fields) => FieldsShape::Union(fields),
|
||||
None => FieldsShape::Arbitrary { offsets: IndexVec::new(), memory_index: IndexVec::new() },
|
||||
|
@ -777,7 +776,7 @@ where
|
|||
Variants::Multiple { ref variants, .. } => cx.tcx().mk_layout(variants[variant_index].clone()),
|
||||
};
|
||||
|
||||
assert_eq!(*layout.variants(), Variants::Single { index: Some(variant_index) });
|
||||
assert_eq!(*layout.variants(), Variants::Single { index: variant_index });
|
||||
|
||||
TyAndLayout { ty: this.ty, layout }
|
||||
}
|
||||
|
@ -904,10 +903,11 @@ 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)
|
||||
.nth(index.unwrap().as_usize())
|
||||
.nth(index.as_usize())
|
||||
.unwrap()
|
||||
.nth(i)
|
||||
.unwrap(),
|
||||
|
@ -926,10 +926,10 @@ where
|
|||
ty::Adt(def, args) => {
|
||||
match this.variants {
|
||||
Variants::Single { index } => {
|
||||
let field =
|
||||
&def.variant(index.unwrap()).fields[FieldIdx::from_usize(i)];
|
||||
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