@@ -1518,9 +1518,97 @@ impl Evaluator<'_> {
15181518 self . size_of_sized ( target_ty, locals, "destination of int to int cast" ) ?;
15191519 Owned ( current[ 0 ..dest_size] . to_vec ( ) )
15201520 }
1521- CastKind :: FloatToInt => not_supported ! ( "float to int cast" ) ,
1522- CastKind :: FloatToFloat => not_supported ! ( "float to float cast" ) ,
1523- CastKind :: IntToFloat => not_supported ! ( "float to int cast" ) ,
1521+ CastKind :: FloatToInt => {
1522+ let ty = self . operand_ty ( operand, locals) ?;
1523+ let TyKind :: Scalar ( chalk_ir:: Scalar :: Float ( ty) ) = ty. kind ( Interner ) else {
1524+ not_supported ! ( "invalid float to int cast" ) ;
1525+ } ;
1526+ let value = self . eval_operand ( operand, locals) ?. get ( self ) ?;
1527+ let value = match ty {
1528+ chalk_ir:: FloatTy :: F32 => {
1529+ let value = value. try_into ( ) . unwrap ( ) ;
1530+ f32:: from_le_bytes ( value) as f64
1531+ }
1532+ chalk_ir:: FloatTy :: F64 => {
1533+ let value = value. try_into ( ) . unwrap ( ) ;
1534+ f64:: from_le_bytes ( value)
1535+ }
1536+ chalk_ir:: FloatTy :: F16 | chalk_ir:: FloatTy :: F128 => {
1537+ not_supported ! ( "unstable floating point type f16 and f128" ) ;
1538+ }
1539+ } ;
1540+ let is_signed = matches ! (
1541+ target_ty. kind( Interner ) ,
1542+ TyKind :: Scalar ( chalk_ir:: Scalar :: Int ( _) )
1543+ ) ;
1544+ let dest_size =
1545+ self . size_of_sized ( target_ty, locals, "destination of float to int cast" ) ?;
1546+ let dest_bits = dest_size * 8 ;
1547+ let ( max, min) = if dest_bits == 128 {
1548+ ( i128:: MAX , i128:: MIN )
1549+ } else if is_signed {
1550+ let max = 1i128 << ( dest_bits - 1 ) ;
1551+ ( max - 1 , -max)
1552+ } else {
1553+ ( 1i128 << dest_bits, 0 )
1554+ } ;
1555+ let value = ( value as i128 ) . min ( max) . max ( min) ;
1556+ let result = value. to_le_bytes ( ) ;
1557+ Owned ( result[ 0 ..dest_size] . to_vec ( ) )
1558+ }
1559+ CastKind :: FloatToFloat => {
1560+ let ty = self . operand_ty ( operand, locals) ?;
1561+ let TyKind :: Scalar ( chalk_ir:: Scalar :: Float ( ty) ) = ty. kind ( Interner ) else {
1562+ not_supported ! ( "invalid float to int cast" ) ;
1563+ } ;
1564+ let value = self . eval_operand ( operand, locals) ?. get ( self ) ?;
1565+ let value = match ty {
1566+ chalk_ir:: FloatTy :: F32 => {
1567+ let value = value. try_into ( ) . unwrap ( ) ;
1568+ f32:: from_le_bytes ( value) as f64
1569+ }
1570+ chalk_ir:: FloatTy :: F64 => {
1571+ let value = value. try_into ( ) . unwrap ( ) ;
1572+ f64:: from_le_bytes ( value)
1573+ }
1574+ chalk_ir:: FloatTy :: F16 | chalk_ir:: FloatTy :: F128 => {
1575+ not_supported ! ( "unstable floating point type f16 and f128" ) ;
1576+ }
1577+ } ;
1578+ let TyKind :: Scalar ( chalk_ir:: Scalar :: Float ( target_ty) ) =
1579+ target_ty. kind ( Interner )
1580+ else {
1581+ not_supported ! ( "invalid float to float cast" ) ;
1582+ } ;
1583+ match target_ty {
1584+ chalk_ir:: FloatTy :: F32 => Owned ( ( value as f32 ) . to_le_bytes ( ) . to_vec ( ) ) ,
1585+ chalk_ir:: FloatTy :: F64 => Owned ( ( value as f64 ) . to_le_bytes ( ) . to_vec ( ) ) ,
1586+ chalk_ir:: FloatTy :: F16 | chalk_ir:: FloatTy :: F128 => {
1587+ not_supported ! ( "unstable floating point type f16 and f128" ) ;
1588+ }
1589+ }
1590+ }
1591+ CastKind :: IntToFloat => {
1592+ let current_ty = self . operand_ty ( operand, locals) ?;
1593+ let is_signed = matches ! (
1594+ current_ty. kind( Interner ) ,
1595+ TyKind :: Scalar ( chalk_ir:: Scalar :: Int ( _) )
1596+ ) ;
1597+ let value = pad16 ( self . eval_operand ( operand, locals) ?. get ( self ) ?, is_signed) ;
1598+ let value = i128:: from_le_bytes ( value) ;
1599+ let TyKind :: Scalar ( chalk_ir:: Scalar :: Float ( target_ty) ) =
1600+ target_ty. kind ( Interner )
1601+ else {
1602+ not_supported ! ( "invalid int to float cast" ) ;
1603+ } ;
1604+ match target_ty {
1605+ chalk_ir:: FloatTy :: F32 => Owned ( ( value as f32 ) . to_le_bytes ( ) . to_vec ( ) ) ,
1606+ chalk_ir:: FloatTy :: F64 => Owned ( ( value as f64 ) . to_le_bytes ( ) . to_vec ( ) ) ,
1607+ chalk_ir:: FloatTy :: F16 | chalk_ir:: FloatTy :: F128 => {
1608+ not_supported ! ( "unstable floating point type f16 and f128" ) ;
1609+ }
1610+ }
1611+ }
15241612 CastKind :: FnPtrToPtr => not_supported ! ( "fn ptr to ptr cast" ) ,
15251613 } ,
15261614 } )
0 commit comments