Skip to content

Commit 6e42535

Browse files
committed
miri: accept fieldless repr-int enums as ABI-compatible with the integer
1 parent 71c83bf commit 6e42535

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

compiler/rustc_const_eval/src/interpret/terminator.rs

+14
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
404404
ty::Int(ity) => (Integer::from_int_ty(&self.tcx, *ity), /* signed */ true),
405405
ty::Uint(uty) => (Integer::from_uint_ty(&self.tcx, *uty), /* signed */ false),
406406
ty::Char => (Integer::I32, /* signed */ false),
407+
ty::Adt(def, _) => {
408+
// Ensure it is an enum, with a suitable repr, and fieldless.
409+
if !def.is_enum() {
410+
return None;
411+
}
412+
let Some(int_ty) = def.repr().int else {
413+
return None;
414+
};
415+
if !def.variants().iter().all(|variant| variant.fields.is_empty()) {
416+
return None;
417+
}
418+
let int = Integer::from_attr(&self.tcx, int_ty);
419+
(int, int_ty.is_signed())
420+
}
407421
_ => return None,
408422
})
409423
};

src/tools/miri/tests/pass/function_calls/abi_compat.rs

+17
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,23 @@ fn main() {
7171
test_abi_compat(0isize, 0i64);
7272
}
7373
test_abi_compat(42u32, num::NonZero::new(1u32).unwrap());
74+
// - `repr(int)` enums and the corresponding integer.
75+
#[repr(i16)]
76+
#[derive(Copy, Clone)]
77+
enum I16 {
78+
Var1 = 0,
79+
Var2 = -5,
80+
}
81+
test_abi_compat(I16::Var1, 0i16);
82+
test_abi_compat(I16::Var2, -5i16);
83+
#[repr(u64)]
84+
#[derive(Copy, Clone)]
85+
enum U64 {
86+
Var1 = 0,
87+
Var2 = u64::MAX,
88+
}
89+
test_abi_compat(U64::Var1, 0u64);
90+
test_abi_compat(U64::Var2, u64::MAX);
7491
// - `char` and `u32`.
7592
test_abi_compat(42u32, 'x');
7693
// - Reference/pointer types with the same pointee.

0 commit comments

Comments
 (0)