Rollup of 6 pull requests
Successful merges:
- rust-lang/rust#147552 ([Debugger Visualizers] Optimize lookup behavior)
- rust-lang/rust#154052 (float: Fix panic at max exponential precision)
- rust-lang/rust#154706 (fix compilation of time/hermit.rs)
- rust-lang/rust#154707 (Make `substr_range` and `subslice_range` return the new `Range` type)
- rust-lang/rust#154767 (triagebot: roll library reviewers for `{coretests,alloctests}`)
- rust-lang/rust#154797 (bootstrap: Include shorthand aliases in x completions)
float: Fix panic at max exponential precision
Rust's formatting machinery allows precision values of up to u16::MAX. Exponential formatting works out the number of significant digits to use by adding one (for the integral digit before the decimal point).
This previously used usize precision, so the maximum validated precision did not overflow, but in commit fb9ce02976 ("Limit formatting width and precision to 16 bits.") the precision type was narrowed to u16 without widening that addition first.
As a result an exponential precision value of 65535 is no longer handled correctly, because the digit count wraps to 0, and thus "{:.65535e}" panics in flt2dec::to_exact_exp_str with "assertion failed: ndigits > 0". Other formats (and the parser) accept values up to u16::MAX.
A naive fix would be to widen that addition back to usize, but that still does not properly address 16-bit targets, where usize is only guaranteed to be able to represent values up to u16::MAX. The real issue is that this internal API is expressed in the wrong units for the formatter.
Fix this by changing exact exponential formatting to take fractional digits internally as well, and compute the temporary significant digit bound only when sizing the scratch buffer. To support that let's also make formatted length accounting saturate so that extremely large rendered outputs do not reintroduce overflows in padding logic.
This preserves the existing intent and keeps FormattingOptions compact while making formatting work consistently again.
Rust's formatting machinery allows precision values of up to u16::MAX.
Exponential formatting works out the number of significant digits to use
by adding one (for the integral digit before the decimal point).
This previously used usize precision, so the maximum validated precision
did not overflow, but in commit fb9ce02976 ("Limit formatting width
and precision to 16 bits.") the precision type was narrowed to u16
without widening that addition first.
As a result an exponential precision value of 65535 is no longer handled
correctly, because the digit count wraps to 0, and thus "{:.65535e}"
panics in flt2dec::to_exact_exp_str with "assertion failed: ndigits >
0". Other formats (and the parser) accept values up to u16::MAX.
A naive fix would be to widen that addition back to usize, but that
still does not properly address 16-bit targets, where usize is only
guaranteed to be able to represent values up to u16::MAX. The real issue
is that this internal API is expressed in the wrong units for the
formatter.
Fix this by changing exact exponential formatting to take fractional
digits internally as well, and compute the temporary significant digit
bound only when sizing the scratch buffer. To support that let's also
make formatted length accounting saturate so that extremely large
rendered outputs do not reintroduce overflows in padding logic.
This preserves the existing intent and keeps FormattingOptions compact
while making formatting work consistently again.
coretests: Expand ieee754 parsing and printing tests to f16
Use `float_test!` to cover all types, with a note about f128 missing the traits. Also includes some minor reorganization.
`Float` and `FloatExt` are already used by both parsing and printing, so
move them out of `dec2flt` to a new module in `num::imp`. `Int` `Cast`
have the potential to be used more places in the future, so move them
there as well. `Lemire` is the only remaining trait; since it is small,
move it into the `dec2flt` root.
The `fmt::LowerExp` bound is removed from `Float` here since the trait
is moving into a module without `#[cfg(not(no_fp_fmt_parse))]` and it
isn't implemented with that config (it's not easily possible to add
`cfg` attributes to a single supertrait, unfortunately). This isn't a
problem since it isn't actually being used.
`RawFloat` is currently used specifically for the implementation of the
lemire algorithm, but it is useful for more than that. Split it into
three different traits:
* `Float`: Anything that is reasonably applicable to all floating point
types.
* `FloatExt`: Items that should be part of `Float` but don't work for
all float types. This will eventually be merged back into `Float`.
* `Lemire`: Items that are specific to the Lemire algorithm.
num: Separate public API from internal implementations
Currently we have a single `core::num` module that contains both thin wrapper API and higher-complexity numeric routines. Restructure this by moving implementation details to a new `imp` module.
This results in a more clean separation of what is actually user-facing compared to items that have a stability attribute because they are public for testing.
The first commit does the actual change then the second moves a portion back.
Currently we have a single `core::num` module that contains both thin
wrapper API and higher-complexity numeric routines. Restructure this by
moving implementation details to a new `imp` module.
This results in a more clean separation of what is actually user-facing
compared to items that have a stability attribute because they are
public for testing.
There are a number of instances of `FIXME(f16_f128)` related to target
configuration; either these could use `target_has_reliable_f128`, or the
FIXME is describing such a cfg and is thus redundant (since any
`cfg(target_has_reliable_f*)` needs to be removed before stabilization
anyway).
Switch to using `target_has_reliable_*` where applicable and remove the
redundant FIXMEs.
Additional test for uN::{gather,scatter}_bits
Feature gate: #![feature(uint_gather_scatter_bits)]
Tracking issue: https://github.com/rust-lang/rust/issues/149069
Accepted ACP: https://github.com/rust-lang/libs-team/issues/695#issuecomment-3549284861
Adds an additional runtime test for `uN::gather_bits` and `uN::scatter_bits` in coretests. They are each other's inverses in a sense, so a shared test can test both with relative ease.
I plan to follow up with optimized implementations for these functions.
Implement the accepted ACP for methods that find the index of the least
significant (lowest) and most significant (highest) set bit in an
integer for signed, unsigned, and NonZero types.
Also add unit tests for all these types.
Enable Non-determinism of float operations in Miri and change std tests
Links to [#4208](https://github.com/rust-lang/miri/issues/4208) and [#3555](https://github.com/rust-lang/miri/issues/3555) in Miri.
Non-determinism of floating point operations was disabled in rust-lang/rust#137594 because it breaks the tests and doc-tests in core/coretests and std. This PR enables some of them.
This pr includes the following changes:
- Enables the float non-determinism but with a lower relative error of 4ULP instead of 16ULP
- These operations now have a fixed output based on the C23 standard, except the pow operations, this is tracked in [#4286](https://github.com/rust-lang/miri/issues/4286#issue-3010677983)
- Changes tests that made incorrect assumptions about the operations, not to make that assumption anymore (from `assert_eq!` to `assert_approx_eq!`.
- Changed the doctests of the stdlib of these operations to compare against fixed constants instead of `f*::EPSILON`, which now succeed with Miri and `-Zmiri-many-seeds`
- Added a constant `APPROX_DELTA` in `std/tests/floats/f32.rs` which is used for approximation tests, but with a different value when run in Miri. This is to make these tests succeed.
- Added tests in the float tests of Miri to test the C23 behaviour.
Fixes https://github.com/rust-lang/miri/issues/4208
coretests: move float tests from num to floats module and use a more flexible macro to generate them
This makes some progress on https://github.com/rust-lang/rust/issues/141726 by moving the float tests in `num` to `floats` and using a newer, more flexible macro to generate them. We also newly run these tests on f16 and f128 in const, and at runtime in Miri and for hosts where that works well enough.
I didn't yet deduplicate any tests or port the existing `floats::f*` tests to the macro, that can happen in a future PR.
try-job: x86_64-gnu-aux
exact_div: add tests
tracking issue: rust-lang/rust#139911
I neglected to add tests in my last PR (rust-lang/rust#141237), so I've added them here.
r? ``@workingjubilee`` (Feel free to reroll, I just picked you since you reviewed the last one.)