From eebf676bf8f76fcdfa610e7e46ab6c135a9cd2d0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 14 Nov 2021 13:28:47 -0500 Subject: [PATCH 1/2] fix getting the discriminant of a zero-variant enum --- compiler/rustc_middle/src/ty/sty.rs | 4 +++- src/test/ui/consts/const_discriminant.rs | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index e57075ed33811..59601e1484956 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2067,7 +2067,9 @@ impl<'tcx> TyS<'tcx> { ) -> Option> { match self.kind() { TyKind::Adt(adt, _) if adt.variants.is_empty() => { - bug!("discriminant_for_variant called on zero variant enum"); + // This can actually happen during CTFE, see + // https://github.com/rust-lang/rust/issues/89765. + None } TyKind::Adt(adt, _) if adt.is_enum() => { Some(adt.discriminant_for_variant(tcx, variant_index)) diff --git a/src/test/ui/consts/const_discriminant.rs b/src/test/ui/consts/const_discriminant.rs index a47f6af02965b..a9c0217ae2421 100644 --- a/src/test/ui/consts/const_discriminant.rs +++ b/src/test/ui/consts/const_discriminant.rs @@ -25,6 +25,12 @@ enum SingleVariant { const TEST_V: Discriminant = discriminant(&SingleVariant::V); +pub const TEST_VOID: () = { + // This is UB, but CTFE does not check validity so it does not detect this. + unsafe { std::mem::discriminant(&*(&() as *const () as *const Void)); }; +}; + + fn main() { assert_eq!(TEST_A, TEST_A_OTHER); assert_eq!(TEST_A, discriminant(black_box(&Test::A(17)))); From 9ec88626eac5e3e7c5fd719135545f1ac31fab8b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 14 Nov 2021 19:03:32 -0500 Subject: [PATCH 2/2] expand comment --- src/test/ui/consts/const_discriminant.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/consts/const_discriminant.rs b/src/test/ui/consts/const_discriminant.rs index a9c0217ae2421..f623c5101f4cd 100644 --- a/src/test/ui/consts/const_discriminant.rs +++ b/src/test/ui/consts/const_discriminant.rs @@ -27,6 +27,7 @@ const TEST_V: Discriminant = discriminant(&SingleVariant::V); pub const TEST_VOID: () = { // This is UB, but CTFE does not check validity so it does not detect this. + // This is a regression test for https://github.com/rust-lang/rust/issues/89765. unsafe { std::mem::discriminant(&*(&() as *const () as *const Void)); }; };