@@ -1531,6 +1531,84 @@ impl SsaBuilder {
15311531 self . translate_expression ( block_id, & lowered_expr)
15321532 }
15331533
1534+ fn int_type_width_and_sign ( ty : & HirType ) -> Option < ( u8 , bool ) > {
1535+ match ty {
1536+ HirType :: I8 => Some ( ( 8 , true ) ) ,
1537+ HirType :: I16 => Some ( ( 16 , true ) ) ,
1538+ HirType :: I32 => Some ( ( 32 , true ) ) ,
1539+ HirType :: I64 => Some ( ( 64 , true ) ) ,
1540+ HirType :: I128 => Some ( ( 128 , true ) ) ,
1541+ HirType :: U8 => Some ( ( 8 , false ) ) ,
1542+ HirType :: U16 => Some ( ( 16 , false ) ) ,
1543+ HirType :: U32 => Some ( ( 32 , false ) ) ,
1544+ HirType :: U64 => Some ( ( 64 , false ) ) ,
1545+ HirType :: U128 => Some ( ( 128 , false ) ) ,
1546+ _ => None ,
1547+ }
1548+ }
1549+
1550+ fn float_type_width ( ty : & HirType ) -> Option < u8 > {
1551+ match ty {
1552+ HirType :: F32 => Some ( 32 ) ,
1553+ HirType :: F64 => Some ( 64 ) ,
1554+ _ => None ,
1555+ }
1556+ }
1557+
1558+ fn select_cast_op ( & self , source_ty : & HirType , target_ty : & HirType ) -> CastOp {
1559+ use CastOp :: * ;
1560+
1561+ if source_ty == target_ty {
1562+ return Bitcast ;
1563+ }
1564+
1565+ if let ( Some ( ( src_bits, src_signed) ) , Some ( ( dst_bits, _dst_signed) ) ) = (
1566+ Self :: int_type_width_and_sign ( source_ty) ,
1567+ Self :: int_type_width_and_sign ( target_ty) ,
1568+ ) {
1569+ if src_bits > dst_bits {
1570+ return Trunc ;
1571+ }
1572+ if src_bits < dst_bits {
1573+ return if src_signed { SExt } else { ZExt } ;
1574+ }
1575+ return Bitcast ;
1576+ }
1577+
1578+ if let ( Some ( src_bits) , Some ( dst_bits) ) = (
1579+ Self :: float_type_width ( source_ty) ,
1580+ Self :: float_type_width ( target_ty) ,
1581+ ) {
1582+ if src_bits < dst_bits {
1583+ return FpExt ;
1584+ }
1585+ if src_bits > dst_bits {
1586+ return FpTrunc ;
1587+ }
1588+ return Bitcast ;
1589+ }
1590+
1591+ if let ( Some ( ( _src_bits, src_signed) ) , Some ( _dst_float_bits) ) = (
1592+ Self :: int_type_width_and_sign ( source_ty) ,
1593+ Self :: float_type_width ( target_ty) ,
1594+ ) {
1595+ return if src_signed { SiToFp } else { UiToFp } ;
1596+ }
1597+
1598+ if let ( Some ( _src_float_bits) , Some ( ( _dst_bits, dst_signed) ) ) = (
1599+ Self :: float_type_width ( source_ty) ,
1600+ Self :: int_type_width_and_sign ( target_ty) ,
1601+ ) {
1602+ return if dst_signed { FpToSi } else { FpToUi } ;
1603+ }
1604+
1605+ match ( source_ty, target_ty) {
1606+ ( HirType :: Ptr ( _) , HirType :: I64 | HirType :: U64 ) => PtrToInt ,
1607+ ( HirType :: I64 | HirType :: U64 , HirType :: Ptr ( _) ) => IntToPtr ,
1608+ _ => Bitcast ,
1609+ }
1610+ }
1611+
15341612 /// Translate expression to SSA value
15351613 fn translate_expression (
15361614 & mut self ,
@@ -2535,17 +2613,10 @@ impl SsaBuilder {
25352613
25362614 TypedExpression :: Cast ( cast) => {
25372615 let operand_val = self . translate_expression ( block_id, & cast. expr ) ?;
2616+ let source_ty = self . convert_type ( & cast. expr . ty ) ;
25382617 let target_ty = self . convert_type ( & cast. target_type ) ;
25392618 let result = self . create_value ( target_ty. clone ( ) , HirValueKind :: Instruction ) ;
2540-
2541- // NOTE: Proper cast operation selection requires type information.
2542- // Should determine: IntToInt, IntToFloat, FloatToInt, FloatToFloat, Bitcast, etc.
2543- // Needs source type width, target type width, signedness information.
2544- //
2545- // WORKAROUND: Always uses Bitcast (works for pointer casts and same-size conversions)
2546- // FUTURE (v2.0): Add type-aware cast selection logic
2547- // Estimated effort: 4-5 hours (needs type width/signedness utilities)
2548- let cast_op = CastOp :: Bitcast ;
2619+ let cast_op = self . select_cast_op ( & source_ty, & target_ty) ;
25492620
25502621 self . add_instruction (
25512622 block_id,
0 commit comments