Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking Issue for arithmetic that panics on overflow (strict_* operations) #118260

Open
1 of 5 tasks
rmehri01 opened this issue Nov 24, 2023 · 4 comments
Open
1 of 5 tasks
Labels
C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@rmehri01
Copy link
Contributor

rmehri01 commented Nov 24, 2023

Feature gate: #![feature(strict_overflow_ops)]

This is a tracking issue for doing arithmetic that is guaranteed to panic on overflow, see the ACP for more details: rust-lang/libs-team#270.

Public API

For both signed and unsigned integers:

pub const fn strict_add(self, rhs: Self) -> Self;
pub const fn strict_sub(self, rhs: Self) -> Self;
pub const fn strict_mul(self, rhs: Self) -> Self;
pub const fn strict_div(self, rhs: Self) -> Self;
pub const fn strict_div_euclid(self, rhs: Self) -> Self;
pub const fn strict_rem(self, rhs: Self) -> Self;
pub const fn strict_rem_euclid(self, rhs: Self) -> Self;
pub const fn strict_neg(self) -> Self;
pub const fn strict_shl(self, rhs: u32) -> Self;
pub const fn strict_shr(self, rhs: u32) -> Self;
pub const fn strict_pow(self, exp: u32) -> Self;

Additionally, signed integers have:

pub const fn strict_add_unsigned(self, rhs: $UnsignedT) -> Self;
pub const fn strict_sub_unsigned(self, rhs: $UnsignedT) -> Self;
pub const fn strict_abs(self) -> Self;

And unsigned integers have:

pub const fn strict_add_signed(self, rhs: $SignedT) -> Self;

Steps / History

Unresolved Questions

  • Should we have strict_neg on unsigned types? It's basically identical to assert_ne!(x, 0).
  • Should we have strict_div, strict_rem, strict_div_euclid and strict_rem_euclid on unsigned types? Those will never panic; they are identical to the non-strict versions.

Footnotes

  1. https://std-dev-guide.rust-lang.org/feature-lifecycle/stabilization.html

@rmehri01 rmehri01 added C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Nov 24, 2023
@tspiteri
Copy link
Contributor

tspiteri commented Mar 9, 2024

I have implemented something similar to this in the fixed crate, for example FixedI32::unwrapped_add, together with an Unwrapped wrapper similar to Wrapping and Saturating.

I used the prefix unwrapped_ as I thought it can be interpreted mainly (a) as checked followed by unwrap, so that it is unwrapped, but also kinda (b) as not wrapping, since panicking is done instead of wrapping. I found this double interpretation amusing, which is why I stuck with that prefix.

@daira
Copy link
Contributor

daira commented Jun 3, 2024

Should we have strict_neg on unsigned types? It's basically identical to assert_ne!(x, 0).

You mean assert_eq!(x, 0). And no, it's pointless.

@thaliaarchi
Copy link
Contributor

thaliaarchi commented Nov 23, 2024

I'm interested in contributing to fix issues with this or championing stabilization. (However, I haven't stabilized something before.)

  • I think unsigned checked_neg should be included. Although it's not terribly useful on it's own, there's a precedent for including it and it smooths out macro polymorphism. Unsigned checked_neg is stable with the same triviality. (Unsigned wrapping_neg and overflowing_neg use wrapping operations.)

  • strict_{div,rem}_{ceil,floor} should be implemented for consistency.

    However, there still large gaps in division and modulo rounding for the other operations (Tracking Issue for int_roundings #88581): rem_{ceil,floor}, {checked,overflowing,strict,wrapping}_{div,rem}_{ceil,floor}, saturating_rem, saturating_{div,rem}_{ceil,euclid,floor} are not implemented. If the implementation of the strict ones is not straightforward, punting that to another PR with the others might make sense. I wrote a document tracking rounding of division and modulo operations across languages, which may be useful.

  • I agree a Strict<T> wrapper would be good (in another PR).

What would a good next step be?

@pascaldekloe
Copy link

Any redundant strict_ methods on unsigned types can help with programming generics and traits sometimes. Considering the utilization of such primitives, that "sometimes" may add up to a huge number of usecases.

I'd love to see even better support for checked on language level like Zig does. For example, Rust could read +? as checked add, +| as saturating add, and +% as overflowing add.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants