Implement round-ties-to-even for Duration Debug for consistency with f64
## Summary
This PR proposes a fix for rust-lang/rust#103747 implementing IEEE-754 S4.3 roundTiesToEven for Duration Debug implementation.
## Testing
Added new test in `time.rs` for validating roundTiesToEven behavior in Duration formatting. Reran all debug formatting tests in `time.rs` with `./x test library/coretests --test-args time::debug_formatting`.
This caused several performance regressions because of existing code
which uses `Read::read` and therefore requires full buffer
initialization. This is particularly a problem when the same buffer is
re-used for multiple read calls since this means it needs to be fully
re-initialized each time.
There is still some benefit to landing the API changes, but we will have
to add private APIs so that the existing infrastructure can
track and avoid redundant initialization.
test: update duplicate many_digits test to use f64 instead of f32
Replace the f32 test case with an f64 equivalent to improve coverage for parsing large digit counts in double-precision floating-point conversion. Specifically, this PR updates the `many_digits` test in `library/coretests/tests/num/dec2flt/parse.rs` to test f64 (double-precision) parsing instead of f32 (single-precision).
The test verifies that decimal strings with an excessive number of digits (beyond `Decimal::MAX_DIGITS`) are parsed correctly, ensuring proper truncation of insignificant digits. Previously, the same test was repeated twice (see comment https://github.com/rust-lang/rust/pull/86761#issuecomment-3623334228 by `@Viatorus).`
## Changes
- Replaced the duplicated f32 test case with an equivalent f64 test case.
- Updated the expected bit pattern and input string to a very long decimal with many trailing zeros, testing the limits of f64 precision.
Constify `DropGuard::dismiss` and trait impls
Feature: `drop_guard` (rust-lang/rust#144426), `const_convert` (rust-lang/rust#143773), `const_drop_guard` (no tracking issue yet)
Constifies `DropGuard::dismiss` and trait impls.
I reused `const_convert` (rust-lang/rust#143773) for the `Deref*` impls.
Implement benchmarks 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
For each method, there are three benchmarks, which differ in that the mask (second) argument is one of:
- constant at compile time
- runtime value but invariant for the measured loop
- different for each call
Sample output
```text
num::int_bits::u32::constant::gather_bits 555.82ns/iter +/- 22.41
num::int_bits::u32::constant::scatter_bits 545.45ns/iter +/- 124.26
num::int_bits::u32::invariant::gather_bits 8178.86ns/iter +/- 217.37
num::int_bits::u32::invariant::scatter_bits 7135.95ns/iter +/- 214.51
num::int_bits::u32::variable::gather_bits 10539.29ns/iter +/- 198.90
num::int_bits::u32::variable::scatter_bits 9671.26ns/iter +/- 254.88
```
(and similarly for the other `uN` types)
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.
Remove an outdated test
This... is a weird test.
It has two impls:
- `impl<T> From<Foo<T>> for Box<T>` (commented out, more on that later), and
- `impl<T> Into<Vec<T>> for Foo<T>`
The idea of that test is to show that the first impl doesn't compile, but the second does, thus `TryFrom` should be using `Into` and not `From` (because `Into` is more general, since the `From` impl doesn't compile).
However:
1. The types are different -- `Box` vs `Vec`, which is significant b/c `Box` is fundamental
2. The commented out impl actually compiles! (which wasn't detected b/c it's commented out :\ )
Here is a table for compilation of the impls:
| | `Vec` | `Box` |
|--------|--------------|----------------|
| `From` | since 1.41.0 | never |
| `Into` | always | not since 1.28 |
[godbolt used to test this](https://godbolt.org/z/T38E3jGKa)
Order of events:
1. in `1.28` the `incoherent_fundamental_impls` lint becomes deny by default (this is *not* mentioned in the changelog yay)
2. `1.32` changed absolutely nothing, even though this version is credited in the test
3. the test was added (I'm not exactly sure when) (see https://github.com/rust-lang/rust/pull/56796)
4. in `1.41` coherence was relaxed to allow `From`+`Vec` to compile
To conclude: since `1.41` this test does nothing (and before that it was written in a way which did not detect this change). It looks to me like today (since `1.41`) we *could* bound `TryFrom` impl with `From` (but now it'd be a useless breaking change of course).
Am I missing anything? Is there a useful version of this test that could be written?
Remove initialized-bytes tracking from `BorrowedBuf` and `BorrowedCursor`
As discussed extensively in libs-api, the initialized-bytes tracking primarily benefits calls to `read_buf` that end up initializing the buffer and calling `read`, at the expense of calls to `read_buf` that *don't* need to initialize the buffer. Essentially, this optimizes for the past at the expense of the future. If people observe performance issues using `read_buf` (or something that calls it) with a given `Read` impl, they can fix those performance issues by implementing `read_buf` for that `Read`.
Update the documentation to stop talking about initialized-but-unfilled bytes.
Remove all functions that just deal with those bytes and their tracking, and remove usage of those methods.
Remove `BorrowedCursor::advance` as there's no longer a safe case for advancing within initialized-but-unfilled bytes. Rename `BorrowedCursor::advance_unchecked` to `advance`.
Update tests.
r? ``@Amanieu``
As discussed extensively in libs-api, the initialized-bytes tracking
primarily benefits calls to `read_buf` that end up initializing the
buffer and calling `read`, at the expense of calls to `read_buf` that
*don't* need to initialize the buffer. Essentially, this optimizes for
the past at the expense of the future. If people observe performance
issues using `read_buf` (or something that calls it) with a given `Read`
impl, they can fix those performance issues by implementing `read_buf`
for that `Read`.
Update the documentation to stop talking about initialized-but-unfilled
bytes.
Remove all functions that just deal with those bytes and their tracking,
and remove usage of those methods.
Remove `BorrowedCursor::advance` as there's no longer a safe case for
advancing within initialized-but-unfilled bytes. Rename
`BorrowedCursor::advance_unchecked` to `advance`.
Update tests.