Skip to content

Commit 6b1083c

Browse files
authored
Rollup merge of rust-lang#76199 - Mark-Simulacrum:void-zero, r=nikomatsakis
Permit uninhabited enums to cast into ints This essentially reverts part of rust-lang#6204; it is unclear why that [commit](rust-lang@c0f587d) was introduced, and I suspect no one remembers. The changed code was only called from casting checks and appears to not affect any callers of that code (other than permitting this one case). Fixes rust-lang#75647.
2 parents e3051d8 + 990a395 commit 6b1083c

File tree

4 files changed

+12
-12
lines changed

4 files changed

+12
-12
lines changed

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2436,8 +2436,10 @@ impl<'tcx> AdtDef {
24362436
self.variants.iter().flat_map(|v| v.fields.iter())
24372437
}
24382438

2439+
/// Whether the ADT lacks fields. Note that this includes uninhabited enums,
2440+
/// e.g., `enum Void {}` is considered payload free as well.
24392441
pub fn is_payloadfree(&self) -> bool {
2440-
!self.variants.is_empty() && self.variants.iter().all(|v| v.fields.is_empty())
2442+
self.variants.iter().all(|v| v.fields.is_empty())
24412443
}
24422444

24432445
/// Return a `VariantDef` given a variant id.

compiler/rustc_mir/src/interpret/cast.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
139139

140140
// # First handle non-scalar source values.
141141

142-
// Handle cast from a univariant (ZST) enum.
142+
// Handle cast from a ZST enum (0 or 1 variants).
143143
match src.layout.variants {
144144
Variants::Single { index } => {
145+
if src.layout.abi.is_uninhabited() {
146+
// This is dead code, because an uninhabited enum is UB to
147+
// instantiate.
148+
throw_ub!(Unreachable);
149+
}
145150
if let Some(discr) = src.layout.ty.discriminant_for_variant(*self.tcx, index) {
146151
assert!(src.layout.is_zst());
147152
let discr_layout = self.layout_of(discr.ty)?;
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
// check-pass
2+
13
enum E {}
24

35
fn f(e: E) {
4-
println!("{}", (e as isize).to_string()); //~ ERROR non-primitive cast
6+
println!("{}", (e as isize).to_string());
57
}
68

79
fn main() {}

src/test/ui/uninhabited/uninhabited-enum-cast.stderr

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)