New lint: non_canonical_total_float_cmp#16817
Open
nik-rev wants to merge 1 commit intorust-lang:masterfrom
Open
New lint: non_canonical_total_float_cmp#16817nik-rev wants to merge 1 commit intorust-lang:masterfrom
non_canonical_total_float_cmp#16817nik-rev wants to merge 1 commit intorust-lang:masterfrom
Conversation
Collaborator
|
r? @llogiq rustbot has assigned @llogiq. Use Why was this reviewer chosen?The reviewer was selected based on:
|
465994e to
68aabe2
Compare
|
Lintcheck changes for 8438094
This comment will be updated if you push new changes |
68aabe2 to
6d44767
Compare
BenjaminBrienen
approved these changes
Apr 6, 2026
kpreid
suggested changes
Apr 6, 2026
Co-authored-by: Kevin Reid <kpreid@switchb.org>
1ff644b to
8438094
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Zulip discussion: https://rust-lang.zulipchat.com/#narrow/channel/257328-clippy/topic/lint.20.60float.2Epartial_cmp.28float2.29.2Eunwrap_or.28Ordering.3A.3ALess.29.60/with/536651326
What it does
Checks for manual attempts to force a total ordering on floating-point numbers by
using
.partial_cmp(..).unwrap_or(Ordering).Why is this bad?
Floating-point numbers do not have a total order by default because of [
NaN] values and the existence of both-0.0and0.0.When developers use
.unwrap_or(..)with [partial_cmp], they are usually trying to implement a total order manually, likely because they do not know about the existence of [total_cmp].However, such an attempt can never produce a correct total order.
For example, if a comparison function is given
(1.0, NaN)to compare, then, regardless of which [Ordering] it returns (other thanEqual), it must return the opposite ordering for(NaN, 1.0), which use ofunwrap_or()cannot do.In contexts like sorting or searching (e.g.,
BTreeMap), such an inconsistent ordering function can lead to non-deterministic results, infinite loops, or panics.While sorting is the most common place this pattern appears, it also affects any logic relying on a stable comparison, such as finding a minimum/maximum value in a collection.
Known problems
Performance: On some architectures (like x86),
total_cmpmay beslightly slower than hardware-accelerated float comparisons if the values
are already in floating-point registers.
Semantic Change:
total_cmpconsiders-0.0to be strictly less than0.0.If your logic relies on them being equal (the default behavior of
==),this lint's suggestion will change your program's behavior.
Example
Use instead:
AI Disclosure
I used gemini to help me write the "performance" section under "Known problems" in the lint's documentation.
changelog: [
non_canonical_total_float_cmp]: add lint