@@ -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