RUST-2471 Fix Eq implementation for Bson; extend Eq/Hash to raw types - #686
RUST-2471 Fix Eq implementation for Bson; extend Eq/Hash to raw types#686abr-egn wants to merge 1 commit into
Conversation
|
|
||
| impl std::hash::Hash for RawBson { | ||
| fn hash<H: std::hash::Hasher>(&self, state: &mut H) { | ||
| std::mem::discriminant(self).hash(state); |
There was a problem hiding this comment.
This is unrelated to the rest of the changes, but since we're changing the hash output (or adding it in the case of the raw types), this makes it behave a little better. Including the discriminant in the hash reduces collisions; previously, all the unit variants would hash equal, as would pairs like Bson::String("x") and Bson::Symbol("x").
| impl<'a> PartialEq for RawBsonRef<'a> { | ||
| fn eq(&self, other: &Self) -> bool { | ||
| match self { | ||
| Self::Double(s) => matches!(other, Self::Double(o) if s.to_bits() == o.to_bits()), |
There was a problem hiding this comment.
This slightly awkward construction means there doesn't need to be a fallthrough case like there would be for matching directly against (self, other), so we keep the compile-time exhaustiveness check.
| std::mem::discriminant(self).hash(state); | ||
| match self { | ||
| Bson::Double(double) => { | ||
| if *double == 0.0_f64 { |
There was a problem hiding this comment.
This special casing goes away because both equality and hash are just using the byte values.
RUST-2471
This changes the
Bsonimpl forPartialEqto compare by byte value rather than the derived comparison, which carried the float non-reflexive behavior and madeEqa lie. To keep things consistent, I updated the raw types to use the same comparison; this also meant making the raw types Eq/Hash was straightforward.Notably, the raw buffer types (
RawDocument[Buf],RawArray[Buf]) were already just comparing by byte value, so this change makes everything consistent rather than having an undocumented mismatch.Fixes #683, #684.