Skip to content

Conversation

@Zabot
Copy link

@Zabot Zabot commented Jan 7, 2026

Following up discussion in #84

Previously we would call PartialOrd::partial_cmp implicilty using the overloaded comparison operators > and < when comparing priorities, despite the fact that P is required to be Ord. A well behaved implementation of partial_cmp is supposed to return Some(Ord::cmp(self, other)). That relationship is only a convention, so a misbehaved implementation may return None, which may cause the order items are popped from the queue to behave seemingly randomly.

We can be a bit more defensive here and instead always call Ord::cmp directly, ensuring that we never try to compare things that could possibly return None. In order to enforce this going forward I added a test that panics in the implementation for partial_cmp and exercised all of the code paths that might call it. This isn't perfect, since new callsites could be added, but I figure its probably good enough for now.

Not sure exactly how to version this, it's not a breaking change if your implementation of PartialOrd follows the convention, but if you don't it would be a breaking change, since we'd be using a different function for comparisons.

Previously we would call `PartialOrd::partial_cmp` implicilty using
the overloaded comparison operators `>` and `<` when comparing
priorities, despite the fact that P is required to be `Ord`. A well
behaved implementation of `partial_cmp` is supposed to return
`Some(Ord::cmp(self, other))`. That relationship is only a convention,
so a misbehaved implementation may return None, which may cause
the order items are popped from the queue to behave seemingly randomly.

We can be a bit more defensive here and instead always call `Ord::cmp`
directly, ensuring that we never try to compare things that could
possibly return `None`. In order to enforce this going forward I added
a test that panics in the implementation for partial_cmp and exercised
all of the code paths that might call it. This isn't perfect, since
new callsites could be added, but I figure its probably good enough for
now.

Not sure exactly how to version this, it's not a breaking change if you
implementation of `PartialOrd` follows the convention, but if you don't
it would be a breaking change, since we'd be using a different
function for comparisons.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant