Skip to content

Widget states do not implement `Eq` thus not ensuring reflexivity

Topic

Currently the Pane struct is only required to implement the PartialEq trait. This is a problem, it means it's not guaranteed that two identical layouts results equivalent in a comparison.

Context

The difference between PartialEq and Eq is described in the following table:

Property PartialEq Eq Description
Reflexivity a = a
Symmetricity a = b \implies b = a
Transitivity a = b \land b = c \implies a = c

The problem stems from floating point numbers that do not have a full equivalence relation (the IEEE 754 standard defines that \text{NaN} \neq \text{NaN}).

While this has not caused any issues so far, it remains formally incorrect.

Possible solutions

  • Use a wrapper type that provides total equality for floats (e.g., from crates like ordered_float)
    • Pros: You can implement Eq via derive macro and there are no chance of error from developers
    • Cons: Developers need to wrap floating point variables (e.g. with NotNan<T>) and you lose IEEE-754 compliance
  • Accept PartialEq only, and document the limitation
    • Pros: Status quo, there nothing to modify
    • Cons: Reflexivity is not guaranteed
  • Exclude floating-point fields from equality checks
    • Pros: You can implement Eq via derive macro and you keep IEE-754 compliance
    • Cons: You lose floating point variables

The first is probably the best tradeoff. The ordered_float create provides the NotNan wrapper that ensures \text{NaN} values cannot be stored. It is reasonable to require layouts not to store \text{NaN} values and for developers to use NotNan. The main drawback would be that if NotNan encounters a \text{NaN} value the program will panic.