Skip to content

Commit 58e0749

Browse files
committed
fix(v3): hand-write F4/F8 PartialEq via total_cmp for Eq/Ord consistency
Derived IEEE PartialEq (NaN != NaN, +0.0 == -0.0) was inconsistent with the manual Eq/Ord impls built on total_cmp (NaN == NaN, +0.0 != -0.0), breaking Eq's reflexivity contract and Ord/PartialEq equality agreement.
1 parent c78b7a4 commit 58e0749

1 file changed

Lines changed: 16 additions & 2 deletions

File tree

tests/sqlx/src/scalar_domains.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
804804
pub 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+
}
806814
impl Eq for F4 {}
807815
impl 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)]
835843
pub 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+
}
837851
impl Eq for F8 {}
838852
impl Ord for F8 {
839853
fn cmp(&self, other: &Self) -> std::cmp::Ordering {

0 commit comments

Comments
 (0)