Add truncate note to Vec::resize
A very minor addition to the `Vec::resize` documentation to point out the `truncate` method.
When I was searching for something matching `truncate` I managed to miss it, along with some colleagues. We later found it by chance. We did find `resize` however, so I was hoping to point it out in the documentation.
Partially stabilize `array_methods`
This stabilizes `<[T; N]>::as_slice` and `<[T; N]>::as_mut_slice`, which is forms part of the `array_methods` feature: #76118.
This also makes `<[T; N]>::as_slice` const due to its trivial nature.
Manual Debug for Unix ExitCode ExitStatus ExitStatusError
These structs have misleading names. An ExitStatus[Error] is actually a Unix wait status; an ExitCode is actually an exit status. These misleading names appear in the `Debug` output.
The `Display` impls on Unix have been improved, but the `Debug` impls are still misleading, as reported in #74832.
Fix this by pretending that these internal structs are called `unix_exit_status` and `unix_wait_status` as applicable. (We can't actually rename the structs because of the way that the cross-platform machinery works: the names are cross-platform.)
After this change, this program
```
#![feature(exit_status_error)]
fn main(){
let x = std::process::Command::new("false").status().unwrap();
dbg!(x.exit_ok());
eprintln!("x={:?}",x);
}
```
produces this output
```
[src/main.rs:4] x.exit_ok() = Err(
ExitStatusError(
unix_wait_status(
256,
),
),
)
x=ExitStatus(unix_wait_status(256))
```
Closes#74832
Remove unnecessary unsafe block in `process_unix`
Because it's nested under this unsafe fn!
This block isn't detected as unnecessary because of a bug in the compiler: #88260.
Mark unsafe methods NonZero*::unchecked_(add|mul) as const.
Now that https://github.com/rust-lang/rfcs/pull/3016 has landed, these two unstable `std` function can be marked `const`, according to this detail of #84186.
const fn for option copied, take & replace
Tracking issue: [#67441](https://github.com/rust-lang/rust/issues/67441)
Adding const fn for the copied, take and replace method of Option. Also adding necessary unit test.
It's my first contribution so I am pretty sure I don't know what I'm doing but there's a first for everything!
Add `Ipv6Addr::is_benchmarking`
This PR adds the unstable method `Ipv6Addr::is_benchmarking`. This method is added for parity with `Ipv4Addr::is_benchmarking`, and I intend to use it in a future rework of `Ipv6Addr::is_global` (edit: #86634) to more accurately follow the [IANA Special Address Registry](https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml) (like is done in `Ipv4Addr::is_global`).
With `Ipv6Addr::is_benchmarking` and `Ipv4Addr::is_benchmarking` now both existing, `IpAddr::is_benchmarking` is also added.
Fix read_to_end to not grow an exact size buffer
If you know how much data to expect and use `Vec::with_capacity` to pre-allocate a buffer of that capacity, `Read::read_to_end` will still double its capacity. It needs some space to perform a read, even though that read ends up returning `0`.
It's a bummer to carefully pre-allocate 1GB to read a 1GB file into memory and end up using 2GB.
This fixes that behavior by special casing a full buffer and reading into a small "probe" buffer instead. If that read returns `0` then it's confirmed that the buffer was the perfect size. If it doesn't, the probe buffer is appended to the normal buffer and the read loop continues.
Fixing this allows several workarounds in the standard library to be removed:
- `Take` no longer needs to override `Read::read_to_end`.
- The `reservation_size` callback that allowed `Take` to inhibit the previous over-allocation behavior isn't needed.
- `fs::read` doesn't need to reserve an extra byte in `initial_buffer_size`.
Curiously, there was a unit test that specifically checked that `Read::read_to_end` *does* over-allocate. I removed that test, too.
Make `<[T]>::split_at_unchecked` and `<[T]>::split_at_mut_unchecked` public
The methods were originally added in https://github.com/rust-lang/rust/pull/75936 (30dc32b10e), but for some reason as private. Nevertheless, the methods have documentation and even a [tracking issue](https://github.com/rust-lang/rust/issues/76014).
It's very weird to have a tracking issue for private methods and these methods may be useful outside of the standard library. As such, this PR makes the methods public.
Use bitand when checking for signed integer division overflow
For `self == Self::MIN && rhs == -1`, LLVM does not realize that this is the same check made by `self / rhs`, so the code generated may have some unnecessary duplication. For `(self == Self::MIN) & (rhs == -1)`, LLVM realizes it is the same check.
Optimize unnecessary check in Vec::retain
The function `vec::Vec::retain` only have two stages:
1. Nothing was deleted.
2. Some elements were deleted.
Here is an unnecessary check `if g.deleted_cnt > 0` in the loop, and it's difficult for compiler to optimize it. I split the loop into two stages manully and keep the code clean using const generics.
I write a special but common bench case for this optimization. I call retain on vec but keep all elements.
Before and after this optimization:
```
test vec::bench_retain_whole_100000 ... bench: 84,803 ns/iter (+/- 17,314)
```
```
test vec::bench_retain_whole_100000 ... bench: 42,638 ns/iter (+/- 16,910)
```
The result is expected, there are two `if`s before the optimization and one `if` after.
On MinGW toolchains the various features (such as function sections)
necessary to eliminate dead function references are disabled due to
various bugs. This means that the windows sockets library will most
likely remain linked to any mingw toolchain built program that also
utilizes libstd.
That said, I made an attempt to also enable `function-sections` and
`--gc-sections` during my experiments, but the symbol references
remained, sadly.
For `self == Self::MIN && rhs == -1`, LLVM does not realize that this is the
same check made by `self / rhs`, so the code generated may have some unnecessary
duplication. For `(self == Self::MIN) & (rhs == -1)`, LLVM realizes it is the
same check.
Constify ?-operator for Result and Option
Try to make `?`-operator usable in `const fn` with `Result` and `Option`, see #74935 . Note that the try-operator itself was constified in #87237.
TODO
* [x] Add tests for const T -> T conversions
* [x] cleanup commits
* [x] Remove `#![allow(incomplete_features)]`
* [?] Await decision in #86808 - I'm not sure
* [x] Await support for parsing `~const` in bootstrapping compiler
* [x] Tracking issue(s)? - #88674
Remove ignore-tidy-undocumented-unsafe from core::slice::sort
Write down the missing safety arguments to be able to remove `ignore-tidy-undocumented-unsafe` from `core::slice::sort`.
Helps with #66219
``@rustbot`` label C-cleanup T-libs
Restructure std::rt
These changes should reduce binary size slightly while at the same slightly improving performance of startup, thread spawning and `std:🧵:current()`. I haven't verified if the compiler is able to optimize some of these cases already, but at least for some others the compiler is unable to do these optimizations as they slightly change behavior in cases where program startup would crash anyway by omitting a backtrace and panic location.
I can remove 6f6bb16 if preferred.
The reference automatically coerces to a pointer. Writing an explicit
cast here is slightly misleading because that's most commonly used when
a pointer needs to be converted from one pointer type to another, e.g.
`*const c_void` to `*const sigaction` or vice versa.
The `Step` trait guarantees that `Range<impl Step>` yields items in
sorted order. We can override the `Iterator::is_sorted` method based on
this guarantee, as we already do for `Iterator::min` and `max`.
make junit output more consistent with default format
The default format of libtest includes new-lines between each section to ensure the label output from cargo is on it's own line
<pre><font color="#A1B56C"><b>❯</b></font> <font color="#A1B56C">cargo</font><font color="#D8D8D8"> </font><font color="#A1B56C">test</font>
<font color="#A1B56C"><b> Compiling</b></font> test-test v0.1.0 (/home/jlusby/tmp/test-test)
<font color="#A1B56C"><b> Finished</b></font> test [unoptimized + debuginfo] target(s) in 0.59s
<font color="#A1B56C"><b> Running</b></font> unittests (target/debug/deps/test_test-639f369234319c09)
running 1 test
test tests::it_works ... <font color="#A1B56C">ok</font>
test result: <font color="#A1B56C">ok</font>. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
<font color="#A1B56C"><b> Doc-tests</b></font> test-test
running 0 tests
test result: <font color="#A1B56C">ok</font>. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
</pre>
But when the junit outputter was added to libtest these newlines were omitted, resulting in some "fun" output when run via cargo.
Note the `Doc-tests` text at the end of the first line of xml.
<pre><font color="#A1B56C"><b>❯</b></font> <font color="#A1B56C">cargo</font><font color="#D8D8D8"> </font><font color="#A1B56C">test</font><font color="#D8D8D8"> </font><font color="#A1B56C">--</font><font color="#D8D8D8"> </font><font color="#A1B56C">-Zunstable-options</font><font color="#D8D8D8"> </font><font color="#A1B56C">--format</font><font color="#D8D8D8"> </font><font color="#A1B56C">junit</font>
<font color="#A1B56C"><b> Finished</b></font> test [unoptimized + debuginfo] target(s) in 0.00s
<font color="#A1B56C"><b> Running</b></font> unittests (target/debug/deps/test_test-639f369234319c09)
<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="test" package="test" id="0" errors="0" failures="0" tests="1" skipped="0" ><testcase classname="tests" name="it_works" time="0"/><system-out/><system-err/></testsuite></testsuites><font color="#A1B56C"><b> Doc-tests</b></font> test-test
<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="test" package="test" id="0" errors="0" failures="0" tests="0" skipped="0" ><system-out/><system-err/></testsuite></testsuites>
</pre>
After this PR the junit output includes the same style of newlines as the pretty format
<pre><font color="#A1B56C"><b>❯</b></font> <font color="#A1B56C">cargo</font><font color="#D8D8D8"> </font><font color="#A1B56C">test</font><font color="#D8D8D8"> </font><font color="#A1B56C">--</font><font color="#D8D8D8"> </font><font color="#A1B56C">-Zunstable-options</font><font color="#D8D8D8"> </font><font color="#A1B56C">--format</font><font color="#D8D8D8"> </font><font color="#A1B56C">junit</font>
<font color="#A1B56C"><b> Compiling</b></font> test-test v0.1.0 (/home/jlusby/tmp/test-test)
<font color="#A1B56C"><b> Finished</b></font> test [unoptimized + debuginfo] target(s) in 0.39s
<font color="#A1B56C"><b> Running</b></font> unittests (target/debug/deps/test_test-42c2320bb9450c69)
<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="test" package="test" id="0" errors="0" failures="0" tests="1" skipped="0" ><testcase classname="tests" name="it_works" time="0"/><system-out/><system-err/></testsuite></testsuites>
<font color="#A1B56C"><b> Doc-tests</b></font> test-test
<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="test" package="test" id="0" errors="0" failures="0" tests="0" skipped="0" ><system-out/><system-err/></testsuite></testsuites>
</pre>
Add SOLID targets
This PR introduces new tier 3 targets for [SOLID](https://www.kmckk.co.jp/eng/SOLID/) embedded development platform by Kyoto Microcomputer Co., Ltd.
| Target name | `target_arch` | `target_vendor` | `target_os` |
|--------------------------------|---------------|-----------------|--------------|
| `aarch64-kmc-solid_asp3` | `aarch64` | `kmc` | `solid_asp3` |
| `armv7a-kmc-solid_asp3-eabi` | `arm` | `kmc` | `solid_asp3` |
| `armv7a-kmc-solid_asp3-eabihf` | `arm` | `kmc` | `solid_asp3` |
## Related PRs
- [ ] `libc`: https://github.com/rust-lang/libc/pull/2227
- [ ] `cc`: https://github.com/alexcrichton/cc-rs/pull/609
## Non-blocking Issues
- [ ] The target kernel can support `Thread::unpark` directly, but this property is not utilized because the underlying kernel feature is used to implement `Condvar` and it's unclear whether `std` should guarantee that parking tokens are not clobbered by other synchronization primitives.
- [ ] The rustc book: The page title "\*-kmc-solid-\*" shows up as "-kmc-solid-" in TOC
## Tier 3 Target Policy
As tier 3 targets, the new targets are required to adhere to [the tier 3 target policy](https://doc.rust-lang.org/nightly/rustc/target-tier-policy.html#tier-3-target-policy) requirements. This section quotes each requirement in entirety and describes how they are met.
> - A tier 3 target must have a designated developer or developers (the "target maintainers") on record to be CCed when issues arise regarding the target. (The mechanism to track and CC such developers may evolve over time.)
See [`src/doc/rustc/src/platform-support/kmc-solid.md`](https://github.com/kawadakk/rust/blob/release-add-solid-support/src/doc/rustc/src/platform-support/kmc-solid.md).
> - Targets must use naming consistent with any existing targets; for instance, a target for the same CPU or OS as an existing Rust target should use the same name for that CPU or OS. Targets should normally use the same names and naming conventions as used elsewhere in the broader ecosystem beyond Rust (such as in other toolchains), unless they have a very good reason to diverge. Changing the name of a target can be highly disruptive, especially once the target reaches a higher tier, so getting the name right is important even for a tier 3 target.
> - Target names should not introduce undue confusion or ambiguity unless absolutely necessary to maintain ecosystem compatibility. For example, if the name of the target makes people extremely likely to form incorrect beliefs about what it targets, the name should be changed or augmented to disambiguate it.
The new target names follow this format: `$ARCH-$VENDOR-$OS-$ABI`, which is already adopted by most existing targets. `$ARCH` and `$ABI` follow the convention: `aarch64-*` for AArch64, `armv7a-*-eabi` for Armv7-A with EABI. `$OS` is used to distinguish multiple variations of the platform in a somewhat similar way to the Apple targets, though we are only adding one variation in this PR. `$VENDOR` denotes the platform vendor name similarly to the Apple, Solaris, SGX, and VxWorks targets.
`$OS` corresponds to the value of `target_os` and takes the format `solid-$KERNEL`. The inclusion of a hyphen prevents unique decomposition of target names, though the mapping between target names and target attributes isn't trivial in the first place, e.g., because of the Android targets.
More targets may be added later, as we support other base kernels (there are at least three at the point of writing) and are interested in supporting other processor architectures in the future.
> - Tier 3 targets may have unusual requirements to build or use, but must not create legal issues or impose onerous legal terms for the Rust project or for Rust developers or users.
> - The target must not introduce license incompatibilities.
> - Anything added to the Rust repository must be under the standard Rust license (`MIT OR Apache-2.0`).
> - The target must not cause the Rust tools or libraries built for any other host (even when supporting cross-compilation to the target) to depend on any new dependency less permissive than the Rust licensing policy. This applies whether the dependency is a Rust crate that would require adding new license exceptions (as specified by the `tidy` tool in the rust-lang/rust repository), or whether the dependency is a native library or binary. In other words, the introduction of the target must not cause a user installing or running a version of Rust or the Rust tools to be subject to any new license requirements.
> - If the target supports building host tools (such as `rustc` or `cargo`), those host tools must not depend on proprietary (non-FOSS) libraries, other than ordinary runtime libraries supplied by the platform and commonly used by other binaries built for the target. For instance, `rustc` built for the target may depend on a common proprietary C runtime library or console output library, but must not depend on a proprietary code generation library or code optimization library. Rust's license permits such combinations, but the Rust project has no interest in maintaining such combinations within the scope of Rust itself, even at tier 3.
> - Targets should not require proprietary (non-FOSS) components to link a functional binary or library.
> - "onerous" here is an intentionally subjective term. At a minimum, "onerous" legal/licensing terms include but are *not* limited to: non-disclosure requirements, non-compete requirements, contributor license agreements (CLAs) or equivalent, "non-commercial"/"research-only"/etc terms, requirements conditional on the employer or employment of any particular Rust developers, revocable terms, any requirements that create liability for the Rust project or its developers or users, or any requirements that adversely affect the livelihood or prospects of the Rust project or its developers or users.
We intend to make the contribution fully available under the standard Rust license with no additional legal restrictions whatsoever. This PR does not introduce any new dependency less permissive than the Rust license policy, and we are willing to ensure this doesn't happen for future contributions regarding the new targets.
The new targets don't support building host tools.
Although the new targets use a platform-provided C compiler toolchain, it can be substituted by [GNU Arm Embedded Toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm) for testing purposes.
> - Tier 3 targets should attempt to implement as much of the standard libraries as possible and appropriate (`core` for most targets, `alloc` for targets that can support dynamic memory allocation, `std` for targets with an operating system or equivalent layer of system-provided functionality), but may leave some code unimplemented (either unavailable or stubbed out as appropriate), whether because the target makes it impossible to implement or challenging to implement. The authors of pull requests are not obligated to avoid calling any portions of the standard library on the basis of a tier 3 target not implementing those portions.
Most features are implemented. The following features are not implemented due to the lack of native support:
- `fs::File::{file_attr, truncate, duplicate, set_permissions}`
- `fs::{symlink, link, canonicalize}`
- Process creation
- Command-line arguments
~~Networking is not implemented yet, and we intend to add it as soon as it's ready.~~
Edit (2021-07-07): Networking is now implemented.
Backtrace generation is not really a good fit for embedded targets, so it's intentionally left unimplemented. Unwinding is functional, however.
> - The target must provide documentation for the Rust community explaining how to build for the target, using cross-compilation if possible. If the target supports running tests (even if they do not pass), the documentation must explain how to run tests for the target, using emulation if possible or dedicated hardware if necessary.
See [`src/doc/rustc/src/platform-support/kmc-solid.md`](https://github.com/kawadakk/rust/blob/release-add-solid-support/src/doc/rustc/src/platform-support/kmc-solid.md). Running tests is not supported.
> - Neither this policy nor any decisions made regarding targets shall create any binding agreement or estoppel by any party. If any member of an approving Rust team serves as one of the maintainers of a target, or has any legal or employment requirement (explicit or implicit) that might affect their decisions regarding a target, they must recuse themselves from any approval decisions regarding the target's tier status, though they may otherwise participate in discussions.
> - This requirement does not prevent part or all of this policy from being cited in an explicit contract or work agreement (e.g. to implement or maintain support for a target). This requirement exists to ensure that a developer or team responsible for reviewing and approving a target does not face any legal threats or obligations that would prevent them from freely exercising their judgment in such approval, even if such judgment involves subjective matters or goes beyond the letter of these requirements.
> - Tier 3 targets must not impose burden on the authors of pull requests, or other developers in the community, to maintain the target. In particular, do not post comments (automated or manual) on a PR that derail or suggest a block on the PR based on a tier 3 target. Do not send automated messages or notifications (via any medium, including via ``@`)` to a PR author or others involved with a PR regarding a tier 3 target, unless they have opted into such messages.
> - Backlinks such as those generated by the issue/PR tracker when linking to an issue or PR are not considered a violation of this policy, within reason. However, such messages (even on a separate repository) must not generate notifications to anyone involved with a PR who has not requested such notifications.
> - Patches adding or updating tier 3 targets must not break any existing tier 2 or tier 1 target, and must not knowingly break another tier 3 target without approval of either the compiler team or the maintainers of the other tier 3 target.
> - In particular, this may come up when working on closely related targets, such as variations of the same architecture with different features. Avoid introducing unconditional uses of features that another variation of the target may not have; use conditional compilation or runtime detection, as appropriate, to let each target run code supported by that target.
We acknowledge these requirements and intend to ensure they are met.
There are no closely related targets at the moment.
SOLID[1] is an embedded development platform provided by Kyoto
Microcomputer Co., Ltd. This commit introduces a basic Tier 3 support
for SOLID.
# New Targets
The following targets are added:
- `aarch64-kmc-solid_asp3`
- `armv7a-kmc-solid_asp3-eabi`
- `armv7a-kmc-solid_asp3-eabihf`
SOLID's target software system can be divided into two parts: an
RTOS kernel, which is responsible for threading and synchronization,
and Core Services, which provides filesystems, networking, and other
things. The RTOS kernel is a μITRON4.0[2][3]-derived kernel based on
the open-source TOPPERS RTOS kernels[4]. For uniprocessor systems
(more precisely, systems where only one processor core is allocated for
SOLID), this will be the TOPPERS/ASP3 kernel. As μITRON is
traditionally only specified at the source-code level, the ABI is
unique to each implementation, which is why `asp3` is included in the
target names.
More targets could be added later, as we support other base kernels
(there are at least three at the point of writing) and are interested
in supporting other processor architectures in the future.
# C Compiler
Although SOLID provides its own supported C/C++ build toolchain, GNU Arm
Embedded Toolchain seems to work for the purpose of building Rust.
# Unresolved Questions
A μITRON4 kernel can support `Thread::unpark` natively, but it's not
used by this commit's implementation because the underlying kernel
feature is also used to implement `Condvar`, and it's unclear whether
`std` should guarantee that parking tokens are not clobbered by other
synchronization primitives.
# Unsupported or Unimplemented Features
Most features are implemented. The following features are not
implemented due to the lack of native support:
- `fs::File::{file_attr, truncate, duplicate, set_permissions}`
- `fs::{symlink, link, canonicalize}`
- Process creation
- Command-line arguments
Backtrace generation is not really a good fit for embedded targets, so
it's intentionally left unimplemented. Unwinding is functional, however.
## Dynamic Linking
Dynamic linking is not supported. The target platform supports dynamic
linking, but enabling this in Rust causes several problems.
- The linker invocation used to build the shared object of `std` is
too long for the platform-provided linker to handle.
- A linker script with specific requirements is required for the
compiled shared object to be actually loadable.
As such, we decided to disable dynamic linking for now. Regardless, the
users can try to create shared objects by manually invoking the linker.
## Executable
Building an executable is not supported as the notion of "executable
files" isn't well-defined for these targets.
[1] https://solid.kmckk.com/SOLID/
[2] http://ertl.jp/ITRON/SPEC/mitron4-e.html
[3] https://en.wikipedia.org/wiki/ITRON_project
[4] https://toppers.jp/
Fix spacing of links in inline code.
Similar to #80733, but the focus is different. This PR eliminates all occurrences of pieced-together inline code blocks like [`Box`]`<`[`Option`]`<T>>` and replaces them with good-looking ones (using HTML-syntax), like <code>[Box]<[Option]\<T>></code>. As far as I can tell, I should’ve found all of these in the standard library (regex search with `` r"`\]`|`\[`" ``) \[except for in `core::convert` where I’ve noticed other things in the docs that I want to fix in a separate PR]. In particular, unlike #80733, I’ve added almost no new instance of inline code that’s broken up into multiple links (or some link and some link-free part). I also added tooltips (the stuff in quotes for the markdown link listings) in places that caught my eye, but that’s by no means systematic, just opportunistic.
[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"
Context: I got annoyed by repeatedly running into new misformatted inline code while reading the standard library docs. I know that once issue #83997 (and/or related ones) are resolved, these changes become somewhat obsolete, but I fail to notice much progress on that end right now.
r? `@jyn514`
----------
Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt
----------
Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync}
----------
Fix spacing for links inside code blocks, and improve link tooltips in alloc::string
----------
Fix spacing for links inside code blocks in alloc::vec
----------
Fix spacing for links inside code blocks in core::option
----------
Fix spacing for links inside code blocks, and improve a few link tooltips in core::result
----------
Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll}
----------
Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path}
----------
Fix spacing for links inside code blocks in std::{collections, time}
----------
Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str}
----------
Fix spacing for links inside code blocks, and improve link tooltips in std::ffi
----------
Fix spacing for links inside code blocks, and improve a few link tooltips
in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}}
----------
Fix typo in link to `into` for `OsString` docs
----------
Remove tooltips that will probably become redundant in the future
----------
Apply suggestions from code review
Replacing `…std/primitive.reference.html` paths with just `reference`
Co-authored-by: Joshua Nelson <github@jyn.dev>
----------
Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
Introduce `Rvalue::ShallowInitBox`
Polished version of #88700.
Implements MCP rust-lang/compiler-team#460, and should allow #43596 to go forward.
In short, creating an empty box is split from a nullary-op `NullOp::Box` into two steps, first a call to `exchange_malloc`, then a `Rvalue::ShallowInitBox` which transmutes `*mut u8` to a shallow-initialized `Box<T>`. This allows the `exchange_malloc` call to unwind. Details can be found in the MCP.
`NullOp::Box` is not yet removed, purely to make reverting easier in case anything goes wrong as the result of this PR. If revert is needed a reversion of "Use Rvalue::ShallowInitBox for box expression" commit followed by a test bless should be sufficient.
Experiments in #88700 showed a very slight compile-time perf regression due to (supposedly) slightly more time spent in LLVM. We could omit unwind edge generation (in non-`oom=panic` case) in box expression MIR construction to restore perf; but I don't think it's necessary since runtime perf isn't affected and perf difference is rather small.
Add missing time complexities to linked_list.rs
Most functions in LinkedList have time complexities in their description:
Like push front:
```
Adds an element first in the list.
This operation should compute in O(1) time.
```
Time complexities were missing for the following, so I've added them in this PR:
contains: O(n)
front: O(1)
front_mut: O(1)
back: O(1)
back_mut: O(1)
Make `Duration` respect `width` when formatting using `Debug`
When printing or writing a `std::time::Duration` using `Debug` formatting, it previously completely ignored any specified `width`. This is unlike types like integers and floats, which do pad to `width`, for both `Display` and `Debug`, though not all types consider `width` in their `Debug` output (see e.g. #30164). Curiously, `Duration`'s `Debug` formatting *did* consider `precision`.
This PR makes `Duration` pad to `width` just like integers and floats, so that
```rust
format!("|{:8?}|", Duration::from_millis(1234))
```
returns
```
|1.234s |
```
Before you ask "who formats `Debug` output?", note that `Duration` doesn't actually implement `Display`, so `Debug` is currently the only way to format `Duration`s. I think that's wrong, and `Duration` should get a `Display` implementation, but in the meantime there's no harm in making the `Debug` formatting respect `width` rather than ignore it.
I chose the default alignment to be left-aligned. The general rule Rust uses is: numeric types are right-aligned by default, non-numeric types left-aligned. It wasn't clear to me whether `Duration` is a numeric type or not. The fact that a formatted `Duration` can end with suffixes of variable length (`"s"`, `"ms"`, `"µs"`, etc.) made me lean towards left-alignment, but it would be trivial to change it.
Fixes issue #88059.
Temporarily rename int_roundings functions to avoid conflicts
These functions are unstable, but because they're inherent they still
introduce conflicts with stable trait functions in crates. Temporarily
rename them to fix these conflicts, until we can resolve those conflicts
in a better way.
Add a better error message for #39364
There is a known bug in the implementation of mpsc channels in rust.
This adds a clearer error message when the bug occurs, so that developers don't lose too much time looking for the origin of the bug.
See https://github.com/rust-lang/rust/issues/39364
Fix WinUWP std compilation errors due to I/O safety
I/O safety for Windows has landed in #87329. However, it does not cover UWP specific parts and prevents all UWP targets from building. See https://github.com/YtFlow/Maple/issues/18. This PR fixes these compile errors when building std for UWP targets.
These functions are unstable, but because they're inherent they still
introduce conflicts with stable trait functions in crates. Temporarily
rename them to fix these conflicts, until we can resolve those conflicts
in a better way.
Fix missing `no_global_oom_handling` cfg-gating
Cfg-gate these trait impls that are neglected.
These functions compile now because they use `box` syntax which depends on `exchange_malloc` during codegen only; as a result they compiles with cfg `no_global_oom_handling` but shouldn't.
Discovered in #89030 because that PR makes `box` syntax depend on `exchange_malloc` lang item during MIR construction.
If you know how much data to expect and use `Vec::with_capacity` to
pre-allocate a buffer of that capacity, `Read::read_to_end` will still
double its capacity. It needs some space to perform a read, even though
that read ends up returning `0`.
It's a bummer to carefully pre-allocate 1GB to read a 1GB file into
memory and end up using 2GB.
This fixes that behavior by special casing a full buffer and reading
into a small "probe" buffer instead. If that read returns `0` then it's
confirmed that the buffer was the perfect size. If it doesn't, the probe
buffer is appended to the normal buffer and the read loop continues.
Fixing this allows several workarounds in the standard library to be
removed:
- `Take` no longer needs to override `Read::read_to_end`.
- The `reservation_size` callback that allowed `Take` to inhibit the
previous over-allocation behavior isn't needed.
- `fs::read` doesn't need to reserve an extra byte in
`initial_buffer_size`.
Curiously, there was a unit test that specifically checked that
`Read::read_to_end` *does* over-allocate. I removed that test, too.
Impl `Error` for `FromSecsError` without foreign type
Using it through the crate-local path in `std` means that it shouldn't make an "Implementations on Foreign Types" section in the `std::error::Error` docs.
Fixes a technicality regarding the size of C's `char` type
Specifically, ISO/IEC 9899:2018 — better known as "C18" — (and at least
C11, C99 and C89) do not specify the size of `byte` in bits.
Section 3.6 defines "byte" as "addressable unit of data storage" while
section 6.2.5 ("Types") only defines "char" as "large enough to store
any member of the basic execution set" giving it a lower bound of 7 bit
(since there are 96 characters in the basic execution set).
With section 6.5.3.4 paragraph 4 "When sizeof is applied to an operant
that has type char […] the result is 1" you could read this as the size
of `char` in bits being defined as exactly the same as the number of
bits in a byte but it's also valid to read that as an exception.
In general implementations take `char` as the smallest unit of
addressable memory, which for modern byte-addressed architectures is
overwhelmingly 8 bits to the point of this convention being completely
cemented into just about all of our software.
So is any of this actually relevant at all? I hope not. I sincerely hope
that this never, ever comes up.
But if for some reason a poor rustacean is having to interface with C
code running on a Cray X1 that in 2003 is still doing word-addressed
memory with 64-bit chars and they trust the docs here blindly it will
blow up in her face. And I'll be truly sorry for her to have to deal
with … all of that.
This allows the format_args! macro to keep the pre-expansion code out of
the unsafe block without doing gymnastics with nested `match`
expressions. This reduces codegen.
This mainly fixes the critical issue of aarch64 store intrinsics
overwriting additional memory, see
https://github.com/rust-lang/stdarch/issues/1220
Other changes:
* aarch64/armv7: additional vld1/vst1 intrinsics + perf fixes for existing ones
* armv7: Make FMA work with vfpv4
* Non-visible changes to the testing framework
Using it through the crate-local path in `std` means that it shouldn't make an "Implementations on Foreign Types" section in the `std::error::Error` docs.
Add initial support for m68k
This patch series adds initial support for m68k making use of the new M68k
backend introduced with LLVM-13. Additional changes will be needed to be
able to actually use the backend for this target.
Specifically, ISO/IEC 9899:2018 — better known as "C18" — (and at least
C11, C99 and C89) do not specify the size of `byte` in bits.
Section 3.6 defines "byte" as "addressable unit of data storage" while
section 6.2.5 ("Types") only defines "char" as "large enough to store
any member of the basic execution set" giving it a lower bound of 7 bit
(since there are 96 characters in the basic execution set).
With section 6.5.3.4 paragraph 4 "When sizeof is applied to an operant
that has type char […] the result is 1" you could read this as the size
of `char` in bits being defined as exactly the same as the number of
bits in a byte but it's also valid to read that as an exception.
In general implementations take `char` as the smallest unit of
addressable memory, which for modern byte-addressed architectures is
overwhelmingly 8 bits to the point of this convention being completely
cemented into just about all of our software.
So is any of this actually relevant at all? I hope not. I sincerely hope
that this never, ever comes up.
But if for some reason a poor rustacean is having to interface with C
code running on a Cray X1 that in 2003 is still doing word-addressed
memory with 64-bit words and they trust the docs here blindly it will
blow up in her face. And I'll be truly sorry for her to have to deal
with … all of that.
Rollup of 10 pull requests
Successful merges:
- #87960 (Suggest replacing an inexisting field for an unmentioned field)
- #88855 (Allow simd_shuffle to accept vectors of any length)
- #88966 (Check for shadowing issues involving block labels)
- #88996 (Fix linting when trailing macro expands to a trailing semi)
- #89017 (fix potential race in AtomicU64 time monotonizer)
- #89021 (Add a separate error for `dyn Trait` in `const fn`)
- #89051 (Add intra-doc links and small changes to `std::os` to be more consistent)
- #89053 (refactor: VecDeques IntoIter fields to private)
- #89055 (Suggest better place to add call parentheses for method expressions wrapped in parentheses)
- #89081 (Fix a typo)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
refactor: VecDeques IntoIter fields to private
Made the fields of VecDeque's IntoIter private by creating a IntoIter::from(...) function to create a new instance of IntoIter and migrating usage to use IntoIter::from(...).
Add intra-doc links and small changes to `std::os` to be more consistent
I believe that a few items in `std::os` should be linked. I've also added a basic example in `std::os::windows`.
fix potential race in AtomicU64 time monotonizer
The AtomicU64-based monotonizer introduced in #83093 is incorrect because several threads could try to update the value concurrently and a thread which doesn't have the newest value among all the updates could win.
That bug probably has little real world impact since it doesn't make observed time worse than hardware clocks. The worst case would probably be a thread which has a clock that is behind by several cycles observing several inconsistent fixups, which should be similar to observing the unfiltered backslide in the first place.
New benchmarks, they don't look as good as the original PR but still an improvement compared to the mutex.
I don't know why the contended mutex case is faster now than in the previous benchmarks.
```
actually_monotonic() == true:
test time::tests::instant_contention_01_threads ... bench: 44 ns/iter (+/- 0)
test time::tests::instant_contention_02_threads ... bench: 45 ns/iter (+/- 0)
test time::tests::instant_contention_04_threads ... bench: 45 ns/iter (+/- 0)
test time::tests::instant_contention_08_threads ... bench: 45 ns/iter (+/- 0)
test time::tests::instant_contention_16_threads ... bench: 46 ns/iter (+/- 0)
atomic u64:
test time::tests::instant_contention_01_threads ... bench: 66 ns/iter (+/- 0)
test time::tests::instant_contention_02_threads ... bench: 287 ns/iter (+/- 14)
test time::tests::instant_contention_04_threads ... bench: 296 ns/iter (+/- 43)
test time::tests::instant_contention_08_threads ... bench: 604 ns/iter (+/- 163)
test time::tests::instant_contention_16_threads ... bench: 1,147 ns/iter (+/- 29)
mutex:
test time::tests::instant_contention_01_threads ... bench: 78 ns/iter (+/- 0)
test time::tests::instant_contention_02_threads ... bench: 652 ns/iter (+/- 275)
test time::tests::instant_contention_04_threads ... bench: 900 ns/iter (+/- 32)
test time::tests::instant_contention_08_threads ... bench: 1,927 ns/iter (+/- 62)
test time::tests::instant_contention_16_threads ... bench: 3,748 ns/iter (+/- 146)
```
Avoid codegen for Result::into_ok in lang_start
This extra codegen seems to be the cause for the regressions in max-rss on #86034. While LLVM will certainly optimize the dead code away, avoiding it's generation in the first place seems good, particularly when it is so simple.
#86034 produced this [diff](https://gist.github.com/Mark-Simulacrum/95c7599883093af3b960c35ffadf4dab#file-86034-diff) for a simple `fn main() {}`. With this PR, that diff [becomes limited to just a few extra IR instructions](https://gist.github.com/Mark-Simulacrum/95c7599883093af3b960c35ffadf4dab#file-88988-from-pre-diff) -- no extra functions.
Note that these are pre-optimization; LLVM surely will eliminate this during optimization. However, that optimization can end up generating more work and bump memory usage, and this eliminates that.
Allow `panic!("{}", computed_str)` in const fn.
Special-case `panic!("{}", arg)` and translate it to `panic_display(&arg)`. `panic_display` will behave like `panic_any` in cosnt eval and behave like `panic!(format_args!("{}", arg))` in runtime.
This should bring Rust 2015 and 2021 to feature parity in terms of `const_panic`; and hopefully would unblock the stabilisation of #51999.
`@rustbot` modify labels: +T-compiler +T-libs +A-const-eval +A-const-fn
r? `@oli-obk`
Add chown functions to std::os::unix::fs to change the owner and group of files
This is a straightforward wrapper that uses the existing helpers for C
string handling and errno handling.
Having this available is convenient for UNIX utility programs written in
Rust, and avoids having to call unsafe functions like `libc::chown`
directly and handle errors manually, in a program that may otherwise be
entirely safe code.
In addition, these functions provide a more Rustic interface by
accepting appropriate traits and using `None` rather than `-1`.
Add TcpListener::into_incoming and IntoIncoming
The `incoming` method is really useful, however for some use cases the borrow
this introduces is needlessly restricting. Thus, an owned variant is added.
r? ``@joshtriplett``
The RefCell is now borrowed exactly once. In addition a code sequence
that contains an unwrap that is guaranteed to never panic at runtime is
replaced with get_or_insert_with, which makes the intended behavior
clearer and will not emit code to panic even without optimizations.
Previously the thread name would first be heap allocated and then
re-allocated to add a nul terminator. Now it will be heap allocated only
once with nul terminator added form the start.
This is a straightforward wrapper that uses the existing helpers for C
string handling and errno handling.
Having this available is convenient for UNIX utility programs written in
Rust, and avoids having to call unsafe functions like `libc::chown`
directly and handle errors manually, in a program that may otherwise be
entirely safe code.
In addition, these functions provide a more Rustic interface by
accepting appropriate traits and using `None` rather than `-1`.
Most of these are because alloc uses `#[lang_item]` to define methods,
but core documents primitives before those methods are available.
- Fix rustdoc-js-std test
For some reason this change made CStr not show up in the results for
`str,u8`. Since it still shows up for str, and since it wasn't a great
match for that query anyway, I think this is ok to let slide.
- Add test that all primitives can be linked to
- Enable `doc(primitive)` in `core` as well
- Add linkcheck exception specifically for Windows
Ideally this would be done automatically by the linkchecker by
replacing `\\` with forward slashes, but this PR is already a ton of
work ...
- Don't forcibly fail linkchecking if there's a broken intra-doc link on Windows
Previously, it would exit with a hard error if a missing file had `::`
in it. This changes it to report a missing file instead, which allows
adding an exception.
This works by doing two things:
- Adding links that are specific to the crate. Since not all primitive
items are defined in `core` (due to lang_items), these need to use
relative links and not intra-doc links.
- Duplicating `primitive_docs` in both core and std. This allows not needing CARGO_PKG_NAME to build the standard library. It also adds a tidy check to make sure they stay the same.
Reword description of automatic impls of `Unsize`.
The existing documentation felt a little unhelpfully concise, so this change tries to improve it by using longer sentences, each of which specifies which kinds of types it applies to as early as possible. In particular, the third item starts with “Structs ...” instead of saying “Foo is a struct” later.
Also, the previous list items “Only the last field has a type involving `T`” and “`T` is not part of the type of any other fields” are, as far as I see, redundant with each other, so I removed the latter.
I have no particular knowledge of `Unsize`; I have attempted to leave the meaning entirely unchanged but may have missed a nuance.
Markdown preview of the edited documentation:
> All implementations of `Unsize` are provided automatically by the compiler.
> Those implementations are:
>
> - Arrays `[T; N]` implement `Unsize<[T]>`.
> - Types implementing a trait `Trait` also implement `Unsize<dyn Trait>`.
> - Structs `Foo<..., T, ...>` implement `Unsize<Foo<..., U, ...>>` if all of these conditions
> are met:
> - `T: Unsize<U>`.
> - Only the last field of `Foo` has a type involving `T`.
> - `Bar<T>: Unsize<Bar<U>>`, where `Bar<T>` stands for the actual type of that last field.
Add proc_macro::Span::{before, after}.
This adds `proc_macro::Span::before()` and `proc_macro::Span::after()` to get a zero width span at the start or end of the span.
These are equivalent to rustc's `Span::shrink_to_lo()` and `Span::shrink_to_hi()` but with a less cryptic name. They are useful when generating diagnostlics like "missing \<thing\> after \<thing\>".
E.g.
```rust
syn::Error::new(ident.span().after(), "missing `:` after field name").into_compile_error()
```
I originally added this bound in an attempt to make the specialization
sound for owning iterators but it was never correct here and the correct
and already implemented solution is is to place it on the IntoIter
implementation.
This is achieved with a branchless bit-twiddling implementation of the
case x < 100_000, and using this as building block.
Benchmark on an Intel i7-8700K (Coffee Lake):
name old ns/iter new ns/iter diff ns/iter diff % speedup
num::int_log::u8_log10_predictable 165 169 4 2.42% x 0.98
num::int_log::u8_log10_random 438 423 -15 -3.42% x 1.04
num::int_log::u8_log10_random_small 438 423 -15 -3.42% x 1.04
num::int_log::u16_log10_predictable 633 417 -216 -34.12% x 1.52
num::int_log::u16_log10_random 908 471 -437 -48.13% x 1.93
num::int_log::u16_log10_random_small 945 471 -474 -50.16% x 2.01
num::int_log::u32_log10_predictable 1,496 1,340 -156 -10.43% x 1.12
num::int_log::u32_log10_random 1,076 873 -203 -18.87% x 1.23
num::int_log::u32_log10_random_small 1,145 874 -271 -23.67% x 1.31
num::int_log::u64_log10_predictable 4,005 3,171 -834 -20.82% x 1.26
num::int_log::u64_log10_random 1,247 1,021 -226 -18.12% x 1.22
num::int_log::u64_log10_random_small 1,265 921 -344 -27.19% x 1.37
num::int_log::u128_log10_predictable 39,667 39,579 -88 -0.22% x 1.00
num::int_log::u128_log10_random 6,456 6,696 240 3.72% x 0.96
num::int_log::u128_log10_random_small 4,108 3,903 -205 -4.99% x 1.05
Benchmark on an M1 Mac Mini:
name old ns/iter new ns/iter diff ns/iter diff % speedup
num::int_log::u8_log10_predictable 143 130 -13 -9.09% x 1.10
num::int_log::u8_log10_random 375 325 -50 -13.33% x 1.15
num::int_log::u8_log10_random_small 376 325 -51 -13.56% x 1.16
num::int_log::u16_log10_predictable 500 322 -178 -35.60% x 1.55
num::int_log::u16_log10_random 794 405 -389 -48.99% x 1.96
num::int_log::u16_log10_random_small 1,035 405 -630 -60.87% x 2.56
num::int_log::u32_log10_predictable 1,144 894 -250 -21.85% x 1.28
num::int_log::u32_log10_random 832 786 -46 -5.53% x 1.06
num::int_log::u32_log10_random_small 832 787 -45 -5.41% x 1.06
num::int_log::u64_log10_predictable 2,681 2,057 -624 -23.27% x 1.30
num::int_log::u64_log10_random 1,015 806 -209 -20.59% x 1.26
num::int_log::u64_log10_random_small 1,004 795 -209 -20.82% x 1.26
num::int_log::u128_log10_predictable 56,825 56,526 -299 -0.53% x 1.01
num::int_log::u128_log10_random 9,056 8,861 -195 -2.15% x 1.02
num::int_log::u128_log10_random_small 1,528 1,527 -1 -0.07% x 1.00
The 128 bit case remains ridiculously slow because llvm fails to optimize division by
a constant 128-bit value to multiplications. This could be worked around but it seems
preferable to fix this in llvm.
From u32 up, table lookup (like suggested here
https://github.com/rust-lang/rust/issues/70887#issuecomment-881099813) is still
faster, but requires a hardware leading_zero to be viable, and might clog up the
cache.
Correct “copies” to “moves” in `<Option<T> as From<T>>::from` doc, and other copyediting
The `impl<T> From<T> for Option<T>` has no `Copy` or `Clone` bound, so its operation is guaranteed to be a move. The call site might copy, but the function itself cannot.
Since that would have been a rather small PR, I also reviewed the other documentation in the file and made other improvements (in separate commits): adding periods and commas, linking `Deref::Target`, and clarifying what "a container" is in `FromIterator`.
More symbolic doc aliases
A bunch of small changes, mostly adding `#[doc(alias = "…")]` entries for symbolic `"…"`.
Also a small change in documentation of `const` keywords.
Suggest deriving traits if possible
This only applies to builtin derives as I don't think there is a
clean way to get the available derives in typeck.
Closes#85851
* Clarify rounding.
* Avoid "wrapping" wording.
* Omit wrong claim on 0 only being returned in error cases.
* Typo fix for one_less_than_next_power_of_two.
BTreeMap/BTreeSet::from_iter: use bulk building to improve the performance
Bulk building is a common technique to increase the performance of building a fresh btree map. Instead of inserting items one-by-one, we sort all the items beforehand then create the BtreeMap in bulk.
Benchmark
```
./x.py bench library/alloc --test-args btree::map::from_iter
```
* Before
```
test btree::map::from_iter_rand_100 ... bench: 3,694 ns/iter (+/- 840)
test btree::map::from_iter_rand_10_000 ... bench: 1,033,446 ns/iter (+/- 192,950)
test btree::map::from_iter_seq_100 ... bench: 5,689 ns/iter (+/- 1,259)
test btree::map::from_iter_seq_10_000 ... bench: 861,033 ns/iter (+/- 118,815)
```
* After
```
test btree::map::from_iter_rand_100 ... bench: 3,033 ns/iter (+/- 707)
test btree::map::from_iter_rand_10_000 ... bench: 775,958 ns/iter (+/- 105,152)
test btree::map::from_iter_seq_100 ... bench: 2,969 ns/iter (+/- 336)
test btree::map::from_iter_seq_10_000 ... bench: 258,292 ns/iter (+/- 29,364)
```
Document when to use Windows' `symlink_dir` vs. `symlink_file`
It was previously unclear why there are two functions and when they should be used.
Fixes: #88635
Add links in docs for some primitive types
This pull request adds additional links in existing documentation of some of the primitive types.
Where items are linked only once, I have used the `[link](destination)` format. For items in `std`, I have linked directly to the HTML, since although the primitives are in `core`, they are not displayed on `core` documentation. I was unsure of what length I should keep lines of documentation to, so I tried to keep them within reason.
Additionally, I have avoided excessively linking to keywords like `self` when they are not relevant to the documentation. I can add these links if it would be an improvement.
I hope this can improve Rust. Please let me know if there's anything I did wrong!
While issues have been seen on arm64 platforms the Arm architecture requires
that the counter monotonically increases and that it must provide a uniform
view of system time (e.g. it must not be possible for a core to receive a
message from another core with a time stamp and observe time going backwards
(ARM DDI 0487G.b D11.1.2). While there have been a few 64bit SoCs that have
bugs (#49281, #56940) which cause time to not monotonically increase, these have
been fixed in the Linux kernel and we shouldn't penalize all Arm SoCs for those
who refuse to update their kernels:
SUN50I_ERRATUM_UNKNOWN1 - Allwinner A64 / Pine A64 - fixed in 5.1
FSL_ERRATUM_A008585 - Freescale LS2080A/LS1043A - fixed in 4.10
HISILICON_ERRATUM_161010101 - Hisilicon 1610 - fixed in 4.11
ARM64_ERRATUM_858921 - Cortex A73 - fixed in 4.12
255a3f3e18 std: Force `Instant::now()` to be monotonic added a mutex to work around
this problem and a small test program using glommio shows the majority of time spent
acquiring and releasing this Mutex. 3914a7b0da tries to improve this, but actually
makes it worse on big systems as for 128b atomics a ldxp/stxp pair (and
successful loop) is required which is expensive as a lock and because of how
the load/store-exclusives scale on large Arm systems is both unfair to threads
and tends to go backwards in performance.
aarch64 prior to v8.4 (FEAT_LSE2) doesn't have an instruction that guarantees
untorn 128b reads except for completing a 128b load/store exclusive pair
(ldxp/stxp) or compare-and-swap (casp) successfully. The requirement to
complete a 128b read+write atomic is actually more expensive and more unfair
than the previous implementation of monotonize() which used a Mutex on aarch64,
especially at large core counts. For aarch64 switch to the 64b atomic
implementation which is about 13x faster for a benchmark that involves many
calls to Instant::now().
This implementation has no `Copy` or `Clone` bound, so its operation is
guaranteed to be a move. The call site might copy, but the function
itself cannot.
Also linkify `Some` while we're touching the line anyway.
remove redundant / misplaced sentence from docs
Removes sentence that seems to have drifted down into the examples section. Luckily, someone already added an explanation of what happens with packed structs back into the initial section of the doc entry and this wayward sentence can likely just be deleted.
Add an example for deriving PartialOrd on enums
For some reason, I always forget which variants are smaller and which
are larger when you derive PartialOrd on an enum. And the wording in the
current docs is not entirely clear to me.
So, I often end up making a small enum, deriving PartialOrd on it, and
then writing a `#[test]` with an assert that the top one is smaller than
the bottom one (or the other way around) to figure out which way the
deriving goes.
So then I figured, it would be great if the standard library docs just
had that example, so if I keep forgetting, at least I can figure it out
quickly by looking at std's docs.
There is a known bug in the implementation of mpsc channels in rust.
This adds a clearer error message when the bug occurs, so that developers don't lose too much time looking for the origin of the bug.
See https://github.com/rust-lang/rust/issues/39364
`fmt::Formatter::pad`: don't call chars().count() more than one time
First commit merges two branches of match to call chars().count() only once: that should be faster if this method hits place of 3rd (previous) branch, plus quarter shorter.
Second commit fixes some clippy lints while i'm here (should it be separate PR?).