@@ -48,7 +48,7 @@ macro_rules! from_bytes {
4848 ( $ty: tt, $value: expr) => {
4949 ( $ty:: from_le_bytes( match ( $value) . try_into( ) {
5050 Ok ( x) => x,
51- Err ( _) => return Err ( MirEvalError :: TypeError ( " mismatched size" ) ) ,
51+ Err ( _) => return Err ( MirEvalError :: TypeError ( stringify! ( mismatched size in constructing $ty ) ) ) ,
5252 } ) )
5353 } ;
5454}
@@ -797,70 +797,122 @@ impl Evaluator<'_> {
797797 lc = self . read_memory ( Address :: from_bytes ( lc) ?, size) ?;
798798 rc = self . read_memory ( Address :: from_bytes ( rc) ?, size) ?;
799799 }
800- let is_signed = matches ! ( ty. as_builtin( ) , Some ( BuiltinType :: Int ( _) ) ) ;
801- let l128 = i128:: from_le_bytes ( pad16 ( lc, is_signed) ) ;
802- let r128 = i128:: from_le_bytes ( pad16 ( rc, is_signed) ) ;
803- match op {
804- BinOp :: Ge | BinOp :: Gt | BinOp :: Le | BinOp :: Lt | BinOp :: Eq | BinOp :: Ne => {
805- let r = match op {
806- BinOp :: Ge => l128 >= r128,
807- BinOp :: Gt => l128 > r128,
808- BinOp :: Le => l128 <= r128,
809- BinOp :: Lt => l128 < r128,
810- BinOp :: Eq => l128 == r128,
811- BinOp :: Ne => l128 != r128,
812- _ => unreachable ! ( ) ,
813- } ;
814- let r = r as u8 ;
815- Owned ( vec ! [ r] )
816- }
817- BinOp :: BitAnd
818- | BinOp :: BitOr
819- | BinOp :: BitXor
820- | BinOp :: Add
821- | BinOp :: Mul
822- | BinOp :: Div
823- | BinOp :: Rem
824- | BinOp :: Sub => {
825- let r = match op {
826- BinOp :: Add => l128. overflowing_add ( r128) . 0 ,
827- BinOp :: Mul => l128. overflowing_mul ( r128) . 0 ,
828- BinOp :: Div => l128. checked_div ( r128) . ok_or_else ( || {
829- MirEvalError :: Panic ( format ! ( "Overflow in {op:?}" ) )
830- } ) ?,
831- BinOp :: Rem => l128. checked_rem ( r128) . ok_or_else ( || {
832- MirEvalError :: Panic ( format ! ( "Overflow in {op:?}" ) )
833- } ) ?,
834- BinOp :: Sub => l128. overflowing_sub ( r128) . 0 ,
835- BinOp :: BitAnd => l128 & r128,
836- BinOp :: BitOr => l128 | r128,
837- BinOp :: BitXor => l128 ^ r128,
838- _ => unreachable ! ( ) ,
839- } ;
840- let r = r. to_le_bytes ( ) ;
841- for & k in & r[ lc. len ( ) ..] {
842- if k != 0 && ( k != 255 || !is_signed) {
843- return Err ( MirEvalError :: Panic ( format ! ( "Overflow in {op:?}" ) ) ) ;
800+ if let TyKind :: Scalar ( chalk_ir:: Scalar :: Float ( f) ) = ty. kind ( Interner ) {
801+ match f {
802+ chalk_ir:: FloatTy :: F32 => {
803+ let l = from_bytes ! ( f32 , lc) ;
804+ let r = from_bytes ! ( f32 , rc) ;
805+ match op {
806+ BinOp :: Ge
807+ | BinOp :: Gt
808+ | BinOp :: Le
809+ | BinOp :: Lt
810+ | BinOp :: Eq
811+ | BinOp :: Ne => {
812+ let r = op. run_compare ( l, r) as u8 ;
813+ Owned ( vec ! [ r] )
814+ }
815+ BinOp :: Add | BinOp :: Sub | BinOp :: Mul | BinOp :: Div => {
816+ let r = match op {
817+ BinOp :: Add => l + r,
818+ BinOp :: Sub => l - r,
819+ BinOp :: Mul => l * r,
820+ BinOp :: Div => l / r,
821+ _ => unreachable ! ( ) ,
822+ } ;
823+ Owned ( r. to_le_bytes ( ) . into ( ) )
824+ }
825+ x => not_supported ! (
826+ "invalid binop {x:?} on floating point operators"
827+ ) ,
828+ }
829+ }
830+ chalk_ir:: FloatTy :: F64 => {
831+ let l = from_bytes ! ( f64 , lc) ;
832+ let r = from_bytes ! ( f64 , rc) ;
833+ match op {
834+ BinOp :: Ge
835+ | BinOp :: Gt
836+ | BinOp :: Le
837+ | BinOp :: Lt
838+ | BinOp :: Eq
839+ | BinOp :: Ne => {
840+ let r = op. run_compare ( l, r) as u8 ;
841+ Owned ( vec ! [ r] )
842+ }
843+ BinOp :: Add | BinOp :: Sub | BinOp :: Mul | BinOp :: Div => {
844+ let r = match op {
845+ BinOp :: Add => l + r,
846+ BinOp :: Sub => l - r,
847+ BinOp :: Mul => l * r,
848+ BinOp :: Div => l / r,
849+ _ => unreachable ! ( ) ,
850+ } ;
851+ Owned ( r. to_le_bytes ( ) . into ( ) )
852+ }
853+ x => not_supported ! (
854+ "invalid binop {x:?} on floating point operators"
855+ ) ,
844856 }
845857 }
846- Owned ( r[ 0 ..lc. len ( ) ] . into ( ) )
847858 }
848- BinOp :: Shl | BinOp :: Shr => {
849- let shift_amount = if r128 < 0 {
850- return Err ( MirEvalError :: Panic ( format ! ( "Overflow in {op:?}" ) ) ) ;
851- } else if r128 > 128 {
852- return Err ( MirEvalError :: Panic ( format ! ( "Overflow in {op:?}" ) ) ) ;
853- } else {
854- r128 as u8
855- } ;
856- let r = match op {
857- BinOp :: Shl => l128 << shift_amount,
858- BinOp :: Shr => l128 >> shift_amount,
859- _ => unreachable ! ( ) ,
860- } ;
861- Owned ( r. to_le_bytes ( ) [ 0 ..lc. len ( ) ] . into ( ) )
859+ } else {
860+ let is_signed = matches ! ( ty. as_builtin( ) , Some ( BuiltinType :: Int ( _) ) ) ;
861+ let l128 = i128:: from_le_bytes ( pad16 ( lc, is_signed) ) ;
862+ let r128 = i128:: from_le_bytes ( pad16 ( rc, is_signed) ) ;
863+ match op {
864+ BinOp :: Ge | BinOp :: Gt | BinOp :: Le | BinOp :: Lt | BinOp :: Eq | BinOp :: Ne => {
865+ let r = op. run_compare ( l128, r128) as u8 ;
866+ Owned ( vec ! [ r] )
867+ }
868+ BinOp :: BitAnd
869+ | BinOp :: BitOr
870+ | BinOp :: BitXor
871+ | BinOp :: Add
872+ | BinOp :: Mul
873+ | BinOp :: Div
874+ | BinOp :: Rem
875+ | BinOp :: Sub => {
876+ let r = match op {
877+ BinOp :: Add => l128. overflowing_add ( r128) . 0 ,
878+ BinOp :: Mul => l128. overflowing_mul ( r128) . 0 ,
879+ BinOp :: Div => l128. checked_div ( r128) . ok_or_else ( || {
880+ MirEvalError :: Panic ( format ! ( "Overflow in {op:?}" ) )
881+ } ) ?,
882+ BinOp :: Rem => l128. checked_rem ( r128) . ok_or_else ( || {
883+ MirEvalError :: Panic ( format ! ( "Overflow in {op:?}" ) )
884+ } ) ?,
885+ BinOp :: Sub => l128. overflowing_sub ( r128) . 0 ,
886+ BinOp :: BitAnd => l128 & r128,
887+ BinOp :: BitOr => l128 | r128,
888+ BinOp :: BitXor => l128 ^ r128,
889+ _ => unreachable ! ( ) ,
890+ } ;
891+ let r = r. to_le_bytes ( ) ;
892+ for & k in & r[ lc. len ( ) ..] {
893+ if k != 0 && ( k != 255 || !is_signed) {
894+ return Err ( MirEvalError :: Panic ( format ! ( "Overflow in {op:?}" ) ) ) ;
895+ }
896+ }
897+ Owned ( r[ 0 ..lc. len ( ) ] . into ( ) )
898+ }
899+ BinOp :: Shl | BinOp :: Shr => {
900+ let shift_amount = if r128 < 0 {
901+ return Err ( MirEvalError :: Panic ( format ! ( "Overflow in {op:?}" ) ) ) ;
902+ } else if r128 > 128 {
903+ return Err ( MirEvalError :: Panic ( format ! ( "Overflow in {op:?}" ) ) ) ;
904+ } else {
905+ r128 as u8
906+ } ;
907+ let r = match op {
908+ BinOp :: Shl => l128 << shift_amount,
909+ BinOp :: Shr => l128 >> shift_amount,
910+ _ => unreachable ! ( ) ,
911+ } ;
912+ Owned ( r. to_le_bytes ( ) [ 0 ..lc. len ( ) ] . into ( ) )
913+ }
914+ BinOp :: Offset => not_supported ! ( "offset binop" ) ,
862915 }
863- BinOp :: Offset => not_supported ! ( "offset binop" ) ,
864916 }
865917 }
866918 Rvalue :: Discriminant ( p) => {
0 commit comments