Skip to content

Commit f999097

Browse files
committed
transpile: let convert_literal handle casting literal to enum
1 parent 03a1045 commit f999097

4 files changed

Lines changed: 18 additions & 31 deletions

File tree

c2rust-transpile/src/translator/enums.rs

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@ use c2rust_ast_builder::mk;
22
use proc_macro2::Span;
33
use syn::Expr;
44

5-
use crate::c_ast::CUnOp;
65
use crate::{
76
diagnostics::TranslationResult,
87
translator::{signed_int_expr, ConvertedDecl, EnumMode, ExprContext, Translation},
98
with_stmts::WithStmts,
10-
CDeclKind, CEnumConstantId, CEnumId, CExprId, CExprKind, CLiteral, CQualTypeId, CTypeId,
11-
CTypeKind, ConstIntExpr,
9+
CDeclKind, CEnumConstantId, CEnumId, CQualTypeId, CTypeId, CTypeKind, ConstIntExpr,
1210
};
1311

1412
impl<'c> Translation<'c> {
@@ -141,29 +139,8 @@ impl<'c> Translation<'c> {
141139
ctx: ExprContext,
142140
mut source_cty: CQualTypeId,
143141
enum_id: CEnumId,
144-
expr: Option<CExprId>,
145142
mut val: Box<Expr>,
146143
) -> TranslationResult<WithStmts<Box<Expr>>> {
147-
if let Some(expr) = expr {
148-
match self.ast_context[expr].kind {
149-
CExprKind::Literal(_, CLiteral::Integer(i, _)) => {
150-
val = self.enum_for_i64(enum_id, i as i64);
151-
return Ok(WithStmts::new_val(val));
152-
}
153-
154-
CExprKind::Unary(_, CUnOp::Negate, subexpr_id, _) => {
155-
if let &CExprKind::Literal(_, CLiteral::Integer(i, _)) =
156-
&self.ast_context[subexpr_id].kind
157-
{
158-
val = self.enum_for_i64(enum_id, -(i as i64));
159-
return Ok(WithStmts::new_val(val));
160-
}
161-
}
162-
163-
_ => {}
164-
}
165-
}
166-
167144
// We could be casting from enum to enum...
168145
if let CTypeKind::Enum(source_enum_id) =
169146
self.ast_context.resolve_type(source_cty.ctype).kind
@@ -208,7 +185,7 @@ impl<'c> Translation<'c> {
208185

209186
/// Given an integer value this attempts to either generate the corresponding enum
210187
/// variant directly, otherwise it converts a number to the enum type.
211-
fn enum_for_i64(&self, enum_id: CEnumId, value: i64) -> Box<Expr> {
188+
pub fn enum_for_i64(&self, enum_id: CEnumId, value: i64) -> Box<Expr> {
212189
if let Some(enum_constant_id) = self.enum_variant_for_i64(enum_id, value) {
213190
return self.enum_constant_expr(enum_constant_id);
214191
}

c2rust-transpile/src/translator/literals.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@ impl<'c> Translation<'c> {
1616
base: IntBase,
1717
negative: bool,
1818
) -> TranslationResult<Box<Expr>> {
19+
let type_resolved_id = self.ast_context.resolve_type_id(ty.ctype);
20+
21+
if let CTypeKind::Enum(enum_id) = self.ast_context[type_resolved_id].kind {
22+
let mut val = val as i64;
23+
24+
if negative {
25+
val = -val;
26+
}
27+
28+
return Ok(self.enum_for_i64(enum_id, val));
29+
}
30+
1931
let lit = match base {
2032
IntBase::Dec => mk().int_unsuffixed_lit(val),
2133
IntBase::Hex => mk().float_unsuffixed_lit(&format!("0x{:x}", val)),
@@ -35,6 +47,7 @@ impl<'c> Translation<'c> {
3547
pub fn literal_matches_ty(&self, lit: &CLiteral, ty: CQualTypeId, is_negated: bool) -> bool {
3648
let ty_kind = &self.ast_context.resolve_type(ty.ctype).kind;
3749
match *lit {
50+
CLiteral::Integer(_, _) if ty_kind.is_enum() => true,
3851
CLiteral::Integer(value, _) | CLiteral::Character(value)
3952
if ty_kind.is_integral_type() && !ty_kind.is_bool() =>
4053
{

c2rust-transpile/src/translator/mod.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3660,7 +3660,7 @@ impl<'c> Translation<'c> {
36603660
}
36613661

36623662
CastKind::PointerToIntegral => {
3663-
self.convert_pointer_to_integral_cast(ctx, source_cty, target_cty, val, expr)
3663+
self.convert_pointer_to_integral_cast(ctx, source_cty, target_cty, val)
36643664
}
36653665

36663666
CastKind::IntegralCast
@@ -3696,9 +3696,7 @@ impl<'c> Translation<'c> {
36963696
{
36973697
self.f128_cast_to(val, target_ty_kind)
36983698
} else if let &CTypeKind::Enum(enum_id) = target_ty_kind {
3699-
val.and_then_try(|val| {
3700-
self.convert_cast_to_enum(ctx, source_cty, enum_id, expr, val)
3701-
})
3699+
val.and_then_try(|val| self.convert_cast_to_enum(ctx, source_cty, enum_id, val))
37023700
} else if target_ty_kind.is_floating_type() && source_ty_kind.is_bool() {
37033701
Ok(val.map(|val| {
37043702
mk().cast_expr(mk().cast_expr(val, mk().path_ty(vec!["u8"])), target_ty)

c2rust-transpile/src/translator/pointers.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,6 @@ impl<'c> Translation<'c> {
514514
source_cty: CQualTypeId,
515515
target_cty: CQualTypeId,
516516
val: WithStmts<Box<Expr>>,
517-
expr: Option<CExprId>,
518517
) -> TranslationResult<WithStmts<Box<Expr>>> {
519518
if ctx.is_const {
520519
return Err(format_translation_err!(
@@ -532,7 +531,7 @@ impl<'c> Translation<'c> {
532531
WithStmts::new_val(transmute_expr(source_ty, target_ty, val)).set_unsafe()
533532
}))
534533
} else if let &CTypeKind::Enum(enum_id) = target_ty_kind {
535-
val.and_then_try(|val| self.convert_cast_to_enum(ctx, source_cty, enum_id, expr, val))
534+
val.and_then_try(|val| self.convert_cast_to_enum(ctx, source_cty, enum_id, val))
536535
} else {
537536
Ok(val.map(|val| mk().cast_expr(val, target_ty)))
538537
}

0 commit comments

Comments
 (0)