Require const stability attribute on all stable functions that are `const`
This PR requires all stable functions (of all kinds) that are `const fn` to have a `#[rustc_const_stable]` or `#[rustc_const_unstable]` attribute. Stability was previously implied if omitted; a follow-up PR is planned to change the fallback to be unstable.
These are working well for *unsigned* types, for the the signed ones there are a bunch of questions about what the semantics and API should be. And for the main "helpers for big integer implementations" use, there's no need for the signed versions anyway.
And there are plenty of other methods which exist for unsigned types but not signed ones, like `next_power_of_two`, so this isn't unusual.
Fixes 90541
Using short-circuit operators makes it easier to perform some kinds of
source code analysis, like MC/DC code coverage (a requirement in
safety-critical environments). The optimized x86 assembly is the same
between the old and new versions:
```
xor eax, eax
test esi, esi
je .LBB0_1
cmp edi, -2147483648
jne .LBB0_4
cmp esi, -1
jne .LBB0_4
ret
.LBB0_1:
ret
.LBB0_4:
mov eax, edi
cdq
idiv esi
mov eax, 1
ret
```
Using short-circuit operators makes it easier to perform some kinds of
source code analysis, like MC/DC code coverage (a requirement in
safety-critical environments). The optimized x86 assembly is the same
between the old and new versions:
```
xor eax, eax
test esi, esi
je .LBB0_1
cmp edi, -2147483648
jne .LBB0_4
cmp esi, -1
jne .LBB0_4
ret
.LBB0_1:
ret
.LBB0_4:
mov eax, edi
cdq
idiv esi
mov edx, eax
mov eax, 1
ret
```
Stabilize feature `saturating_div` for rust 1.58.0
The tracking issue is #89381
This seems like a reasonable simple change(?). The feature `saturating_div` was added as part of the ongoing effort to implement a `Saturating` integer type (see #87921). The implementation has been discussed [here](https://github.com/rust-lang/rust/pull/87921#issuecomment-899357720) and [here](https://github.com/rust-lang/rust/pull/87921#discussion_r691888556). It extends the list of saturating operations on integer types (like `saturating_add`, `saturating_sub`, `saturating_mul`, ...) by the function `fn saturating_div(self, rhs: Self) -> Self`.
The stabilization of the feature `saturating_int_impl` (for the `Saturating` type) needs to have this stabilized first.
Closes#89381
Add #[must_use] to from_value conversions
I added two methods to the list myself. Clippy did not flag them because they take `mut` args, but neither modifies their argument.
```rust
core::str const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str;
std::ffi::CString unsafe fn from_raw(ptr: *mut c_char) -> CString;
```
I put a custom note on `from_raw`:
```rust
#[must_use = "call `drop(from_raw(ptr))` if you intend to drop the `CString`"]
pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
```
Parent issue: #89692
r? ``@joshtriplett``
Improve docs for int_log
* Clarify rounding.
* Avoid "wrapping" wording.
* Omit wrong claim on 0 only being returned in error cases.
* Typo fix for one_less_than_next_power_of_two.
Since the wrapped remainder is going to be 0 for all cases when the rhs is -1,
there is no need to divide in this case. Comparing the lhs with MIN is only done
for the overflow bool. In particular, this results in better code generation for
wrapping remainder, which discards the overflow bool completely.
For `self == Self::MIN && rhs == -1`, LLVM does not realize that this is the
same check made by `self / rhs`, so the code generated may have some unnecessary
duplication. For `(self == Self::MIN) & (rhs == -1)`, LLVM realizes it is the
same check.
These functions are unstable, but because they're inherent they still
introduce conflicts with stable trait functions in crates. Temporarily
rename them to fix these conflicts, until we can resolve those conflicts
in a better way.
* Clarify rounding.
* Avoid "wrapping" wording.
* Omit wrong claim on 0 only being returned in error cases.
* Typo fix for one_less_than_next_power_of_two.
Add carrying_add, borrowing_sub, widening_mul, carrying_mul methods to integers
This comes in part from my own attempts to make (crude) big integer implementations, and also due to the stalled discussion in [RFC 2417](https://github.com/rust-lang/rfcs/pull/2417). My understanding is that changes like these are best offered directly as code and then an RFC can be opened if there needs to be more discussion before stabilisation. Since all of these methods are unstable from the start, I figured I might as well offer them now.
I tried looking into intrinsics, messed around with a few different implementations, and ultimately concluded that these are "good enough" implementations for now to at least put up some code and maybe start bikeshedding on a proper API for these.
For the `carrying_add` and `borrowing_sub`, I tried looking into potential architecture-specific code and realised that even using the LLVM intrinsics for `addcarry` and `subborrow` on x86 specifically, I was getting exactly the same assembly as the naive implementation using `overflowing_add` and `overflowing_sub`, although the LLVM IR did differ because of the architecture-specific code. Longer-term I think that they would be best suited to specific intrinsics as that would make optimisations easier (instructions like add-carry tend to use implicit flags, and thus can only be optimised if they're done one-after-another, and thus it would make the most sense to have compact intrinsics that can be merged together easily).
For `widening_mul` and `carrying_mul`, for now at least, I simply cast to the larger type and perform arithmetic that way, since we currently have no intrinsic that would work better for 128-bit integers. In the future, I also think that some form of intrinsic would work best to cover that case, but for now at least, I think that they're "good enough" for now.
The main reasoning for offering these directly to the standard library even though they're relatively niche optimisations is to help ensure that the code generated for them is optimal. Plus, these operations alone aren't enough to create big integer implementations, although they could help simplify the code required to do so and make it a bit more accessible for the average implementor.
That said, I 100% understand if any or all of these methods are not desired simply because of how niche they are. Up to you. 🤷🏻
Make wrapping_neg() use wrapping_sub(), #[inline(always)]
This is a follow-up change to the fix for #75598. It simplifies the implementation of wrapping_neg() for all integer types by just calling 0.wrapping_sub(self) and always inlines it. This leads to much less assembly code being emitted for opt-level≤1 and thus much better performance for debug-compiled code.
Background is [this discussion on the internals forum](https://internals.rust-lang.org/t/why-does-rust-generate-10x-as-much-unoptimized-assembly-as-gcc/14930).
Document math behind MIN/MAX consts on integers
Currently the documentation for `[integer]::{MIN, MAX}` doesn't explain where the constants come from. This documents how the values of those constants are related to powers of 2.
This is a follow-up change to the fix for #75598. It simplifies the implementation of wrapping_neg() for all integer types by just calling 0.wrapping_sub(self) and always inlines it. This leads to much less assembly code being emitted for opt-level≤1.