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
- Pros: You can implement
- 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
- Pros: You can implement
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.