Skip to content

Tracking Issue for exact_div #139911

Description

@newpavlov

View all comments

Feature gate: #![feature(exact_div)]

This is a tracking issue for exact division methods (i.e. for division without remainder) on primitive integer types.

Public API

/// Checked integer division without remainder. Computes `self / rhs`,
/// returning `None` if `rhs == 0` or if division remainder is not zero.
pub const fn checked_exact_div(self, rhs: Self) -> Option<Self> { ... }

/// Integer division without remainder. Computes `self / rhs`,
/// panics if `rhs == 0` or if division remainder is not zero.
pub const fn exact_div(self, rhs: Self) -> Self { ... }

/// Integer division without remainder.
/// Unchecked version of `exact_div`.
pub unsafe const fn unchecked_exact_div(self, rhs: Self) -> Self { ... }

Steps / History

Unresolved Questions

Activity

  1. added
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    T-libs-api[DEPRECATED; DO NOT USE]
    on Apr 16, 2025
  2. hanna-kruppe commented on Apr 16, 2025

    @hanna-kruppe
    Contributor

    How do these handle overflow (iN::MIN / -1)?

  3. newpavlov commented on Apr 16, 2025

    @newpavlov
    ContributorAuthor

    They return None/panic/cause UB respectively, see here.

  4. hanna-kruppe commented on Apr 16, 2025

    @hanna-kruppe
    Contributor

    For the safe version this makes sense but for unchecked_exact_div it’s not obvious to me that UB is the right choice. Having three distinct preconditions to check (no remainder, no division by zero, no overflow) is not great because it’s easy to forget one, especially the overflow edge case. Even for unsigned types, the precedent in stable Rust is handling division by zero via impl Div<NonZeroT> for T instead of an unsafe method that’s UB on zero RHS. This may be useful in this case as well. And overflow in signed division could panic even if the “no remainder” portion is unchecked under threat of UB.

  5. newpavlov commented on Apr 16, 2025

    @newpavlov
    ContributorAuthor

    The unsafe variant would be a simple wrapper around the exact_div intrinsic.

  6. hanna-kruppe commented on Apr 16, 2025

    @hanna-kruppe
    Contributor

    Just because the perma-unstable intrinsic works this way doesn’t mean it’s also the best option for a stable user-facing API. We also have an unchecked_div intrinsic but as noted in my last comment, it’s not exposed as-is.

  7. newpavlov commented on Apr 16, 2025

    @newpavlov
    ContributorAuthor

    Any other behavior would be surprising. You could argue that we don't need unchecked_exact_div methods similarly to how we don't have unchecked_div, but there was an explicit interest in it during previous discussion. Personally, I think we should add unchecked_div methods instead.

  8. hanna-kruppe commented on Apr 16, 2025

    @hanna-kruppe
    Contributor

    I’m not here to argue about whether the functionality is needed, just point out that there’s other ways to expose it that may be better (easier to use correctly), at least for unsigned integers. Similarly , there’s no need to add unsafe unchecked_div methods for unsigned integers because the safe Div implementations already achieves the same effect (those impls use the unchecked_div intrinsic internally, and callers that need to unsafely assert that the RHS is non-zero can combine it with NonZero::new_unchecked), and unchecked_div for signed integers could also take a NonZero RHS and only require callers to check the “no overflow” condition.

  9. abgros commented on Apr 16, 2025

    @abgros

    For the safe version this makes sense but for unchecked_exact_div it’s not obvious to me that UB is the right choice. Having three distinct preconditions to check (no remainder, no division by zero, no overflow) is not great because it’s easy to forget one, especially the overflow edge case.

    No, there is only one unsafe precondition: a.exact_div_unchecked(b) is only allowed if there is a number c such that b * c == a (without overflow). The three cases are just a consequence of that.

    An "unchecked" method panicking on some inputs would be quite surprising.

  10. hanna-kruppe commented on Apr 16, 2025

    @hanna-kruppe
    Contributor

    This “single” precondition leaves a third of the work to the “(without overflow)” and isn’t even correct: a = b = 0 is UB but c = 0 satisfies b * c = a.

    In any case: even if there is some clever way to subsume all three conditions in a single one, that’s of little use to unsafe code authors if the generality makes it easy to overlook edge cases or difficult to connect to the concrete facts available at the call site.

  11. abgros commented on Apr 16, 2025

    @abgros

    This “single” precondition leaves a third of the work to the “(without overflow)” and isn’t even correct: a = b = 0 is UB but c = 0 satisfies b * c = a.

    You're right, it should be a unique number c.

  12. Amanieu commented on Apr 30, 2025

    @Amanieu
    Member

    This came up in the @rust-lang/libs-api meeting while discussing rust-lang/libs-team#570.

    We think that the unchecked version is valuable because it exposes the lowest-level primitive which others can build around. Only exposing higher-level wrappers can end up being harder for users to work with.

    However we did feel that there was little value to the panicking version, especially since it can be emulated by calling .unwrap() on the result of the checked version (which additionally has the advantage of making it clear this is a potential panic point). As such we would like the panicking version removed and the checked_ prefix to be removed on the checked version.

    Regarding naming, in the meeting there was a preference for exact_div and exact_div_unchecked, the reasoning being that unchecked_exact_div can be ambiguous as to whether "unchecked" refers just to "exact" or the entire "exact_div" operation.

  13. BurntSushi commented on Apr 30, 2025

    @BurntSushi
    Member

    I don't think I'm on board with the checked variant dropping the checked_ prefix. From my comment on the ACP:

    As of today, every single method on integer types (as far as I can see) that returns an Option starts with a checked_ prefix. I'm not one for a foolish consistency, but I think it makes sense here.

    We should just keep that prefix given how strong the convention already is.

    The other benefit of using the checked_ prefix is that it leaves room for adding the panicking variant in the future, should that become better motivated.

    Could the libs-api members who want to drop the checked_ prefix say more about that here?

  14. 39 remaining items

  15. added 2 commits that reference this issue on Nov 30, 2025
  16. Apersoma commented on Apr 24, 2026

    @Apersoma
    Contributor

    I think it would make sense to implement these on NonZero as well since x.exact_div(y) will never be zero if x is not zero.

  17. added 2 commits that reference this issue on Jun 24, 2026
  18. added a commit that references this issue on Jun 24, 2026
  19. added a commit that references this issue on Jun 25, 2026
  20. added
    T-libsRelevant to the library team, which will review and decide on the PR/issue.
    and removed
    T-libs-api[DEPRECATED; DO NOT USE]
    on Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCS-tracking-unimplementedStatus: The feature has not been implemented.T-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions