[Arm64] use isb instruction instead of yield in spin loops
On arm64 we have seen on several databases that ISB (instruction synchronization
barrier) is better to use than yield in a spin loop. The yield instruction is a
nop. The isb instruction puts the processor to sleep for some short time. isb
is a good equivalent to the pause instruction on x86.
Below is an experiment that shows the effects of yield and isb on Arm64 and the
time of a pause instruction on x86 Intel processors. The micro-benchmarks use
https://github.com/google/benchmark.git
```
$ cat a.cc
static void BM_scalar_increment(benchmark::State& state) {
int i = 0;
for (auto _ : state)
benchmark::DoNotOptimize(i++);
}
BENCHMARK(BM_scalar_increment);
static void BM_yield(benchmark::State& state) {
for (auto _ : state)
asm volatile("yield"::);
}
BENCHMARK(BM_yield);
static void BM_isb(benchmark::State& state) {
for (auto _ : state)
asm volatile("isb"::);
}
BENCHMARK(BM_isb);
BENCHMARK_MAIN();
$ g++ -o run a.cc -O2 -lbenchmark -lpthread
$ ./run
--------------------------------------------------------------
Benchmark Time CPU Iterations
--------------------------------------------------------------
AWS Graviton2 (Neoverse-N1) processor:
BM_scalar_increment 0.485 ns 0.485 ns 1000000000
BM_yield 0.400 ns 0.400 ns 1000000000
BM_isb 13.2 ns 13.2 ns 52993304
AWS Graviton (A-72) processor:
BM_scalar_increment 0.897 ns 0.874 ns 801558633
BM_yield 0.877 ns 0.875 ns 800002377
BM_isb 13.0 ns 12.7 ns 55169412
Apple Arm64 M1 processor:
BM_scalar_increment 0.315 ns 0.315 ns 1000000000
BM_yield 0.313 ns 0.313 ns 1000000000
BM_isb 9.06 ns 9.06 ns 77259282
```
```
static void BM_pause(benchmark::State& state) {
for (auto _ : state)
asm volatile("pause"::);
}
BENCHMARK(BM_pause);
Intel Skylake processor:
BM_scalar_increment 0.295 ns 0.295 ns 1000000000
BM_pause 41.7 ns 41.7 ns 16780553
```
Tested on Graviton2 aarch64-linux with `./x.py test`.
On arm64 we have seen on several databases that ISB (instruction synchronization
barrier) is better to use than yield in a spin loop. The yield instruction is a
nop. The isb instruction puts the processor to sleep for some short time. isb
is a good equivalent to the pause instruction on x86.
Below is an experiment that shows the effects of yield and isb on Arm64 and the
time of a pause instruction on x86 Intel processors. The micro-benchmarks use
https://github.com/google/benchmark.git
$ cat a.cc
static void BM_scalar_increment(benchmark::State& state) {
int i = 0;
for (auto _ : state)
benchmark::DoNotOptimize(i++);
}
BENCHMARK(BM_scalar_increment);
static void BM_yield(benchmark::State& state) {
for (auto _ : state)
asm volatile("yield"::);
}
BENCHMARK(BM_yield);
static void BM_isb(benchmark::State& state) {
for (auto _ : state)
asm volatile("isb"::);
}
BENCHMARK(BM_isb);
BENCHMARK_MAIN();
$ g++ -o run a.cc -O2 -lbenchmark -lpthread
$ ./run
--------------------------------------------------------------
Benchmark Time CPU Iterations
--------------------------------------------------------------
AWS Graviton2 (Neoverse-N1) processor:
BM_scalar_increment 0.485 ns 0.485 ns 1000000000
BM_yield 0.400 ns 0.400 ns 1000000000
BM_isb 13.2 ns 13.2 ns 52993304
AWS Graviton (A-72) processor:
BM_scalar_increment 0.897 ns 0.874 ns 801558633
BM_yield 0.877 ns 0.875 ns 800002377
BM_isb 13.0 ns 12.7 ns 55169412
Apple Arm64 M1 processor:
BM_scalar_increment 0.315 ns 0.315 ns 1000000000
BM_yield 0.313 ns 0.313 ns 1000000000
BM_isb 9.06 ns 9.06 ns 77259282
static void BM_pause(benchmark::State& state) {
for (auto _ : state)
asm volatile("pause"::);
}
BENCHMARK(BM_pause);
Intel Skylake processor:
BM_scalar_increment 0.295 ns 0.295 ns 1000000000
BM_pause 41.7 ns 41.7 ns 16780553
Tested on Graviton2 aarch64-linux with `./x.py test`.
Searching for "reduce" currently puts the `reduce` alias for `fold`
above the actual `reduce` function. The `reduce` function already has a
cross-reference for `fold`, and vice versa.
The Eq trait has a special hidden function. MIR `InstrumentCoverage`
would add this function to the coverage map, but it is never called, so
the `Eq` trait would always appear uncovered.
Fixes: #83601
The fix required creating a new function attribute `no_coverage` to mark
functions that should be ignored by `InstrumentCoverage` and the
coverage `mapgen` (during codegen).
While testing, I also noticed two other issues:
* spanview debug file output ICEd on a function with no body. The
workaround for this is included in this PR.
* `assert_*!()` macro coverage can appear covered if followed by another
`assert_*!()` macro. Normally they appear uncovered. I submitted a new
Issue #84561, and added a coverage test to demonstrate this issue.
Add the `try_trait_v2` library basics
No compiler changes as part of this -- just new unstable traits and impls thereof.
The goal here is to add the things that aren't going to break anything, to keep the feature implementation simpler in the next PR.
(Draft since the FCP won't end until Saturday, but I was feeling optimistic today -- and had forgotten that FCP was 10 days, not 7 days.)
Stabilize Duration::MAX
Following the suggested direction from https://github.com/rust-lang/rust/issues/76416#issuecomment-817278338, this PR proposes that `Duration::MAX` should have been part of the `duration_saturating_ops` feature flag all along, having been
0. heavily referenced by that feature flag
1. an odd duck next to most of `duration_constants`, as I expressed in https://github.com/rust-lang/rust/issues/57391#issuecomment-717681193
2. introduced in #76114 which added `duration_saturating_ops`
and accordingly should be folded into `duration_saturating_ops` and therefore stabilized.
r? `@m-ou-se`
move core::hint::black_box under its own feature gate
The `black_box` function had its own RFC and is tracked separately from the `test` feature at https://github.com/rust-lang/rust/issues/64102. Let's reflect this in the feature gate.
To avoid breaking all the benchmarks, libtest's `test::black_box` is a wrapping definition, not a reexport -- this means it is still under the `test` feature gate.
Cautiously add IntoIterator for arrays by value
Add the attribute described in #84133, `#[rustc_skip_array_during_method_dispatch]`, which effectively hides a trait from method dispatch when the receiver type is an array.
Then cherry-pick `IntoIterator for [T; N]` from #65819 and gate it with that attribute. Arrays can now be used as `IntoIterator` normally, but `array.into_iter()` has edition-dependent behavior, returning `slice::Iter` for 2015 and 2018 editions, or `array::IntoIter` for 2021 and later.
r? `@nikomatsakis`
cc `@LukasKalbertodt` `@rust-lang/libs`
Duration is used in std to represent a difference between two Instants.
As such, it has to at least contain that span of time in it. However,
Instant can vary by platform. Thus, we should explain the impl of
Duration::MAX is sensitive to these vagaries of the platform.
further split up const_fn feature flag
This continues the work on splitting up `const_fn` into separate feature flags:
* `const_fn_trait_bound` for `const fn` with trait bounds
* `const_fn_unsize` for unsizing coercions in `const fn` (looks like only `dyn` unsizing is still guarded here)
I don't know if there are even any things left that `const_fn` guards... at least libcore and liballoc do not need it any more.
`@oli-obk` are you currently able to do reviews?
Mention FusedIterator case in Iterator::fuse doc
Using `fuse` on an iterator that incorrectly implements
`FusedIterator` does not fuse the iterator. This commit adds a
note about this in the documentation of this method to increase
awareness about this potential issue (esp. when relying on fuse
in unsafe code).
Closes#83969
implement `TrustedRandomAccess` for `Take` iterator adapter
`TrustedRandomAccess` requires the iterator length to fit within `usize`. `take(n)` only constrains the upper bound of an iterator. So if the inner is `TrustedRandomAccess` (which already implies a finite length) then so can be `Take`.
```````@rustbot``````` label T-libs-impl
Improve `Iterator::by_ref` example
I split the example into two: one that fails to compile, and one that
works. I also made them identical except for the addition of `by_ref`
so we don't confuse readers with random differences.
cc `@steveklabnik,` who is the one that added the previous version of this example
Using `fuse` on an iterator that incorrectly implements
`FusedIterator` does not fuse the iterator. This commit adds a
note about this in the documentation of this method to increase
awareness about this potential issue (esp. when relying on fuse
in unsafe code).
Added CharIndices::offset function
The CharIndices iterator has a field internally called front_offset, that I think would be very useful to have access to.
You can already do something like ``char_indices.next().map(|(offset, _)| offset)``, but that is wordy, in addition to not handling the case where the iterator has ended, where you'd want the offset to be equal to the length.
I'm very new to the open source world and the rust repository, so I'm sorry if I missed a step or did something weird.
Implement indexing slices with pairs of core::ops::Bound<usize>
Closes#49976.
I am not sure about code duplication between `check_range` and `into_maybe_range`. Should be former implemented in terms of the latter? Also this PR doesn't address code duplication between `impl SliceIndex for Range*`.
Format `Struct { .. }` on one line even with `{:#?}`.
The result of `debug_struct("A").finish_non_exhaustive()` before this change:
```
A {
..
}
```
And after this change:
```
A { .. }
```
If there's any fields, the result stays unchanged:
```
A {
field: value,
..
}
fix 'const-stable since' for NonZeroU*::new_unchecked
For the unsigned `NonZero` types, `new_unchecked` was const-stable from the start with https://github.com/rust-lang/rust/pull/50808. Fix the docs to accurately reflect that.
I think this `since` is also incorrect:
```rust
#[stable(feature = "from_nonzero", since = "1.31.0")]
impl From<$Ty> for $Int {
```
The signed nonzero types were only stabilized in 1.34, so that `From` impl certainly didn't exist before. But I had enough of digging through git histories after I figured out when `new_unchecked` became const-stable...^^
Replace all `fmt.pad` with `debug_struct`
This replaces any occurrence of:
- `f.pad("X")` with `f.debug_struct("X").finish()`
- `f.pad("X { .. }")` with `f.debug_struct("X").finish_non_exhaustive()`
This is in line with existing formatting code such as
1255053067/library/std/src/sync/mpsc/mod.rs (L1470-L1475)
Deprecate the core::raw / std::raw module
It only contains the `TraitObject` struct which exposes components of wide pointer. Pointer metadata APIs are designed to replace this: https://github.com/rust-lang/rust/issues/81513
Add some #[inline(always)] to arithmetic methods of integers
I tried to add it only to methods which return results of intrinsics and don't have any branching.
Branching could made performance of debug builds (`-Copt-level=0`) worse.
Main goal of changes is allowing wider optimizations in `-Copt-level=1`.
Closes: https://github.com/rust-lang/rust/issues/75598
r? `@nagisa`
No compiler changes as part of this -- just new unstable traits and impls thereof.
The goal here is to add the things that aren't going to break anything, to keep the feature implementation simpler in the next PR.
add lint deref_nullptr detecting when a null ptr is dereferenced
fixes#83856
changelog: add lint that detect code like
```rust
unsafe {
&*core::ptr::null::<i32>()
};
unsafe {
addr_of!(std::ptr::null::<i32>())
};
let x: i32 = unsafe {*core::ptr::null()};
let x: i32 = unsafe {*core::ptr::null_mut()};
unsafe {*(0 as *const i32)};
unsafe {*(core::ptr::null() as *const i32)};
```
```
warning: Dereferencing a null pointer causes undefined behavior
--> src\main.rs:5:26
|
5 | let x: i32 = unsafe {*core::ptr::null()};
| ^^^^^^^^^^^^^^^^^^
| |
| a null pointer is dereferenced
| this code causes undefined behavior when executed
|
= note: `#[warn(deref_nullptr)]` on by default
```
Limitation:
It does not detect code like
```rust
const ZERO: usize = 0;
unsafe {*(ZERO as *const i32)};
```
or code where `0` is not directly a literal
I tried to add it only to methods which return results of intrinsics and don't have any branching.
Branching could made performance of debug builds (`-Copt-level=0`) worse.
Main goal of changes is allowing wider optimizations in `-Copt-level=1`.
Closes: https://github.com/rust-lang/rust/issues/75598
Add note about reverting a workaround in the future
The root cause was fixed upstream in LLVM main. This adds a reminder to revert the workaround once the LLVM rustc depends on is new enough. Since I'm not sure how such optimizations get routed to LLVM releases, I used the conservative assumption that it will only show up with LLVM 13.
The root cause was fixed upstream in LLVM main. This adds a reminder to revert the workaround once the LLVM rustc depends on is new enough. Since I'm not sure how such optimizations get routed to LLVM releases, I used the conservative assumption that it will only show up with LLVM 13.
Stabilize `peekable_peek_mut`
Resolves#78302. Also adds some documentation on `std::iter::Iterator::peekable()` regarding the new method.
The feature was added in #77491 in Nov' 20, which is recently, but the feature seems reasonably small. Never did a stabilization-pr, excuse my ignorance if there is a protocol I'm not aware of.
Improve links in inline code in `core::pin`.
## Context
So I recently opened #80720. That PR uses HTML-based `<code>foo</code>` syntax in place of `` `foo` `` for some inline code. It looks like usage of `<code>` tags in doc comments is without precedent in the standard library, but the HTML-based syntax has an important advantage:
You can write something like
```
<code>[Box]<[Option]\<T>></code>
```
which becomes: <code>[Box]<[Option]\<T>></code>, whereas with ordinary backtick syntax, you cannot create links for a substring of an inline code block.
## Problem
I recalled (from my own experience) that a way to partially work around this limitation is to do something like
```
[`Box`]`<`[`Option`]`<T>>`
```
which looks like this: [`Box`]`<`[`Option`]`<T>>` _(admitted, it looks even worse on GitHub than in `rustdoc`’s CSS)_.
[Box]: https://doc.rust-lang.org/std/boxed/struct.Box.html "Box"
[`Box`]: https://doc.rust-lang.org/std/boxed/struct.Box.html "Box"
[Option]: https://doc.rust-lang.org/std/option/enum.Option.html "Option"
[`Option`]: https://doc.rust-lang.org/std/option/enum.Option.html "Option"
[Pin]: https://doc.rust-lang.org/std/pin/struct.Pin.html "Pin"
[&mut]: https://doc.rust-lang.org/std/primitive.reference.html "mutable reference"
So I searched the standard library and found that e.g. the [std::pin](https://doc.rust-lang.org/std/pin/index.html) module documentation uses this hack/workaround quite a bit, with types like <code>[Pin]<[Box]\<T>></code> or <code>[Pin]<[&mut] T>></code>. Although the way they look like in this sentence is what I would like them to look like, not what they currently look.
### Status Quo
Here’s a screenshot of what it currently looks like:
![Screenshot_20210105_202751](https://user-images.githubusercontent.com/3986214/103692608-4a978780-4f98-11eb-9451-e13622b2e3c0.png)
With a few HTML-style code blocks, we can fix all the spacing issues in the above screenshot that are due usage of this hack/workaround of putting multiple code blocks right next to each other being used.
### after d3915c555e:
![Screenshot_20210105_202932](https://user-images.githubusercontent.com/3986214/103692688-6f8bfa80-4f98-11eb-9be5-9b370eaef644.png)
There’s still a problem of inconsistency. Especially in a sentence such as
> A [`Pin<P>`][Pin] where `P: Deref` should be considered as a "`P`-style pointer" to _[...]_
looks weird with the variable `P` having different colors (and `Deref` has a different color from before where it was a link, too). Or compare the difference of <code>[Pin]<[Box]\<T>></code> vs [`Box<T>`][Box] where one time the variable is part of the link and the other time it isn’t.
_Note: Color differences show even **more strongly** when the ayu theme is used, while they are a bit less prominent in the light theme than they are in the dark theme, which is the one used for these screenshots._
This is why I’ve added the next commit
### after ceaeb249a3
![Screenshot_20210105_203113](https://user-images.githubusercontent.com/3986214/103693496-ab738f80-4f99-11eb-942d-29dace459734.png)
pulling all the type parameters out of their links, and also the last commit with clearly visible changes
### after 87ac118ba3
![Screenshot_20210105_203252](https://user-images.githubusercontent.com/3986214/103693625-e5dd2c80-4f99-11eb-91b7-470c37934e7e.png)
where more links are added, removing e.g. the inconsistency with `Deref`’s color in e.g. `P: Deref` that I already mentioned above.
## Discussion
I am aware that this PR may very well be overkill. If for now only the first commit (plus the fix for the `Drop` link in e65385fbfa, the link titles 684edf7a70 as far as they apply, and a few of the line-break changes) are wanted, I can reduce this PR to just those changes. I personally find the rendered result with all these changes very nice though. On the other hand, all these `<code>` tags are not very nice in the source code, I’ll admit.
Perhaps alternative solutions could be preferred, such as `rustdoc` support for merging subsequent inline code blocks so that all the cases that currently use workarounds rendered as [`Box`]`<`[`Option`]`<T>>` automatically become <code>[Box]<[Option]\<T>></code> without any need for further changes. Even in this case, having a properly formatted, better looking example in the standard library docs could help motivate such a change to `rustdoc` by prodiving an example of the expected results and also the already existing alternative (i.e. using `<code>`). On the other hand, `` [`Box`]`<`[`Option`]`<T>>` `` isn’t particularly nice-looking source code either. I’m not even sure if I wouldn’t actually find the version `<code>[Box]<[Option]\<T>></code>` cleaner to read.
`@rustbot` modify labels: T-doc, T-rustdoc
Add more info for common trait resolution and async/await errors
* Suggest `Pin::new`/`Box::new`/`Arc::new`/`Box::pin` in more cases
* Point at `impl` and type defs introducing requirements on E0277
Stabilize cmp_min_max_by
I would like to propose cmp::{min_by, min_by_key, max_by, max_by_key}
for stabilization.
These are relatively simple and seemingly uncontroversial functions and
have been unchanged in unstable for a while now.
Closes: #64460
I would like to propose cmp::{min_by, min_by_key, max_by, max_by_key}
for stabilization.
These are relatively simple and seemingly uncontroversial functions and
have been unchanged in unstable for a while now.
Use `#[inline(always)]` on trivial UnsafeCell methods
UnsafeCell is the standard building block for shared mutable data
structures. UnsafeCell should add zero overhead compared to using raw
pointers directly.
Some reports suggest that debug builds, or even builds at opt-level 1,
may not always be inlining its methods. Mark the methods as
`#[inline(always)]`, since once inlined the methods should result in no
actual code other than field accesses.
Bump bootstrap to 1.52 beta
This includes the standard bump, but also a workaround for new cargo behavior around clearing out the doc directory when the rustdoc version changes.
core: disable `ptr::swap_nonoverlapping_one`'s block optimization on SPIR-V.
SPIR-V primarily supports what it calls the "Logical addressing model" (and AFAIK for graphical shaders it's the only option), and what that implies is that there is no "memory" to uniformly address at some byte/word level, and that you can't really talk about values having a "raw representation" in terms of sequences of bytes. Therefore, the "block"-wise swapping optimization employed by `ptr::swap_nonoverlapping_one` (where a "block" is 32 bytes, currently), is fundamentally incompatible with SPIR-V "memory".
As such, [Rust-GPU](https://github.com/EmbarkStudios/rust-gpu/)'s `rustc_codegen_spirv` backend cannot currently allow the use of `ptr::swap_nonoverlapping_one` - but that comes at a great price, since it's the building block of `mem::{swap,replace}`, and those in turn are used by e.g. `Option::take` and `Range`'s `Iterator` implementation (the latter blocking the use of `for i in 0..n` loops).
There's 4 options I can see in terms of supporting `ptr::swap_nonoverlapping_one` in `rustc_codegen_spirv`:
* legalize the block-wise swap loop back into swapping whole values, for SPIR-V
* this is made borderline impossible by the fact that the size of the state "on the stack" is a block, and has to be expanded back to the appropriate size of the value being swapped, so in practice this would have to effectively pattern-match on the exact shape of the block-wise swapping algorithm, as a roundabout way of "patching `core::ptr` on the fly"
* (**this PR**) disable the block-wise swap optimization altogether when `#[cfg(target_arch = "spirv")`
* I've tested it and it does in fact allow compiling `for i in 0..n` loops, which was my primary motivation
* main downside IMO is the fact that `core` now acknowledges an out-of-tree backend
* as a counterpoint, any attempt to compile Rust to SPIR-V would run into this problem, one way or another
* only enable the block-wise swap optimization on targets where it's been empirically proven to be an improvement
* would avoid any surprises in terms of potentially-broken/inefficient codegen, in general
* however, it may be universally applicable (thanks to caches), even if the optimal block size could differ
* move low-level swapping into an intrinsic, where the backend can choose any optimization approach it wants
* this also has an impact on MIR optimizations (cc ``@rust-lang/wg-mir-opt)`` - which currently cannot hope to make sense of e.g. `Option::take` despite it being effectively `_0 = *_1;` `*_1 = None;` `return;`
* long-term this is my preferred approach, and I can start working on it if that's desired, but I wanted to confirm that this swapping optimization is the final blocker for [Rust-GPU](https://github.com/EmbarkStudios/rust-gpu/) supporting e.g. range `for` loops
r? ``@nagisa`` cc ``@rust-lang/libs``
UnsafeCell is the standard building block for shared mutable data
structures. UnsafeCell should add zero overhead compared to using raw
pointers directly.
Some reports suggest that debug builds, or even builds at opt-level 1,
may not always be inlining its methods. Mark the methods as
`#[inline(always)]`, since once inlined the methods should result in no
actual code other than field accesses.
Rename `#[doc(spotlight)]` to `#[doc(notable_trait)]`
Fixes#80936.
"spotlight" is not a very specific or self-explaining name.
Additionally, the dialog that it triggers is called "Notable traits".
So, "notable trait" is a better name.
* Rename `#[doc(spotlight)]` to `#[doc(notable_trait)]`
* Rename `#![feature(doc_spotlight)]` to `#![feature(doc_notable_trait)]`
* Update documentation
* Improve documentation
r? `@Manishearth`
Improve pointer arithmetic docs
* Add slightly more detailed definition of "allocated object" to the module docs, and link it from everywhere.
* Clarify the "remains attached" wording a bit (at least I hope this is clearer).
* Remove the sentence about using integer arithmetic; this seems to confuse people even if it is technically correct.
As usual, the edit needs to be done in a dozen places to remain consistent, I hope I got them all.
Instruct LLVM that binary_search returns a valid index
This allows removing bound checks when the return value of `binary_search` is used to index into the slice it was call on. I also added a codegen test for this, not sure if it's the right thing to do (I didn't find anything on the dev guide), but it felt so.
Add function core::iter::zip
This makes it a little easier to `zip` iterators:
```rust
for (x, y) in zip(xs, ys) {}
// vs.
for (x, y) in xs.into_iter().zip(ys) {}
```
You can `zip(&mut xs, &ys)` for the conventional `iter_mut()` and
`iter()`, respectively. This can also support arbitrary nesting, where
it's easier to see the item layout than with arbitrary `zip` chains:
```rust
for ((x, y), z) in zip(zip(xs, ys), zs) {}
for (x, (y, z)) in zip(xs, zip(ys, zs)) {}
// vs.
for ((x, y), z) in xs.into_iter().zip(ys).zip(xz) {}
for (x, (y, z)) in xs.into_iter().zip((ys.into_iter().zip(xz)) {}
```
It may also format more nicely, especially when the first iterator is a
longer chain of methods -- for example:
```rust
iter::zip(
trait_ref.substs.types().skip(1),
impl_trait_ref.substs.types().skip(1),
)
// vs.
trait_ref
.substs
.types()
.skip(1)
.zip(impl_trait_ref.substs.types().skip(1))
```
This replaces the tuple-pair `IntoIterator` in #78204.
There is prior art for the utility of this in [`itertools::zip`].
[`itertools::zip`]: https://docs.rs/itertools/0.10.0/itertools/fn.zip.html
update array missing `IntoIterator` msg
fixes#82602
r? ```@estebank``` do you know whether we can use the expr span in `rustc_on_unimplemented`? The label isn't too great rn
make unaligned_references future-incompat lint warn-by-default
and also remove the safe_packed_borrows lint that it replaces.
`std::ptr::addr_of!` has hit beta now and will hit stable in a month, so I propose we start fixing https://github.com/rust-lang/rust/issues/27060 for real: creating a reference to a field of a packed struct needs to eventually become a hard error; this PR makes it a warn-by-default future-incompat lint. (The lint already existed, this just raises its default level.) At the same time I removed the corresponding code from unsafety checking; really there's no reason an `unsafe` block should make any difference here.
For references to packed fields outside `unsafe` blocks, this means `unaligned_refereces` replaces the previous `safe_packed_borrows` warning with a link to https://github.com/rust-lang/rust/issues/82523 (and no more talk about unsafe blocks making any difference). So behavior barely changes, the warning is just worded differently. For references to packed fields inside `unsafe` blocks, this PR shows a new future-incompat warning.
Closes https://github.com/rust-lang/rust/issues/46043 because that lint no longer exists.
Generalize and inline slice::fill specializations
This makes the memset specialization applicable to more types. And since the code now lives in a generic method it is also eligible for cross-crate inlining which should fix#83235
Add IEEE 754 compliant fmt/parse of -0, infinity, NaN
This pull request improves the Rust float formatting/parsing libraries to comply with IEEE 754's formatting expectations around certain special values, namely signed zero, the infinities, and NaN. It also adds IEEE 754 compliance tests that, while less stringent in certain places than many of the existing flt2dec/dec2flt capability tests, are intended to serve as the beginning of a roadmap to future compliance with the standard. Some relevant documentation is also adjusted with clarifying remarks.
This PR follows from discussion in https://github.com/rust-lang/rfcs/issues/1074, and closes#24623.
The most controversial change here is likely to be that -0 is now printed as -0. Allow me to explain: While there appears to be community support for an opt-in toggle of printing floats as if they exist in the naively expected domain of numbers, i.e. not the extended reals (where floats live), IEEE 754-2019 is clear that a float converted to a string should be capable of being transformed into the original floating point bit-pattern when it satisfies certain conditions (namely, when it is an actual numeric value i.e. not a NaN and the original and destination float width are the same). -0 is given special attention here as a value that should have its sign preserved. In addition, the vast majority of other programming languages not only output `-0` but output `-0.0` here.
While IEEE 754 offers a broad leeway in how to handle producing what it calls a "decimal character sequence", it is clear that the operations a language provides should be capable of round tripping, and it is confusing to advertise the f32 and f64 types as binary32 and binary64 yet have the most basic way of producing a string and then reading it back into a floating point number be non-conformant with the standard. Further, existing documentation suggested that e.g. -0 would be printed with -0 regardless of the presence of the `+` fmt character, but it prints "+0" instead if given such (which was what led to the opening of #24623).
There are other parsing and formatting issues for floating point numbers which prevent Rust from complying with the standard, as well as other well-documented challenges on the arithmetic level, but I hope that this can be the beginning of motion towards solving those challenges.
This makes it a little easier to `zip` iterators:
```rust
for (x, y) in zip(xs, ys) {}
// vs.
for (x, y) in xs.into_iter().zip(ys) {}
```
You can `zip(&mut xs, &ys)` for the conventional `iter_mut()` and
`iter()`, respectively. This can also support arbitrary nesting, where
it's easier to see the item layout than with arbitrary `zip` chains:
```rust
for ((x, y), z) in zip(zip(xs, ys), zs) {}
for (x, (y, z)) in zip(xs, zip(ys, zs)) {}
// vs.
for ((x, y), z) in xs.into_iter().zip(ys).zip(xz) {}
for (x, (y, z)) in xs.into_iter().zip((ys.into_iter().zip(xz)) {}
```
It may also format more nicely, especially when the first iterator is a
longer chain of methods -- for example:
```rust
iter::zip(
trait_ref.substs.types().skip(1),
impl_trait_ref.substs.types().skip(1),
)
// vs.
trait_ref
.substs
.types()
.skip(1)
.zip(impl_trait_ref.substs.types().skip(1))
```
This replaces the tuple-pair `IntoIterator` in rust-lang/rust#78204.
There is prior art for the utility of this in [`itertools::zip`].
[`itertools::zip`]: https://docs.rs/itertools/0.10.0/itertools/fn.zip.html
Fixes#83046
The program
fn main() {
println!("{:?}", '"');
println!("{:?}", "'");
}
would previously print
'\"'
"\'"
With this patch it now prints:
'"'
"'"
Add Result::into_err where the Ok variant is the never type
Equivalent of #66045 but for the inverse situation where `T: Into<!>` rather than `E: Into<!>`.
I'm using the same feature gate name. I can't see why one of these methods would be OK to stabilize but not the other.
Tracking issue: #61695
Remove Option::{unwrap_none, expect_none}.
This removes `Option::unwrap_none` and `Option::expect_none` since we're not going to stabilize them, see https://github.com/rust-lang/rust/issues/62633.
Closes#62633
stabilize debug_non_exhaustive
tracking issue: https://github.com/rust-lang/rust/issues/67364
but it is still an open question whether the other `Debug*` struct's should have a similar method. I would guess that would best be put underneath a new feature gate, as this one seems uncontroversial enough to stabilize as is