We do handle signaling NaNs properly, with the exception of raising
exceptions as IEEE 754 requires. Add tests to this effect for
`fmin`, `fminimum`, `fminimum_num`, and the max variants.
Give more descriptive output in tests since we sometimes need to treat
these differently. We still don't parse `sNaN`/`qNaN` for now, though we
could in the future.
Make `Float::NAN` a qNaN, add sNaNs, and add operations to check whether
a NaN is quiet or signaling.
The MIPS values are checked against https://gcc.godbolt.org/z/1bhsd5ana.
Fix grammar in Pin documentation
Changed "has an address-sensitive" to "has address-sensitive states" in the `Drop` implementation section of the documentation of `Pin` thereby making it grammatically complete.
core: remove FIXME comment in option.rs FromIterator
The referenced issue rust-lang/rust#11084 was closed in 2021, and the related PR rust-lang/rust#59605 was not merged due to inconclusive results. Similar code (in result.rs, for example) doesn't have this FIXME comment; this is the only reference to issue 11084 (or pull request 59605).
This FIXME was not mentioned in issue rust-lang/rust#44366.
Add missing safety doc for CString::from_vec_unchecked and async_drop_in_place
Add missing safety documentation for two unsafe APIs:
* `CString::from_vec_unchecked` – # Safety: the caller must ensure `v` contains no NUL bytes in its contents.
* `async_drop_in_place` – # Safety: see [`ptr::drop_in_place`] for safety requirements.
This FIXME is relevant not only to Option but other similar cases that
use iter::try_process(). The referenced issue 11084 was closed in 2021,
and the related PR 59605 was not merged due to inconclusive results.
fixed VecDeque::splice() not filling the buffer correctly when resizing the buffer on start = end range
This PR fixesrust-lang/rust#151758. The issue came from `Splice::move_tail`, which as joboet pointed out:
> The issue is in move_tail, which resizes the buffer, but fails to account for the resulting hole.
The problem with reserving more space through `VecDeque`'s `buf.reserve()` is that it doesn't update `VecDeque`'s `head`, which means that this code in `move_tail`:
```rust
deque.wrap_copy(
deque.to_physical_idx(tail_start),
deque.to_physical_idx(new_tail_start),
self.tail_len,
);
```
could move over the section of data that `tail_start..tail_start + self.tail_len` of the buffer is supposed to be held at to the incorrect destination since all `.to_physical_idx()` is doing is a wrapping add on the `VecDeque`'s head with the passed in `idx` value.
To avoid this I decided to use `VecDeque::reserve` to both allocate more space into the `VecDeque` if necessary and update head appropriately. However, `VecDeque::reserve` internally relies on the `VecDeque`'s `len` field. Earlier in `VecDeque::splice`, it modifies the `VecDeque`'s `len` constructing the drain via `Drain::new` (as it does a `mem::replace` on `deque.len` with the start bound of the passed in `range`). The `VecDeque`'s `len` can also be potentially modified in the earlier `Splice::fill()` call if it does any replacement towards elements within the passed in `range` value for `VecDeque::splice()`. I needed to temporarily restore the `VecDeque`'s `len` to its actual len, so that `VecDeque::reserve` can work properly. Afterward, you can bring back the `VecDeque`'s `len` to what its value was before and fill the gap appropriately with the rest of the `replace_with` content.
r? @joboet
miri-test-libstd: use --tests and update some comments
rust-lang/rust#153143 added `./x test --tests` matching `cargo --tests`, which is exactly what Miri wants when testing the standard library. So let's use it for that. We can then also remove a hack in `library/alloctests/benches/vec_deque_append.rs`.
Also update the comment for why the other benchmarks still need to be disabled in Miri, and remove some `cfg_attr` that seem unnecessary since the entire crate that contains them is already disabled in Miri. Those were copied over in https://github.com/rust-lang/rust/commit/b8fa843a1a60146b93ca5b1d11bbe23c1b1076f3 -- they used to be needed since benches and tests were in the same crate, but they aren't any more.
Allow merging all libcore/alloc doctests into a single binary
This is only the changes needed to *allow* merging the tests. This doesn't actually turn doctest merging on in bootstrap. I think that might be a useful follow-up, since it makes them much faster to run, but it's not without downsides because it means we'll no longer be testing that doctests have all necessary `feature()` attributes.
The motivation for this change is to run the tests with `-C instrument-coverage` and then generate a coverage report from the output. Currently, this is very expensive because it requires parsing DWARF for each doctest binary. Merging the binaries decreases the time taken from several hours to ~30 seconds.
---
There are several parts to this change, most of which are independent and I'm happy to split out into other PRs.
- Upgrade process spawning logging from debug->info so it's easier to see, including in a rustdoc built without debug symbols.
- Core doctests now support being run with `-C panic=abort`. Ferrocene needs this downstream for complicated reasons; it's a one-line change so I figured it's not a big deal.
- Downgrade errors about duplicate features from a hard error to a warning. The meaning is clear here, and doctest merging often creates duplicate features since it lifts them all to the crate root. This involves changes to the compiler but generally I expect this to be low-impact.
- Enable this new warning, as well as several related feature lints, in rustdoc. By default rustdoc doesn't lint on anything except the lints it manually adds.
- Rustdoc now treats `allow(incomplete_features)` as a crate-level attribute, just like `internal_features`. Without this, it's possible to get hard errors if rustdoc lifts features to the crate level but not `allow`s.
- Core doctests now support being built with `--merge-doctests=yes`. In particular, I removed a few `$crate` usages and explicitly marked a few doctests as `standalone_crate`.
Allow `./x test` to run tests without doc tests and without benchmarks
# Problem
For Ferrocene we would like to run only the `coretests` and `alloctests` test suites when measuring code coverage. Running `corebenches` and `allocbenches` would alter the numbers, which is not compliant with the certification.
This is currently not possible in bootstrap. By default `./x test` runs unit, integration and doc tests. `./x test --doc` only runs doc tests. So far, so good.
The problem is that while `./x test --no-doc` stops bootstrap from executing doc tests, it surprisingly starts executing benchmarks (next to examples and bins as well). It basically behaves like `cargo test --all-targets`.
# Solution
This PR renames the existing `--no-doc` flag to `--all-targets` and keeps the same behaviour as before. Unfortunately it is not possible to internally switch from `cargo --bins --examples --tests --benches` to `cargo --all-targets` because it will fail e.g. `./x test library/alloc --all-targets` with an error like "use of unstable library feature `test`".
Additionally, this PR add a `./x test --tests` flag (equivalent to `cargo test --tests`) that only executes unit and integration tests.
Both changes we are doing in https://github.com/ferrocene/ferrocene anyways, but believe that they may be useful for other people as well and therefore would like to contribute them.
Note that this PR does _not_ change the behaviour of either `./x test` or `./x test --doc`.
## Note on `test = true`
While this change enables bootstrap to run tests without doc tests and without benchmarks, executing `./x test library/core library/alloc --tests` will still build and execute `corebenches` and `allocbenches`.
What?! 😱 Why all of this effort to enable it then?
Good question! The reason they are still executed is, that they are marked with `test = true` in their respective `Cargo.toml` ([corebenches](https://github.com/rust-lang/rust/blob/3f9853562c73af38a5e6af8b0da1b2734a327e19/library/coretests/Cargo.toml#L24), [allocbenches](https://github.com/rust-lang/rust/blob/3f9853562c73af38a5e6af8b0da1b2734a327e19/library/alloctests/Cargo.toml#L32)).
@bjorn3 mentioned that it is important for upstream that those benchmarks are executed by default, even if no `./x --all-targets` is passed. This is perfectly possible with this PR. Benchmarks marked with `test = true` will be executed when calling either of `./x test`, `./x test --tests` or `./x --all-targets`. Therefore this PR does not include a commit to change that. We will just do this change in https://github.com/ferrocene/ferrocene.
## Open questions
### Error message
I added one commit that adds an error message if a user passes `--no-doc` and points them to `--all-targets` and `--tests`. I think it might be nice to have, but if you think it is not necessary, I can remove it.
# How to test this change
You can see the change in action by running `./x test library/alloc --tests` and `./x test library/alloc --all-targets`. The first will execute `alloctests` and `allocbenches` (which is marked with `test = true`), while the second will additionally run `benches/vec_deque_append.rs` (which is _not_ marked with `test = true`).
- `./x run generate-completions`
- Search and replace `--no-doc` with `--all-targets`
This is to keep the behaviour the same.
- Document `./x test --tests` in `rustc-dev-guide`
- Add change info
In `Option::get_or_insert_with()`, forget the `None` instead of dropping it.
Per https://github.com/rust-lang/rust/pull/148486#issuecomment-3493665688
In `Option::get_or_insert_with()`, after replacing the `None` with `Some`, forget the `None` instead of dropping it.
This allows eliminating the `T: [const] Destruct` bounds, making the functions more flexible in (unstable) const contexts, and avoids generating an implicit `drop_in_place::<Option<T>>()` that will never do anything (and which might even persist after optimization).
Unicode data: reduce size of to_lower/to_upper tables
Reduces the combined size of to_lower and to_upper from 25,364 bytes to 3,110 bytes. Explained in detail in the doc comments
std: organise `sys::pal::os`
Continuing rust-lang/rust#153341, this moves around some functions in `sys::pal`, so that `pal::os` only contains standard-path-related code (which I'll move later as part of rust-lang/rust#117276).
Best reviewed commit-by-commit.
core: respect precision in `ByteStr` `Display`
Fixesrust-lang/rust#153022.
`ByteStr`'s `Display` implementation didn't respect the precision parameter. Just like `Formatter::pad`, this is fixed by counting off the characters in the string and truncating after the requested length – with the added complication that the `ByteStr` needs to be divided into chunks first. By including a fast path that avoids counting the characters when no parameters were specified this should also fix the performance regressions caused by rust-lang/rust#152865.
Instead of generating a standalone executable to test `unicode_data`,
generate normal tests in `coretests`. This ensures tests are always
generated, and will be run as part of the normal testsuite.
Also change the generated tests to loop over lookup tables, rather than
generating a separate `assert_eq!()` statement for every codepoint. The
old approach produced a massive (20,000 lines plus) file which took
minutes to compile!
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.
Update `UnsafeUnpin` impls involving extern types.
`UnsafeUnpin` tracking issue: https://github.com/rust-lang/rust/issues/125735
Relaxes from `T: ?Sized` (i.e. `T: MetaSized`) to `T: PointeeSized` for the `UnsafeUnpin` impls for pointers, references, and `PhantomData<T>`, and for the negative `UnsafeUnpin` impl for `UnsafePinned<T>`. (Compare to the impls for `Freeze` on lines 911-921.)
Both `UnsafeUnpin` and `extern type`s (the only way to have a `!MetaSized` type) are unstable, so this should have no effect on stable code.
Also updates the marker_impls macro docs to use PointeeSized bound, as most uses of the macro now do.
Concretely, this change means that the following types will newly implement `UnsafeUnpin`:
* pointers and references to `T` where `T` is an `extern type`
* `PhantomData<T>` where `T` is an extern type
* either of the above where `T` is a `struct` or tuple with `extern type` tail
Additionally, the negative `UnsafeUnpin` impl for `UnsafePinned<T>` is also relaxed to `T: PointeeSized` to align with the analogous negative `Freeze` impl for `UnsafeCell<T>`, even though both structs have `T: ?Sized` in their declaration (which probably should be relaxed, but that is a separate issue), so this part of the change doesn't actually *do* anything currently, but if `UnsafeCell` and `UnsafePinned` are later relaxed to `T: PointeeSized`, then the negative impl will apply to the newly possible instantiations. Also cc https://github.com/rust-lang/rust/issues/152645 that these impls compile at all.
libcore float tests: replace macro shadowing by const-compatible macro
This lets us avoid https://github.com/rust-lang/rust/issues/153478.
However this means we generate 3 function items per assertion -- or rather, 3*8, since every assertion gets duplicated 8 times (4 float types, each in a const and a non-const variant). That's a lot; is it enough to be concerned about?
coretest already takes forever to build. In a quick test, build time increased from 29.8s to 30.8s, but that may also entirely be noise.
r? @tgross35
std: add wasm64 to sync::Once and thread_parking atomics cfg guards
When targeting `wasm64-unknown-unknown` with atomics enabled, `std::sync::Once` and `thread_parking` fall through to the `no_threads`/`unsupported` implementations because the cfg guards only check for `wasm32`. This causes worker threads to panic with `unreachable` at runtime. The underlying futex implementations already handle both wasm32 and wasm64 correctly, only the cfg guards were missing wasm64.
I tested this manually with a multithreaded wasm64 application ([o1js](https://github.com/o1-labs/o1js/)) compiled with `-Z build-std=panic_abort,std` and `-C target-feature=+atomics,+bulk-memory,+mutable-globals`
Related: rust-lang/rust#83879rust-lang/rust#77839
Happy to adjust anything based on feedback
These warnings are showing up on the most recent nightly:
error: feature `f128` is declared but not used
--> builtins-test/tests/addsub.rs:3:35
|
3 | #![cfg_attr(f128_enabled, feature(f128))]
| ^^^^
It isn't always easy to be more exact with the features we enable, so
mostly ignore this.
We are now getting this warning:
warning: the variable `j` is used as a loop counter
--> libm/src/math/rem_pio2_large.rs:268:5
|
268 | for i in 0..=m {
| ^^^^^^^^^^^^^^ help: consider using: `for (j, i) in ((jv as i32) - (jx as i32)..).zip((0..=m))`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#explicit_counter_loop
= note: `#[warn(clippy::explicit_counter_loop)]` on by default
warning: `libm` (lib) generated 1 warning
Where the suggestion is definitely not an improvement.