Skip to content

Commit 5f6aaa7

Browse files
committed
transpile: Propagate cast of EnumConstant to its own integral type
1 parent c6e5839 commit 5f6aaa7

4 files changed

Lines changed: 21 additions & 12 deletions

File tree

c2rust-transpile/src/translator/enums.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ impl<'c> Translation<'c> {
142142
type_enum_id == constant_enum_id
143143
}
144144

145-
fn enum_integral_type(&self, enum_id: CEnumId) -> CQualTypeId {
145+
pub fn enum_integral_type(&self, enum_id: CEnumId) -> CQualTypeId {
146146
match self.ast_context[enum_id].kind {
147147
CDeclKind::Enum {
148148
integral_type: Some(integral_type),

c2rust-transpile/src/translator/mod.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3058,11 +3058,10 @@ impl<'c> Translation<'c> {
30583058
CDeclKind::EnumConstant { .. } => {
30593059
// If the variable is actually an `EnumConstant`, we need to add a cast to
30603060
// the expected integral type.
3061-
if !self.enum_constant_matches_type(
3062-
override_ty.unwrap_or(qual_ty).ctype,
3063-
decl_id,
3064-
) {
3065-
val = self.convert_cast_from_enum(qual_ty.ctype, val)?;
3061+
let target_type_id = override_ty.unwrap_or(qual_ty);
3062+
3063+
if !self.enum_constant_matches_type(target_type_id.ctype, decl_id) {
3064+
val = self.convert_cast_from_enum(target_type_id.ctype, val)?;
30663065
}
30673066

30683067
return Ok(WithStmts::new_val(val));
@@ -3479,6 +3478,18 @@ impl<'c> Translation<'c> {
34793478
if self.enum_constant_matches_type(target_type_id.ctype, decl_id) {
34803479
return true;
34813480
}
3481+
3482+
let source_enum_id = self.ast_context.parents[&decl_id];
3483+
let source_integral_type_id = self.enum_integral_type(source_enum_id);
3484+
let target_type_resolved_id = self
3485+
.ast_context
3486+
.resolve_type_id_no_typedef(target_type_id.ctype);
3487+
3488+
// Likewise, if we are casting to the inner integral type of the enum, then
3489+
// translate the enum constant directly as that.
3490+
if target_type_resolved_id == source_integral_type_id.ctype {
3491+
return true;
3492+
}
34823493
}
34833494
}
34843495

c2rust-transpile/tests/snapshots/snapshots__transpile@enums.c.2021.snap

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ pub unsafe extern "C" fn test_enums() {
4141
let mut e: Foo = Foo1;
4242
let mut enum_enum: ::core::ffi::c_int =
4343
(e as ::core::ffi::c_uint == foo as ::core::ffi::c_uint) as ::core::ffi::c_int;
44-
let mut enum_constant: ::core::ffi::c_int = (e as ::core::ffi::c_uint
45-
== Foo0 as ::core::ffi::c_int as ::core::ffi::c_uint)
46-
as ::core::ffi::c_int;
44+
let mut enum_constant: ::core::ffi::c_int =
45+
(e as ::core::ffi::c_uint == Foo0 as ::core::ffi::c_uint) as ::core::ffi::c_int;
4746
let mut wrong_enum_enum: ::core::ffi::c_int =
4847
(e as ::core::ffi::c_uint == bar as ::core::ffi::c_uint) as ::core::ffi::c_int;
4948
let mut wrong_enum_constant: ::core::ffi::c_int = (e as ::core::ffi::c_uint

c2rust-transpile/tests/snapshots/snapshots__transpile@enums.c.2024.snap

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,8 @@ pub unsafe extern "C" fn test_enums() {
4242
let mut e: Foo = Foo1;
4343
let mut enum_enum: ::core::ffi::c_int =
4444
(e as ::core::ffi::c_uint == foo as ::core::ffi::c_uint) as ::core::ffi::c_int;
45-
let mut enum_constant: ::core::ffi::c_int = (e as ::core::ffi::c_uint
46-
== Foo0 as ::core::ffi::c_int as ::core::ffi::c_uint)
47-
as ::core::ffi::c_int;
45+
let mut enum_constant: ::core::ffi::c_int =
46+
(e as ::core::ffi::c_uint == Foo0 as ::core::ffi::c_uint) as ::core::ffi::c_int;
4847
let mut wrong_enum_enum: ::core::ffi::c_int =
4948
(e as ::core::ffi::c_uint == bar as ::core::ffi::c_uint) as ::core::ffi::c_int;
5049
let mut wrong_enum_constant: ::core::ffi::c_int = (e as ::core::ffi::c_uint

0 commit comments

Comments
 (0)