Skip to content

Commit 96dbe2f

Browse files
committed
transpile: Add override type for enums in SwitchCases
1 parent e78d538 commit 96dbe2f

1 file changed

Lines changed: 37 additions & 11 deletions

File tree

  • c2rust-transpile/src/cfg

c2rust-transpile/src/cfg/mod.rs

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

438440
/// A Rust statement, or a C declaration, or a comment
@@ -1857,6 +1859,14 @@ impl CfgBuilder {
18571859
self.add_wip_block(wip, Jump(this_label.clone()));
18581860

18591861
// Case
1862+
1863+
let switch_case = self.switch_expr_cases.last_mut().ok_or_else(|| {
1864+
format_err!(
1865+
"Cannot find the 'switch' wrapping this ({:?}) 'case' statement",
1866+
stmt_id,
1867+
)
1868+
})?;
1869+
18601870
let expr = translator
18611871
.convert_expr(ctx.const_().pattern().used(), case_expr, None)
18621872
.ok()
@@ -1868,16 +1878,7 @@ impl CfgBuilder {
18681878
ConstIntExpr::I(n) => mk().lit_pat(mk().int_unsuffixed_lit(n)),
18691879
});
18701880

1871-
self.switch_expr_cases
1872-
.last_mut()
1873-
.ok_or_else(|| {
1874-
format_err!(
1875-
"Cannot find the 'switch' wrapping this ({:?}) 'case' statement",
1876-
stmt_id,
1877-
)
1878-
})?
1879-
.cases
1880-
.push((pat, this_label.clone()));
1881+
switch_case.cases.push((pat, this_label.clone()));
18811882

18821883
// Sub stmt
18831884
let sub_stmt_next = self.convert_stmt_help(
@@ -1923,6 +1924,28 @@ impl CfgBuilder {
19231924
let body_label = self.fresh_label();
19241925

19251926
// Convert the condition
1927+
1928+
let mut override_type_id = None;
1929+
1930+
// If the condition is an implicit cast from an enum to its integral type,
1931+
// override the type to that of the enum.
1932+
if let CExprKind::ImplicitCast(target_type_id, castee_id, ..) =
1933+
translator.ast_context[scrutinee].kind
1934+
{
1935+
let castee_kind = &translator.ast_context[castee_id].kind;
1936+
let castee_type_id = castee_kind.get_qual_type().unwrap();
1937+
let castee_type_kind = &translator
1938+
.ast_context
1939+
.resolve_type(castee_type_id.ctype)
1940+
.kind;
1941+
1942+
if let &CTypeKind::Enum(enum_id) = castee_type_kind {
1943+
if target_type_id == translator.enum_integral_type(enum_id) {
1944+
override_type_id = Some(castee_type_id);
1945+
}
1946+
}
1947+
}
1948+
19261949
let (stmts, val) = translator
19271950
.convert_expr(ctx.used(), scrutinee, None)?
19281951
.discard_unsafe();
@@ -1936,7 +1959,10 @@ impl CfgBuilder {
19361959
let saw_unmatched_case = self.last_per_stmt_mut().saw_unmatched_case;
19371960
let saw_unmatched_default = self.last_per_stmt_mut().saw_unmatched_default;
19381961
self.break_labels.push(next_label.clone());
1939-
self.switch_expr_cases.push(SwitchCases::default());
1962+
self.switch_expr_cases.push(SwitchCases {
1963+
override_type_id,
1964+
..Default::default()
1965+
});
19401966

19411967
let body_stuff = self.convert_stmt_help(
19421968
translator,

0 commit comments

Comments
 (0)