Skip to content

Commit ebce1f8

Browse files
committed
transpile: Translate enums in switch as their own type instead of integers
1 parent 166b751 commit ebce1f8

6 files changed

Lines changed: 53 additions & 21 deletions

File tree

c2rust-ast-builder/src/builder.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,20 @@ impl Builder {
12281228
})
12291229
}
12301230

1231+
pub fn tuple_struct_pat<Pa>(self, path: Pa, qself: Option<QSelf>, elems: Vec<Pat>) -> Pat
1232+
where
1233+
Pa: Make<Path>,
1234+
{
1235+
let path = path.make(&self);
1236+
Pat::TupleStruct(PatTupleStruct {
1237+
attrs: self.attrs,
1238+
qself,
1239+
path,
1240+
paren_token: token::Paren(self.span),
1241+
elems: punct(elems),
1242+
})
1243+
}
1244+
12311245
// Types
12321246

12331247
pub fn barefn_ty(self, decl: BareFnTyParts) -> Box<Type> {

c2rust-transpile/src/cfg/mod.rs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,6 @@ impl GenTerminator<StructureLabel<StmtOrDecl>> {
433433
pub struct SwitchCases {
434434
cases: Vec<(Pat, Label)>,
435435
default: Option<Label>,
436-
#[allow(unused)]
437436
override_type_id: Option<CQualTypeId>,
438437
}
439438

@@ -1868,15 +1867,34 @@ impl CfgBuilder {
18681867
})?;
18691868

18701869
let expr = translator
1871-
.convert_expr(ctx.const_().pattern().used(), case_expr, None)
1870+
.convert_expr(
1871+
ctx.const_().pattern().used(),
1872+
case_expr,
1873+
switch_case.override_type_id,
1874+
)
18721875
.ok()
18731876
.and_then(WithStmts::to_pure_expr);
1874-
let pat = expr
1875-
.and_then(|expr| expr_to_pat(*expr))
1876-
.unwrap_or_else(|| match cie {
1877+
let pat = expr.and_then(|expr| expr_to_pat(*expr)).unwrap_or_else(|| {
1878+
let mut pat = match cie {
18771879
ConstIntExpr::U(n) => mk().lit_pat(mk().int_unsuffixed_lit(n)),
18781880
ConstIntExpr::I(n) => mk().lit_pat(mk().int_unsuffixed_lit(n)),
1879-
});
1881+
};
1882+
1883+
if let Some(override_ty) = switch_case.override_type_id {
1884+
if let CTypeKind::Enum(enum_id) =
1885+
translator.ast_context.resolve_type(override_ty.ctype).kind
1886+
{
1887+
let enum_name = translator
1888+
.type_converter
1889+
.borrow()
1890+
.resolve_decl_name(enum_id)
1891+
.unwrap();
1892+
pat = mk().tuple_struct_pat(enum_name.as_str(), None, vec![pat]);
1893+
}
1894+
}
1895+
1896+
pat
1897+
});
18801898

18811899
switch_case.cases.push((pat, this_label.clone()));
18821900

@@ -1947,7 +1965,7 @@ impl CfgBuilder {
19471965
}
19481966

19491967
let (stmts, val) = translator
1950-
.convert_expr(ctx.used(), scrutinee, None)?
1968+
.convert_expr(ctx.used(), scrutinee, override_type_id)?
19511969
.discard_unsafe();
19521970
wip.extend(stmts);
19531971

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ pub unsafe extern "C" fn test_enums() {
4949
(e.0 == bar.0 as ::core::ffi::c_uint) as ::core::ffi::c_int;
5050
let mut wrong_enum_constant: ::core::ffi::c_int =
5151
(e.0 == Bar0.0 as ::core::ffi::c_uint) as ::core::ffi::c_int;
52-
match foo.0 {
53-
0 | FOO1_MACRO | 2 | 3 | 42 | 4294967254 | _ => {}
52+
match foo {
53+
Foo0 | Foo(FOO1_MACRO) | Foo2 | Foo(3) | Foo(42) | Foo(4294967254) | _ => {}
5454
}
55-
match bar.0 {
56-
0 | BAR1_MACRO | 2 | 3 | -1 | 42 | -42 | _ => {}
55+
match bar {
56+
Bar0 | Bar(BAR1_MACRO) | Bar2 | Bar(3) | BarN1 | Bar(42) | Bar(-42) | _ => {}
5757
};
5858
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ pub unsafe extern "C" fn test_enums() {
5050
(e.0 == bar.0 as ::core::ffi::c_uint) as ::core::ffi::c_int;
5151
let mut wrong_enum_constant: ::core::ffi::c_int =
5252
(e.0 == Bar0.0 as ::core::ffi::c_uint) as ::core::ffi::c_int;
53-
match foo.0 {
54-
0 | FOO1_MACRO | 2 | 3 | 42 | 4294967254 | _ => {}
53+
match foo {
54+
Foo0 | Foo(FOO1_MACRO) | Foo2 | Foo(3) | Foo(42) | Foo(4294967254) | _ => {}
5555
}
56-
match bar.0 {
57-
0 | BAR1_MACRO | 2 | 3 | -1 | 42 | -42 | _ => {}
56+
match bar {
57+
Bar0 | Bar(BAR1_MACRO) | Bar2 | Bar(3) | BarN1 | Bar(42) | Bar(-42) | _ => {}
5858
};
5959
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ pub const ZSTD_d_format: ::core::ffi::c_uint = 1000 as ::core::ffi::c_uint;
2020
#[no_mangle]
2121
pub unsafe extern "C" fn ZSTD_dParam_getBounds(mut dParam: ZSTD_dParameter) -> ::core::ffi::c_int {
2222
let mut bounds: ::core::ffi::c_int = 0 as ::core::ffi::c_int;
23-
match dParam.0 {
24-
100 => {
23+
match dParam {
24+
ZSTD_d_windowLogMax => {
2525
bounds = 1 as ::core::ffi::c_int;
2626
return bounds;
2727
}
28-
ZSTD_d_format => {
28+
ZSTD_d_experimentalParam1 => {
2929
bounds = 5 as ::core::ffi::c_int;
3030
return bounds;
3131
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ pub const ZSTD_d_format: ::core::ffi::c_uint = 1000 as ::core::ffi::c_uint;
2121
#[unsafe(no_mangle)]
2222
pub unsafe extern "C" fn ZSTD_dParam_getBounds(mut dParam: ZSTD_dParameter) -> ::core::ffi::c_int {
2323
let mut bounds: ::core::ffi::c_int = 0 as ::core::ffi::c_int;
24-
match dParam.0 {
25-
100 => {
24+
match dParam {
25+
ZSTD_d_windowLogMax => {
2626
bounds = 1 as ::core::ffi::c_int;
2727
return bounds;
2828
}
29-
ZSTD_d_format => {
29+
ZSTD_d_experimentalParam1 => {
3030
bounds = 5 as ::core::ffi::c_int;
3131
return bounds;
3232
}

0 commit comments

Comments
 (0)