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 wrapping stabilization #27755

Closed
aturon opened this issue Aug 12, 2015 · 14 comments · Fixed by #30943
Closed

Tracking issue for wrapping stabilization #27755

aturon opened this issue Aug 12, 2015 · 14 comments · Fixed by #30943
Labels
B-unstable Blocker: Implemented in the nightly compiler and unstable. final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@aturon
Copy link
Member

aturon commented Aug 12, 2015

The std::num::wrapping module provides a trait, OverflowingOps, that permits overflowing arithmetic on primitive types and tells whether an overflow occurred.

Other methods, like saturating_add and wrapping_add, are included directly as inherent methods on these types.

It's not clear whether the overflowing_foo methods are useful, and if so, whether there's any reason for them to live on a trait. Ideally, if we kept them, they'd move onto the primitive types, and the wrapping module would be removed.

@aturon aturon added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. B-unstable Blocker: Implemented in the nightly compiler and unstable. labels Aug 12, 2015
@sfackler sfackler changed the title Tracking issee for wrapping stabilization Tracking issue for wrapping stabilization Aug 12, 2015
@petrochenkov
Copy link
Contributor

@bmastenbrook
Copy link

I'm currently using the overflowing_* operations in a specialized bignum implementation, and it's a bit of a bother that they aren't stable. Given that these are implemented via LLVM intrinsics, is there any good reason for them to be removed? If they're not going to be removed, is there any way I can contribute to the stabilization?

@aturon
Copy link
Member Author

aturon commented Dec 16, 2015

Nominating for discussion at libs team meeting.

@alexcrichton
Copy link
Member

🔔 This issue is now entering its final comment period for tweaked stabilization 🔔

In triage discussion yesterday it was decided that the trait in this module should move to inherent methods on all the primitives, and we should likely fill out all the checked_* and saturating_* methods as well. There are some missing (like saturating_mul or checked_neg), and making sure we've got a full suite everywhere would ensure consistency!

@alexcrichton alexcrichton added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed I-nominated labels Dec 17, 2015
@petrochenkov
Copy link
Contributor

I'd like to remind the libs team about existence of RFC 1218.
One of the main points of it is to stabilize integer casts together with other arithmetic operations.
A comment to the RFC, which I linked above, also suggests an alternative to making checked_* and friends inherent methods, namely traits like

// Possibly an unstable trait with stable methods
trait IntAdd<Rhs = Self>: Add<Rhs> {
    fn wrapping_add(self) -> Self::Output;
    fn checked_add(self) -> Option<Self::Output>;
    /* other add operations */
}

Casts can't be implemented as inherent methods without double dispatch through yet another trait. Arithmetic operations like checked_add can be inherent methods, if the operands are supposed to be always homogeneous, but I don't see motivation for preferring inherent methods to a trait in this case.
I'm against stabilizing arithmetic methods unless they are gathered together with casts and arranged in one coherent picture.

@glaebhoerl
Copy link
Contributor

@petrochenkov I don't see the reason for preferring inherent methods over traits either (maybe it's just not having to import the trait?), but given that the existing wrapping_op methods have already been stabilized as inherent methods, doing likewise for the others would at least be consistent.

@SimonSapin
Copy link
Contributor

Arithmetic operations like checked_add can be inherent methods, if the operands are supposed to be always homogeneous

Primitive numeric types only implement Add with homogeneous operands.

And yes, the advantage of inherent methods is to not require users to import the trait and not "pollute" the prelude.

@aturon
Copy link
Member Author

aturon commented Dec 21, 2015

To clarify, yes, part of the motivation of inherent methods was doing away with the large soup of traits we used to have (and as @SimonSapin says, this allows you to avoid an explicit import). For numerics, specifically, we tried to move in the direction of concrete types and inherent methods, leaving abstractions/numeric hierarchy to traits than can be built externally and perhaps added later.

This has been a general approach in the standard library: avoid premature abstraction. The trait system makes it easy to create abstractions after the fact, and we prefer to see strong use cases before committing to them.

Finally, as @glaebhoerl points out, the existing stable API surface already takes this approach.

I'm against stabilizing arithmetic methods unless they are gathered together with casts and arranged in one coherent picture.

Most arithmetic methods are already stable. I don't understand the concern about packaging them together; can you elaborate? As I mentioned above, we're shy about numeric abstractions, having tried several times before 1.0 to build a hierarchy, before ultimately ditching the whole thing. I continue to think this needs to be baked out of tree, and don't see why it can't be.

