Skip to content

Commit b05e94f

Browse files
committed
transpile: Propagate cast of EnumConstant to its own integral type
1 parent 777d9f7 commit b05e94f

4 files changed

Lines changed: 21 additions & 11 deletions

File tree

c2rust-transpile/src/translator/enums.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ impl<'c> Translation<'c> {
163163
type_enum_id == constant_enum_id
164164
}
165165

166-
fn enum_integral_type(&self, enum_id: CEnumId) -> CQualTypeId {
166+
pub fn enum_integral_type(&self, enum_id: CEnumId) -> CQualTypeId {
167167
match self.ast_context[enum_id].kind {
168168
CDeclKind::Enum {
169169
integral_type: Some(integral_type),

c2rust-transpile/src/translator/mod.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3104,10 +3104,10 @@ impl<'c> Translation<'c> {
31043104
// If the variable is actually an `EnumConstant`, we need to add a cast to the
31053105
// expected integral type.
31063106
if let &CDeclKind::EnumConstant { .. } = decl {
3107-
if !self
3108-
.enum_constant_matches_type(override_ty.unwrap_or(qual_ty).ctype, decl_id)
3109-
{
3110-
val = self.convert_cast_from_enum(qual_ty.ctype, val)?;
3107+
let target_type_id = override_ty.unwrap_or(qual_ty);
3108+
3109+
if !self.enum_constant_matches_type(target_type_id.ctype, decl_id) {
3110+
val = self.convert_cast_from_enum(target_type_id.ctype, val)?;
31113111
}
31123112

31133113
return Ok(WithStmts::new_val(val));
@@ -3551,6 +3551,18 @@ impl<'c> Translation<'c> {
35513551
return true;
35523552
}
35533553
}
3554+
3555+
let source_enum_id = self.ast_context.parents[&decl_id];
3556+
let source_integral_type_id = self.enum_integral_type(source_enum_id);
3557+
let target_type_resolved_id = self
3558+
.ast_context
3559+
.resolve_type_id_no_typedef(target_type_id.ctype);
3560+
3561+
// Likewise, if we are casting to the inner integral type of the enum, then
3562+
// translate the enum constant directly as that.
3563+
if target_type_resolved_id == source_integral_type_id.ctype {
3564+
return true;
3565+
}
35543566
}
35553567
}
35563568

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,8 @@ pub unsafe extern "C" fn test_enums() {
3333
let mut e: Foo = Foo1;
3434
let mut enum_enum: ::core::ffi::c_int =
3535
(e as ::core::ffi::c_uint == foo as ::core::ffi::c_uint) as ::core::ffi::c_int;
36-
let mut enum_constant: ::core::ffi::c_int = (e as ::core::ffi::c_uint
37-
== Foo0 as ::core::ffi::c_int as ::core::ffi::c_uint)
38-
as ::core::ffi::c_int;
36+
let mut enum_constant: ::core::ffi::c_int =
37+
(e as ::core::ffi::c_uint == Foo0 as ::core::ffi::c_uint) as ::core::ffi::c_int;
3938
let mut wrong_enum_enum: ::core::ffi::c_int =
4039
(e as ::core::ffi::c_uint == bar as ::core::ffi::c_uint) as ::core::ffi::c_int;
4140
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
@@ -34,9 +34,8 @@ pub unsafe extern "C" fn test_enums() {
3434
let mut e: Foo = Foo1;
3535
let mut enum_enum: ::core::ffi::c_int =
3636
(e as ::core::ffi::c_uint == foo as ::core::ffi::c_uint) as ::core::ffi::c_int;
37-
let mut enum_constant: ::core::ffi::c_int = (e as ::core::ffi::c_uint
38-
== Foo0 as ::core::ffi::c_int as ::core::ffi::c_uint)
39-
as ::core::ffi::c_int;
37+
let mut enum_constant: ::core::ffi::c_int =
38+
(e as ::core::ffi::c_uint == Foo0 as ::core::ffi::c_uint) as ::core::ffi::c_int;
4039
let mut wrong_enum_enum: ::core::ffi::c_int =
4140
(e as ::core::ffi::c_uint == bar as ::core::ffi::c_uint) as ::core::ffi::c_int;
4241
let mut wrong_enum_constant: ::core::ffi::c_int = (e as ::core::ffi::c_uint

0 commit comments

Comments
 (0)