rust/library/core/src
bors d117b7f211 Auto merge of #132195 - clarfonthey:bigint-mul, r=scottmcm
Tidy up bigint multiplication methods

This tidies up the library version of the bigint multiplication methods after the addition of the intrinsics in #133663. It follows [this summary](https://github.com/rust-lang/rust/issues/85532#issuecomment-2403442775) of what's desired for these methods.

Note that, if `2H = N`, then `uH::MAX * uH::MAX + uH::MAX + uH::MAX` is `uN::MAX`, and that we can effectively add two "carry" values without overflowing.

For ease of terminology, the "low-order" or "least significant" or "wrapping" half of multiplication will be called the low part, and the "high-order" or "most significant" or "overflowing" half of multiplication will be called the high part. In all cases, the return convention is `(low, high)` and left unchanged by this PR, to be litigated later.

## API Changes

The original API:

```rust
impl uN {
    // computes self * rhs
    pub const fn widening_mul(self, rhs: uN) -> (uN, uN);

    // computes self * rhs + carry
    pub const fn carrying_mul(self, rhs: uN, carry: uN) -> (uN, uN);
}
```

The added API:

```rust
impl uN {
    // computes self * rhs + carry1 + carry2
    pub const fn carrying2_mul(self, rhs: uN, carry: uN, add: uN) -> (uN, uN);
}
impl iN {
    // note that the low part is unsigned
    pub const fn widening_mul(self, rhs: iN) -> (uN, iN);
    pub const fn carrying_mul(self, rhs: iN, carry: iN) -> (uN, iN);
    pub const fn carrying_mul_add(self, rhs: iN, carry: iN, add: iN) -> (uN, iN);
}
```

Additionally, a naive implementation has been added for `u128` and `i128` since there are no double-wide types for those. Eventually, an intrinsic will be added to make these more efficient, but rather than doing this all at once, the library changes are added first.

## Justifications for API

The unsigned parts are done to ensure consistency with overflowing addition: for a two's complement integer, you want to have unsigned overflow semantics for all parts of the integer except the highest one. This is because overflow for unsigned integers happens on the highest bit (from `MAX` to zero), whereas overflow for signed integers happens on the second highest bit (from `MAX` to `MIN`). Since the sign information only matters in the highest part, we use unsigned overflow for everything but that part.

There is still discussion on the merits of signed bigint *addition* methods, since getting the behaviour right is very subtle, but at least for signed bigint *multiplication*, the sign of the operands does make a difference. So, it feels appropriate that at least until we've nailed down the final API, there should be an option to do signed versions of these methods.

Additionally, while it's unclear whether we need all three versions of bigint multiplication (widening, carrying-1, and carrying-2), since it's possible to have up to two carries without overflow, there should at least be a method to allow that. We could potentially only offer the carry-2 method and expect that adding zero carries afterword will optimise correctly, but again, this can be litigated before stabilisation.

## Note on documentation

While a lot of care was put into the documentation for the `widening_mul` and `carrying_mul` methods on unsigned integers, I have not taken this same care for `carrying_mul_add` or the signed versions. While I have updated the doc tests to be more appropriate, there will likely be many documentation changes done before stabilisation.

## Note on tests

