Change:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
searched toolchains through Regression in which is my rollup :sweat_smile: : ... Maybe ? cc
Reduced: `
Thanks for report and test case. In , I removed the special case for enums without variants, expecting that now that we handle failure gracefully it would be caught there. Alas, in this specific case, the succeeds while returning a non-existing variant index.

Discussion:
// We go to `usize` as we cannot allocate anything bigger anyway. let (field_count, variant, down) = match val.ty().kind() { ty::Array(_, len) => (usize::try_from(len.eval_usize(tcx, param_env)).unwrap(), None, op), <ins> // Checks if we have any variants, to avoid downcasting to a non-existing variant (when // there are no variants `read_discriminant` successfully returns a non-existing variant // index). ty::Adt(def, _) if def.variants.is_empty() => throw_ub!(Unreachable), </ins> ty::Adt(def, _) => { let variant = ecx.read_discriminant(&op)?.1; let down = ecx.operand_downcast(&op, variant)?;

+ // MIR for `main` after ConstProp fn main() -> () { <del> let mut _0: ();                      // return place in scope 0 at $DIR/invalid_constant.rs:15:11: 15:11 let _1: std::option::Option<()>;     // in scope 0 at $DIR/invalid_constant.rs:16:5: 16:12 let mut _2: std::option::Option<std::option::Option<()>>; // in scope 0 at $DIR/invalid_constant.rs:16:7: 16:11 let _3: main::Union;                 // in scope 0 at $DIR/invalid_constant.rs:22:9: 22:22 </del> <ins> let mut _0: ();                      // return place in scope 0 at $DIR/invalid_constant.rs:13:11: 13:11 let _1: main::InvalidChar;           // in scope 0 at $DIR/invalid_constant.rs:19:9: 19:22 let mut _3: main::InvalidTag;        // in scope 0 at $DIR/invalid_constant.rs:26:25: 26:46 let mut _5: main::NoVariants;        // in scope 0 at $DIR/invalid_constant.rs:33:35: 33:56 </ins> scope 1 { <del> debug _invalid_char => _3;       // in scope 1 at $DIR/invalid_constant.rs:22:9: 22:22 } scope 2 (inlined f) {                // at $DIR/invalid_constant.rs:16:5: 16:12 debug x => _2;                   // in scope 2 at $DIR/invalid_constant.rs:16:5: 16:12 let mut _4: isize;               // in scope 2 at $DIR/invalid_constant.rs:16:5: 16:12 let _5: std::option::Option<()>; // in scope 2 at $DIR/invalid_constant.rs:16:5: 16:12 scope 3 { debug y => _5;               // in scope 3 at $DIR/invalid_constant.rs:16:5: 16:12 </del> <ins> debug _invalid_char => _1;       // in scope 1 at $DIR/invalid_constant.rs:19:9: 19:22 let _2: [main::InvalidTag; 1];   // in scope 1 at $DIR/invalid_constant.rs:26:9: 26:21 scope 2 { debug _invalid_tag => _2;    // in scope 2 at $DIR/invalid_constant.rs:26:9: 26:21 let _4: [main::NoVariants; 1]; // in scope 2 at $DIR/invalid_constant.rs:33:9: 33:31 scope 3 { debug _enum_without_variants => _4; // in scope 3 at $DIR/invalid_constant.rs:33:9: 33:31 } </ins> } } bb0: { <del> discriminant(_2) = 0;            // scope 0 at $DIR/invalid_constant.rs:16:7: 16:11 -         _4 = discriminant(_2);           // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12 -         switchInt(move _4) -> [0_isize: bb3, otherwise: bb2]; // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12 +         _4 = const 0_isize;              // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12 +         switchInt(const 0_isize) -> [0_isize: bb3, otherwise: bb2]; // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12 } bb1: { -         _3 = const { Union { int: 0x110001 } }; // scope 0 at $DIR/invalid_constant.rs:22:25: 22:58 +         _3 = const main::Union { int: 1114113_u32, chr: {transmute(0x00110001): char} }; // scope 0 at $DIR/invalid_constant.rs:22:25: 22:58 </del> <ins> StorageLive(_1);                 // scope 0 at $DIR/invalid_constant.rs:19:9: 19:22 -         _1 = const { InvalidChar { int: 0x110001 } }; // scope 0 at $DIR/invalid_constant.rs:19:25: 19:64 +         _1 = const InvalidChar { int: 1114113_u32, chr: {transmute(0x00110001): char} }; // scope 0 at $DIR/invalid_constant.rs:19:25: 19:64 </ins> // ty::Const <del> // + ty: main::Union -                                          // + val: Unevaluated(main::{constant#0}, [main::Union], None) </del> <ins> // + ty: main::InvalidChar -                                          // + val: Unevaluated(main::{constant#0}, [main::InvalidChar], None) </ins> +                                          // + val: Value(Scalar(0x00110001)) // mir::Constant <del> // + span: $DIR/invalid_constant.rs:22:25: 22:58 -                                          // + literal: Const { ty: main::Union, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:8 ~ invalid_constant[726d]::main::{constant#0}), const_param_did: None }, substs: [main::Union], promoted: None }) } +                                          // + literal: Const { ty: main::Union, val: Value(Scalar(0x00110001)) } nop;                             // scope 0 at $DIR/invalid_constant.rs:15:11: 23:2 return;                          // scope 0 at $DIR/invalid_constant.rs:23:2: 23:2 } bb2: { -         _5 = ((_2 as Some).0: std::option::Option<()>); // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12 -         _1 = _5;                         // scope 3 at $DIR/invalid_constant.rs:16:5: 16:12 +         _5 = const Scalar(0x02): Option::<()>; // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12 </del> <ins> // + span: $DIR/invalid_constant.rs:19:25: 19:64 -                                          // + literal: Const { ty: main::InvalidChar, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:7 ~ invalid_constant[726d]::main::{constant#0}), const_param_did: None }, substs: [main::InvalidChar], promoted: None }) } +                                          // + literal: Const { ty: main::InvalidChar, val: Value(Scalar(0x00110001)) } StorageLive(_2);                 // scope 1 at $DIR/invalid_constant.rs:26:9: 26:21 StorageLive(_3);                 // scope 1 at $DIR/invalid_constant.rs:26:25: 26:46 (_3.0: u32) = const 4_u32;       // scope 1 at $DIR/invalid_constant.rs:26:25: 26:46 -         _2 = [move _3];                  // scope 1 at $DIR/invalid_constant.rs:26:24: 26:47 +         _2 = [const InvalidTag { int: 4_u32, e: Scalar(0x00000004): E }]; // scope 1 at $DIR/invalid_constant.rs:26:24: 26:47 </ins> +                                          // ty::Const <del> +                                          // + ty: std::option::Option<()> +                                          // + val: Value(Scalar(0x02)) </del> <ins> +                                          // + ty: main::InvalidTag +                                          // + val: Value(Scalar(0x00000004)) </ins> +                                          // mir::Constant <del> +                                          // + span: $DIR/invalid_constant.rs:16:5: 16:12 +                                          // + literal: Const { ty: std::option::Option<()>, val: Value(Scalar(0x02)) } +         _1 = const Scalar(0x02): Option::<()>; // scope 3 at $DIR/invalid_constant.rs:16:5: 16:12 </del> <ins> +                                          // + span: $DIR/invalid_constant.rs:26:24: 26:47 +                                          // + literal: Const { ty: main::InvalidTag, val: Value(Scalar(0x00000004)) } StorageDead(_3);                 // scope 1 at $DIR/invalid_constant.rs:26:46: 26:47 StorageLive(_4);                 // scope 2 at $DIR/invalid_constant.rs:33:9: 33:31 StorageLive(_5);                 // scope 2 at $DIR/invalid_constant.rs:33:35: 33:56 (_5.0: u32) = const 0_u32;       // scope 2 at $DIR/invalid_constant.rs:33:35: 33:56 -         _4 = [move _5];                  // scope 2 at $DIR/invalid_constant.rs:33:34: 33:57 +         _4 = [const NoVariants { int: 0_u32, empty: Scalar(<ZST>): Empty }]; // scope 2 at $DIR/invalid_constant.rs:33:34: 33:57 </ins> +                                          // ty::Const <del> +                                          // + ty: std::option::Option<()> +                                          // + val: Value(Scalar(0x02)) </del> <ins> +                                          // + ty: main::NoVariants +                                          // + val: Value(Scalar(0x00000000)) </ins> +                                          // mir::Constant <del> +                                          // + span: $DIR/invalid_constant.rs:16:5: 16:12 +                                          // + literal: Const { ty: std::option::Option<()>, val: Value(Scalar(0x02)) } goto -> bb1;                     // scope 0 at $DIR/invalid_constant.rs:10:20: 10:21 } bb3: { discriminant(_1) = 0;            // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12 goto -> bb1;                     // scope 0 at $DIR/invalid_constant.rs:9:17: 9:21 </del> <ins> +                                          // + span: $DIR/invalid_constant.rs:33:34: 33:57 +                                          // + literal: Const { ty: main::NoVariants, val: Value(Scalar(0x00000000)) } StorageDead(_5);                 // scope 2 at $DIR/invalid_constant.rs:33:56: 33:57 nop;                             // scope 0 at $DIR/invalid_constant.rs:13:11: 34:2 StorageDead(_4);                 // scope 2 at $DIR/invalid_constant.rs:34:1: 34:2 StorageDead(_2);                 // scope 1 at $DIR/invalid_constant.rs:34:1: 34:2 StorageDead(_1);                 // scope 0 at $DIR/invalid_constant.rs:34:1: 34:2 return;                          // scope 0 at $DIR/invalid_constant.rs:34:2: 34:2 </ins> } }

<del> // Verify that we can pretty print invalid constant introduced // by constant propagation. Regression test for issue #93688. // // compile-flags: -Copt-level=0 -Zinline-mir </del> <ins> // Verify that we can pretty print invalid constants. </ins> #![feature(inline_const)] <del> #[inline(always)] pub fn f(x: Option<Option<()>>) -> Option<()> { match x { None => None, Some(y) => y, } } </del> <ins> #[derive(Copy, Clone)] #[repr(u32)] enum E { A, B, C } #[derive(Copy, Clone)] enum Empty {} </ins> // EMIT_MIR invalid_constant.main.ConstProp.diff fn main() { <del> f(None); union Union { </del> <ins> // An invalid char. union InvalidChar { </ins> int: u32, chr: char, } <del> let _invalid_char = const { Union { int: 0x110001 } }; </del> <ins> let _invalid_char = const { InvalidChar { int: 0x110001 } }; // An enum with an invalid tag. Regression test for #93688. union InvalidTag { int: u32, e: E, } let _invalid_tag = [InvalidTag { int: 4 }]; // An enum without variants. Regression test for #94073. union NoVariants { int: u32, empty: Empty, } let _enum_without_variants = [NoVariants { int: 0 }]; </ins> }