@@ -799,10 +799,18 @@ mod text_value_tests {
799799/// `#[derive(sqlx::Type)]` + `#[sqlx(transparent)]` already generates the
800800/// delegating `Type` AND `Decode` (and `Encode`) impls for the newtype, so we do
801801/// NOT also `#[derive(sqlx::Decode)]` — that would be a conflicting impl.
802- #[ derive( Debug , Clone , Copy , PartialEq , sqlx:: Type ) ]
802+ #[ derive( Debug , Clone , Copy , sqlx:: Type ) ]
803803#[ sqlx( transparent) ]
804804pub struct F4 ( pub f32 ) ;
805805
806+ // `PartialEq` is hand-written via `total_cmp` (not derived) so it stays
807+ // consistent with the `Ord`/`Eq` impls below: derived IEEE equality breaks
808+ // `Eq`'s reflexivity for NaN and disagrees with `total_cmp` on signed zero.
809+ impl PartialEq for F4 {
810+ fn eq ( & self , other : & Self ) -> bool {
811+ self . 0 . total_cmp ( & other. 0 ) == std:: cmp:: Ordering :: Equal
812+ }
813+ }
806814impl Eq for F4 { }
807815impl Ord for F4 {
808816 fn cmp ( & self , other : & Self ) -> std:: cmp:: Ordering {
@@ -830,10 +838,16 @@ impl std::fmt::Display for F4 {
830838/// `double precision`, `Default = F8(0.0)`. Like `F4`, the transparent
831839/// `sqlx::Type` derive also supplies `Decode`/`Encode`, so they are not derived
832840/// separately.
833- #[ derive( Debug , Clone , Copy , PartialEq , sqlx:: Type ) ]
841+ #[ derive( Debug , Clone , Copy , sqlx:: Type ) ]
834842#[ sqlx( transparent) ]
835843pub struct F8 ( pub f64 ) ;
836844
845+ // `PartialEq` is hand-written via `total_cmp` (not derived); see `F4` above.
846+ impl PartialEq for F8 {
847+ fn eq ( & self , other : & Self ) -> bool {
848+ self . 0 . total_cmp ( & other. 0 ) == std:: cmp:: Ordering :: Equal
849+ }
850+ }
837851impl Eq for F8 { }
838852impl Ord for F8 {
839853 fn cmp ( & self , other : & Self ) -> std:: cmp:: Ordering {
0 commit comments