Skip to content

Commit bb8a81f

Browse files
committed
transpile: Propagate cast of EnumConstant to its own integral type
1 parent a75d024 commit bb8a81f

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));
@@ -3544,6 +3544,18 @@ impl<'c> Translation<'c> {
35443544
return true;
35453545
}
35463546
}
3547+
3548+
let source_enum_id = self.ast_context.parents[&decl_id];
3549+
let source_integral_type_id = self.enum_integral_type(source_enum_id);
3550+
let target_type_resolved_id = self
3551+
.ast_context
3552+
.resolve_type_id_no_typedef(target_type_id.ctype);
3553+
3554+
// Likewise, if we are casting to the inner integral type of the enum, then
3555+
// translate the enum constant directly as that.
3556+
if target_type_resolved_id == source_integral_type_id.ctype {
3557+
return true;
3558+
}
35473559
}
35483560
}
35493561

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)