[codec] Reject incomparable values in RangeCfg::contains - #4529
Open
memosr wants to merge 1 commit into
Open
Conversation
RangeCfg::contains used exclusion tests (value < s, value > e). Under a
partial order the negation of these is not inclusion, so a value that is
incomparable to both bounds escaped every arm and was reported as
contained.
Because the inherent method shadows RangeBounds::contains, the same
RangeCfg gave two different answers for the same value:
let cfg = RangeCfg::new(0.0f64..=1.0f64);
cfg.contains(&f64::NAN); // true
RangeBounds::contains(&cfg, &f64::NAN); // false
Switch to partial_cmp so incomparable values are explicitly rejected,
matching core's RangeBounds::contains. Behavior is unchanged for totally
ordered types, which covers every RangeCfg instantiation in the
workspace today.
Adds a regression test.
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.
The inherent
RangeCfg::containsis written as a pair of exclusion tests (value < s,value > e). Under a partial order the negation of "is less than" is not "is greater or equal", so a value incomparable to both bounds escapes every arm and is reported as contained.Since the inherent method shadows the one from the
RangeBoundsimpl, the sameRangeCfggives two different answers for the same value:coresRangeBounds::containsuses inclusion tests, which is why it gets this right.The bound on
RangeCfgisCopy + PartialOrd, soRangeCfg<f64>compiles today. I grepped the workspace and every current instantiation is an integer orNonZerotype, where the two definitions coincide, so this is latent rather than live. Filing it because the divergence is silently wrong for any futurePartialOrd-only type, and because the fix costs nothing for existing users.Fix: use
partial_cmpand treatNoneas out of range. This is also whatclippy::neg_cmp_op_on_partial_ordrecommends; the naive rewrite to!(s <= value)trips that lint, which exists for exactly this class of bug.Behavior is unchanged for totally ordered types. No wire format change.
Added
test_range_cfg_partial_ord_nan, which fails onmainand passes here.cargo test,cargo clippy --all-targets -- -D warnings,cargo fmt, andcargo check --no-default-featuresare all clean forcommonware-codec.