@petrochenkov
Copy link
Contributor

Ok, I've reviewed this again (I haven't touched my RFC or used these methods for a long time) and changed my position from "mildly against" to "don't care". Inherent methods don't prevent having equivalent trait methods in the future and inconsistencies between casts and other operators are not the end of the world.

@SimonSapin
Copy link
Contributor

This is maybe off-topic, but since casts were mentioned I’d like to have fallible casts like impl u64 { to_u32(self) -> Result<u32, ()>

@eddyb
Copy link
Member

eddyb commented Dec 23, 2015

Is there any reason why Wrapping<T> doesn't implement Neg?

@aturon
Copy link
Member Author

aturon commented Dec 31, 2015

@eddyb Not that I know of. Probably just an oversight.

@huonw
Copy link
Member

huonw commented Jan 8, 2016

cc #23975

alexcrichton added a commit to alexcrichton/rust that referenced this issue Jan 12, 2016
This commit migrates all of the methods on `num::wrapping::OverflowingOps` onto
inherent methods of the integer types. This also fills out some missing gaps in
the saturating and checked departments such as:

* `saturating_mul`
* `checked_{neg,rem,shl,shr}`

This is done in preparation for stabilization,

cc rust-lang#27755
bors added a commit that referenced this issue Jan 14, 2016
This commit migrates all of the methods on `num::wrapping::OverflowingOps` onto
inherent methods of the integer types. This also fills out some missing gaps in
the saturating and checked departments such as:

* `saturating_mul`
* `checked_{neg,rem,shl,shr}`

This is done in preparation for stabilization,

cc #27755
@alexcrichton
Copy link
Member

The libs team discussed this in triage recently and the decision was to stabilize

alexcrichton added a commit to alexcrichton/rust that referenced this issue Jan 16, 2016
This commit stabilizes and deprecates the FCP (final comment period) APIs for
the upcoming 1.7 beta release. The specific APIs which changed were:

Stabilized

* `Path::strip_prefix` (renamed from `relative_from`)
* `path::StripPrefixError` (new error type returned from `strip_prefix`)
* `Ipv4Addr::is_loopback`
* `Ipv4Addr::is_private`
* `Ipv4Addr::is_link_local`
* `Ipv4Addr::is_multicast`
* `Ipv4Addr::is_broadcast`
* `Ipv4Addr::is_documentation`
* `Ipv6Addr::is_unspecified`
* `Ipv6Addr::is_loopback`
* `Ipv6Addr::is_unique_local`
* `Ipv6Addr::is_multicast`
* `Vec::as_slice`
* `Vec::as_mut_slice`
* `String::as_str`
* `String::as_mut_str`
* `<[T]>::clone_from_slice` - the `usize` return value is removed
* `<[T]>::sort_by_key`
* `i32::checked_rem` (and other signed types)
* `i32::checked_neg` (and other signed types)
* `i32::checked_shl` (and other signed types)
* `i32::checked_shr` (and other signed types)
* `i32::saturating_mul` (and other signed types)
* `i32::overflowing_add` (and other signed types)
* `i32::overflowing_sub` (and other signed types)
* `i32::overflowing_mul` (and other signed types)
* `i32::overflowing_div` (and other signed types)
* `i32::overflowing_rem` (and other signed types)
* `i32::overflowing_neg` (and other signed types)
* `i32::overflowing_shl` (and other signed types)
* `i32::overflowing_shr` (and other signed types)
* `u32::checked_rem` (and other unsigned types)
* `u32::checked_neg` (and other unsigned types)
* `u32::checked_shl` (and other unsigned types)
* `u32::saturating_mul` (and other unsigned types)
* `u32::overflowing_add` (and other unsigned types)
* `u32::overflowing_sub` (and other unsigned types)
* `u32::overflowing_mul` (and other unsigned types)
* `u32::overflowing_div` (and other unsigned types)
* `u32::overflowing_rem` (and other unsigned types)
* `u32::overflowing_neg` (and other unsigned types)
* `u32::overflowing_shl` (and other unsigned types)
* `u32::overflowing_shr` (and other unsigned types)
* `ffi::IntoStringError`
* `CString::into_string`
* `CString::into_bytes`
* `CString::into_bytes_with_nul`
* `From<CString> for Vec<u8>`
* `From<CString> for Vec<u8>`
* `IntoStringError::into_cstring`
* `IntoStringError::utf8_error`
* `Error for IntoStringError`

Deprecated

* `Path::relative_from` - renamed to `strip_prefix`
* `Path::prefix` - use `components().next()` instead
* `os::unix::fs` constants - moved to the `libc` crate
* `fmt::{radix, Radix, RadixFmt}` - not used enough to stabilize
* `IntoCow` - conflicts with `Into` and may come back later
* `i32::{BITS, BYTES}` (and other integers) - not pulling their weight
* `DebugTuple::formatter` - will be removed
* `sync::Semaphore` - not used enough and confused with system semaphores

Closes rust-lang#23284
cc rust-lang#27709 (still lots more methods though)
Closes rust-lang#27712
Closes rust-lang#27722
Closes rust-lang#27728
Closes rust-lang#27735
Closes rust-lang#27729
Closes rust-lang#27755
Closes rust-lang#27782
Closes rust-lang#27798
Manishearth added a commit to Manishearth/rust that referenced this issue Jan 17, 2016
This commit stabilizes and deprecates the FCP (final comment period) APIs for
the upcoming 1.7 beta release. The specific APIs which changed were:

Stabilized

* `Path::strip_prefix` (renamed from `relative_from`)
* `path::StripPrefixError` (new error type returned from `strip_prefix`)
* `Ipv4Addr::is_loopback`
* `Ipv4Addr::is_private`
* `Ipv4Addr::is_link_local`
* `Ipv4Addr::is_multicast`
* `Ipv4Addr::is_broadcast`
* `Ipv4Addr::is_documentation`
* `Ipv6Addr::is_unspecified`
* `Ipv6Addr::is_loopback`
* `Ipv6Addr::is_unique_local`
* `Ipv6Addr::is_multicast`
* `Vec::as_slice`
* `Vec::as_mut_slice`
* `String::as_str`
* `String::as_mut_str`
* `<[T]>::clone_from_slice` - the `usize` return value is removed
* `<[T]>::sort_by_key`
* `i32::checked_rem` (and other signed types)
* `i32::checked_neg` (and other signed types)
* `i32::checked_shl` (and other signed types)
* `i32::checked_shr` (and other signed types)
* `i32::saturating_mul` (and other signed types)
* `i32::overflowing_add` (and other signed types)
* `i32::overflowing_sub` (and other signed types)
* `i32::overflowing_mul` (and other signed types)
* `i32::overflowing_div` (and other signed types)
* `i32::overflowing_rem` (and other signed types)
* `i32::overflowing_neg` (and other signed types)
* `i32::overflowing_shl` (and other signed types)
* `i32::overflowing_shr` (and other signed types)
* `u32::checked_rem` (and other unsigned types)
* `u32::checked_shl` (and other unsigned types)
* `u32::saturating_mul` (and other unsigned types)
* `u32::overflowing_add` (and other unsigned types)
* `u32::overflowing_sub` (and other unsigned types)
* `u32::overflowing_mul` (and other unsigned types)
* `u32::overflowing_div` (and other unsigned types)
* `u32::overflowing_rem` (and other unsigned types)
* `u32::overflowing_neg` (and other unsigned types)
* `u32::overflowing_shl` (and other unsigned types)
* `u32::overflowing_shr` (and other unsigned types)
* `ffi::IntoStringError`
* `CString::into_string`
* `CString::into_bytes`
* `CString::into_bytes_with_nul`
* `From<CString> for Vec<u8>`
* `From<CString> for Vec<u8>`
* `IntoStringError::into_cstring`
* `IntoStringError::utf8_error`
* `Error for IntoStringError`

Deprecated

* `Path::relative_from` - renamed to `strip_prefix`
* `Path::prefix` - use `components().next()` instead
* `os::unix::fs` constants - moved to the `libc` crate
* `fmt::{radix, Radix, RadixFmt}` - not used enough to stabilize
* `IntoCow` - conflicts with `Into` and may come back later
* `i32::{BITS, BYTES}` (and other integers) - not pulling their weight
* `DebugTuple::formatter` - will be removed
* `sync::Semaphore` - not used enough and confused with system semaphores

Closes rust-lang#23284
cc rust-lang#27709 (still lots more methods though)
Closes rust-lang#27712
Closes rust-lang#27722
Closes rust-lang#27728
Closes rust-lang#27735
Closes rust-lang#27729
Closes rust-lang#27755
Closes rust-lang#27782
Closes rust-lang#27798
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B-unstable Blocker: Implemented in the nightly compiler and unstable. final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants