Make Signed::abs match its documented behavior for ::MIN - #380
Open
tautschnig wants to merge 2 commits into
Open
Make Signed::abs match its documented behavior for ::MIN#380tautschnig wants to merge 2 commits into
tautschnig wants to merge 2 commits into
Conversation
The trait documentation states: "For signed integers, ::MIN will be returned if the number is ::MIN." The implementation used unary negation, which panics with 'attempt to negate with overflow' when overflow checks are enabled (debug builds), so the documented behavior only held in release builds. Use wrapping_abs, which implements the documented semantics in both profiles. Also document the overflow behavior of abs_sub for signed integers (e.g. MAX.abs_sub(&-1) is not representable): it panics with overflow checks enabled and wraps otherwise. Found by running Kani's autoharness (model-checking/kani#3832) over num-traits: the generated harness for abs::<i32> reported the negate overflow reachable at sign.rs. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Updates Signed::abs for primitive signed integers to match the trait’s documented ::MIN behavior in debug (overflow-checking) builds, and adds a regression test to prevent reintroducing the overflow panic.
Changes:
- Switch primitive signed integer
Signed::absimplementation from negation towrapping_absto avoid::MINnegate overflow panics. - Add a regression test ensuring
abs(::MIN) == ::MINacross signed integer primitives and thesign::abshelper. - Document the overflow behavior of
Signed::abs_subfor signed integers when the difference is not representable.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+21
to
+23
| /// For signed integers, the difference may not be representable (e.g. | ||
| /// `MAX.abs_sub(&-1)`), in which case the subtraction overflows: it panics when overflow | ||
| /// checks are enabled and wraps around otherwise. |
Review feedback: MAX.abs_sub(&-1) is ambiguous without a concrete integer type; use i32::MAX so the example can be read (and copied) unmodified. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
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
Signedtrait documentation states: "For signed integers,::MINwill be returned if the number is::MIN." The primitive implementations use unary negation, which panics with "attempt to negate with overflow" when overflow checks are enabled (debug builds):This PR switches the implementation to
wrapping_abs, which implements the documented semantics in both build profiles, and adds a regression test (which runs with overflow checks enabled by default, so it would panic without the fix).It also documents the overflow behavior of
abs_subfor signed integers (e.g.i32::MAX.abs_sub(&-1)is not representable), which panics with overflow checks enabled and wraps otherwise; changing that behavior (e.g. saturating) seemed like a semantic decision better left to the maintainers, so this PR only documents it.Found by running Kani's autoharness (model-checking/kani#3832) over the crate: the generated harness for
abs::<i32>reported the negate-overflow panic reachable; reproduced with plain cargo (no Kani involved) before filing.