diff options
| author | 许杰友 Jieyou Xu (Joe) <39484203+jieyouxu@users.noreply.github.com> | 2024-12-19 16:48:07 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-19 16:48:07 +0800 |
| commit | 2a43ce03fb60736880477e985d7bd13e3ff65b3d (patch) | |
| tree | 4e4bb271114119c1cb923700f08b9c956d37e3da /compiler/rustc_middle | |
| parent | bab18a542d95b5c76620d0a0d383d7ab683cc1b7 (diff) | |
| parent | 397ae3cdf641b8d303ab9d004013f956c2991727 (diff) | |
| download | rust-2a43ce03fb60736880477e985d7bd13e3ff65b3d.tar.gz rust-2a43ce03fb60736880477e985d7bd13e3ff65b3d.zip | |
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
Diffstat (limited to 'compiler/rustc_middle')
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/error.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/layout.rs | 15 |
2 files changed, 10 insertions, 7 deletions
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index fbada6ec405..37328470aa7 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -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. diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index ad1680ed3a2..367b0c07f9b 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -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, .. } => { |
