@@ -48,7 +48,7 @@ macro_rules! from_bytes {
48
48
( $ty: tt, $value: expr) => {
49
49
( $ty:: from_le_bytes( match ( $value) . try_into( ) {
50
50
Ok ( x) => x,
51
- Err ( _) => return Err ( MirEvalError :: TypeError ( " mismatched size" ) ) ,
51
+ Err ( _) => return Err ( MirEvalError :: TypeError ( stringify! ( mismatched size in constructing $ty ) ) ) ,
52
52
} ) )
53
53
} ;
54
54
}
@@ -797,70 +797,122 @@ impl Evaluator<'_> {
797
797
lc = self . read_memory ( Address :: from_bytes ( lc) ?, size) ?;
798
798
rc = self . read_memory ( Address :: from_bytes ( rc) ?, size) ?;
799
799
}
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
+ ) ,
844
828
}
845
829
}
846
- Owned ( r[ 0 ..lc. len ( ) ] . into ( ) )
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
+ ) ,
856
+ }
857
+ } ,
847
858
}
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" ) ,
862
915
}
863
- BinOp :: Offset => not_supported ! ( "offset binop" ) ,
864
916
}
865
917
}
866
918
Rvalue :: Discriminant ( p) => {
0 commit comments