Alongside this change, I've added several tests to ensure that these methods work as expected. These are alongside the codegen tests for the intrinsics.
2024-12-31 18:49:36 +00:00
..
alloc stabilize const_alloc_layout 2024-12-25 19:28:52 +01:00
array Add '<[T]>::as_array', '<[T]>::as_mut_array', '<*const [T]>::as_array', and '<*mut [T]>::as_mut_array' conversion methods; 2024-11-26 21:49:28 +01:00
ascii Add more precondition check tests 2024-10-09 19:34:27 -04:00
async_iter Reformat using the new identifier sorting from rustfmt 2024-09-22 19:11:29 -04:00
cell Less unwrap() in documentation 2024-12-21 01:26:47 +00:00
char update cfgs 2024-11-27 15:14:54 +00:00
clone CloneToUninit: use a private specialization trait 2024-07-29 20:44:43 +03:00
cmp Use generic NonZero everywhere in core. 2024-02-22 15:17:33 +01:00
convert rustdoc-search: let From and Into be unboxed 2024-12-13 11:05:30 -07:00
ffi docs: inline core::ffi::c_str types to core::ffi 2024-12-26 15:51:45 -07:00
fmt Less unwrap() in documentation 2024-12-21 01:26:47 +00:00
future split up #[rustc_deny_explicit_impl] attribute 2024-12-20 16:57:14 +01:00
hash stabilize const_collections_with_hasher and build_hasher_default_const_new 2024-12-02 16:34:39 +01:00
intrinsics Auto merge of #134757 - RalfJung:const_swap, r=scottmcm 2024-12-30 23:46:42 +00:00
io Add BorrowedBuf::into_filled{,_mut} methods to allow returning buffer with original lifetime 2024-11-02 14:26:21 -04:00
iter Rollup merge of #134782 - wtlin1228:docs/iter-rposition, r=Mark-Simulacrum 2024-12-26 21:56:50 -05:00
macros chore: fix typos 2024-12-24 23:37:30 +08:00
mem rename typed_swap → typed_swap_nonoverlapping 2024-12-25 10:53:03 +01:00
net fix typos in the example code in the doc comments of Ipv4Addr::from_bits(), Ipv6Addr::from_bits() & Ipv6Addr::to_bits() 2024-12-20 11:47:02 +08:00
num Tidy up bigint mul methods 2024-12-27 22:01:51 -05:00
ops Stabilize async closures 2024-12-13 00:04:56 +00:00
panic replace placeholder version 2024-11-27 12:10:21 +00:00
prelude Stabilize the Rust 2024 prelude 2024-12-11 13:09:57 -08:00
ptr Rollup merge of #134953 - DiuDiu777:unaligned-doc, r=RalfJung 2024-12-31 14:30:43 +01:00
range Reformat using the new identifier sorting from rustfmt 2024-09-22 19:11:29 -04:00
slice Rollup merge of #134927 - DaniPopes:const-as_flattened_mut, r=scottmcm 2024-12-31 14:12:46 +11:00
str chore: fix typos 2024-12-24 23:37:30 +08:00
sync Less unwrap() in documentation 2024-12-21 01:26:47 +00:00
task Use field init shorthand where possible 2024-12-17 14:33:10 -08:00
unicode Reformat Python code with ruff 2024-12-04 23:03:44 +01:00
any.rs Fixes safety docs for dyn Any + Send {+ Sync} 2024-12-22 21:38:23 +02:00
arch.rs Add core::arch::breakpoint and test 2024-12-02 23:56:24 -08:00
ascii.rs Reformat use declarations. 2024-07-29 08:26:52 +10:00
asserting.rs Reformat use declarations. 2024-07-29 08:26:52 +10:00
bool.rs Add doc alias 'then_with' for then method on bool 2024-12-03 09:20:34 +02:00
borrow.rs Suggest borrowing on fn argument that is impl AsRef 2024-05-09 23:25:31 +00:00
cell.rs Implement PointerLike for isize, NonNull, Cell, UnsafeCell, and SyncUnsafeCell. 2024-12-22 11:18:56 -08:00
clone.rs Make CloneToUninit dyn-compatible 2024-11-12 15:08:41 -06:00
cmp.rs Revert "Auto merge of #130766 - clarfonthey:stable-coverage-attribute, r=wesleywiser" 2024-12-23 12:30:37 +11:00
default.rs update cfgs 2024-09-05 17:24:01 +01:00
error.md Mention core's PanicInfo in error.md. 2024-06-11 15:47:00 +02:00
error.rs Update includes in '/library/core/src/error.rs'; 2024-12-13 12:46:20 +01:00
escape.rs Optimize escape_ascii 2024-10-09 17:17:50 -04:00
hint.rs feat: clarify how to use black_box() 2024-12-12 13:54:17 -05:00
internal_macros.rs Fix doc nits 2024-07-26 13:26:33 +01:00
lib.miri.rs add 'x.py miri', and make it work for 'library/{core,alloc,std}' 2024-04-03 20:27:20 +02:00
lib.rs Auto merge of #132195 - clarfonthey:bigint-mul, r=scottmcm 2024-12-31 18:49:36 +00:00
marker.rs Rollup merge of #134642 - kpreid:pointerlike-cell, r=compiler-errors 2024-12-22 21:59:27 +01:00
option.rs Less unwrap() in documentation 2024-12-21 01:26:47 +00:00
panic.rs update cfgs 2024-11-27 15:14:54 +00:00
panicking.rs update cfgs 2024-11-27 15:14:54 +00:00
pat.rs Rename core_pattern_type and core_pattern_types lib feature gates to pattern_type_macro 2024-12-04 16:16:24 +00:00
pin.rs Fix sentence fragment in pin module docs 2024-12-28 22:21:04 -05:00
primitive.rs Reformat using the new identifier sorting from rustfmt 2024-09-22 19:11:29 -04:00
primitive_docs.rs Use &raw for ptr primitive docs 2024-12-21 15:47:44 -05:00
random.rs random: add tracking issue, address other comments 2024-09-23 10:36:16 +02:00
range.rs Reformat using the new identifier sorting from rustfmt 2024-09-22 19:11:29 -04:00
result.rs Less unwrap() in documentation 2024-12-21 01:26:47 +00:00
time.rs get rid of a whole bunch of unnecessary rustc_const_unstable attributes 2024-11-02 09:59:55 +01:00
tuple.rs update cfgs 2024-09-05 17:24:01 +01:00
ub_checks.rs update cfgs 2024-11-27 15:14:54 +00:00
unit.rs Import the 2021 prelude in the core crate 2024-03-25 13:12:06 -07:00
unsafe_binder.rs Add unwrap_unsafe_binder and wrap_unsafe_binder macro operators 2024-12-12 16:29:40 +00:00