Skip to content

Commit 3fc1d4a

Browse files
committed
transpile: Factor out can_propagate_cast
1 parent d8ab8fb commit 3fc1d4a

1 file changed

Lines changed: 35 additions & 18 deletions

File tree

  • c2rust-transpile/src/translator

c2rust-transpile/src/translator/mod.rs

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3097,28 +3097,15 @@ impl<'c> Translation<'c> {
30973097
_ => {}
30983098
}
30993099

3100-
let expr_kind = &self.ast_context[expr].kind;
31013100
let target_ty = override_ty.unwrap_or(ty);
31023101

31033102
// In general, if we are casting the result of an expression, then the inner
31043103
// expression should be translated to whatever type it normally would.
3105-
// But for literals, if we don't absolutely have to cast, we would rather the
3106-
// literal is translated according to the type we're expecting, and then we can
3107-
// skip the cast entirely.
3108-
if !is_explicit {
3109-
let mut literal_expr_kind = expr_kind;
3110-
let mut is_negated = false;
3111-
3112-
if let &CExprKind::Unary(_, CUnOp::Negate, subexpr_id, _) = literal_expr_kind {
3113-
literal_expr_kind = &self.ast_context[subexpr_id].kind;
3114-
is_negated = true;
3115-
}
3116-
3117-
if let CExprKind::Literal(_, lit) = literal_expr_kind {
3118-
if self.literal_matches_ty(lit, target_ty, is_negated) {
3119-
return self.convert_expr(ctx, expr, Some(target_ty));
3120-
}
3121-
}
3104+
// But for some expression types, if we don't absolutely have to cast,
3105+
// we would rather the expression is translated according to the type we're
3106+
// expecting, and then we can skip the cast entirely.
3107+
if self.can_propagate_cast(expr, target_ty, is_explicit) {
3108+
return self.convert_expr(ctx, expr, Some(target_ty));
31223109
}
31233110

31243111
let mut val = self.convert_expr(ctx, expr, None)?;
@@ -3588,6 +3575,36 @@ impl<'c> Translation<'c> {
35883575
}
35893576
}
35903577

3578+
fn can_propagate_cast(
3579+
&self,
3580+
expr_id: CExprId,
3581+
target_type_id: CQualTypeId,
3582+
is_explicit: bool,
3583+
) -> bool {
3584+
// Always preserve explicit casts.
3585+
if is_explicit {
3586+
return false;
3587+
}
3588+
3589+
let expr_kind = &self.ast_context[expr_id].kind;
3590+
let mut literal_expr_kind = expr_kind;
3591+
let mut is_negated = false;
3592+
3593+
if let &CExprKind::Unary(_, CUnOp::Negate, subexpr_id, _) = literal_expr_kind {
3594+
literal_expr_kind = &self.ast_context[subexpr_id].kind;
3595+
is_negated = true;
3596+
}
3597+
3598+
if let CExprKind::Literal(_, lit) = literal_expr_kind {
3599+
// Does the inner literal fit in the type we're casting to?
3600+
if self.literal_matches_ty(lit, target_type_id, is_negated) {
3601+
return true;
3602+
}
3603+
}
3604+
3605+
false
3606+
}
3607+
35913608
pub fn convert_cast(
35923609
&self,
35933610
ctx: ExprContext,

0 commit comments

Comments
 (0)