Add alignment to the NPO guarantee
This PR [changes](https://github.com/rust-lang/rust/pull/114845#discussion_r1294363357) "same size" to "same size and alignment" in the option module's null pointer optimization docs in <https://doc.rust-lang.org/std/option/#representation>.
As far as I know, this has been true for a long time in the actual rustc implementation, but it's not in the text of those docs, so I figured I'd bring this up to FCP it.
I also see no particular reason that we'd ever *want* to have higher alignment on these. In many of the cases it's impossible, as the minimum alignment is already the size of the type, but even if we *could* do things like on 32-bit we could say that `NonZeroU64` is 4-align but `Option<NonZeroU64>` is 8-align, I just don't see any value in doing that, so feel completely fine closing this door for the few things on which the NPO is already guaranteed. These are basically all primitives, and should end up with the same size & alignment as those primitives.
(There's no layout guarantee for something like `Option<[u8; 3]>`, where it'd be at least plausible to consider raising the alignment from 1 to 4 on, say, some hypothetical target that doesn't have efficient unaligned 4-byte load/stores. And even if we ever did start to offer some kind of guarantee around such a type, I doubt we'd put it under the "null pointer" optimization header.)
Screenshots for the new examples:
![image](https://github.com/rust-lang/rust/assets/18526288/a7dbff42-50b4-462e-9e27-00d511b58763)
![image](https://github.com/rust-lang/rust/assets/18526288/dfd55288-80fb-419a-bc11-26198c27f9f9)
Implement Step for ascii::Char
This allows iterating over ranges of `ascii::Char`, similarly to ranges of `char`.
Note that `ascii::Char` is still unstable, tracked in #110998.
Fix implementation of `Duration::checked_div`
I ran across this while running some sanity checks on `time`. Quickcheck immediately found a bug, and as I'd modified the code from `std` I knew there was a bug here as well.
tl;dr this code fails ([playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1189a3efcdfc192c27d6d87815359353))
```rust
use std::time::Duration;
fn main() {
assert_eq!(
Duration::new(1, 1).checked_div(7),
Some(Duration::new(0, 142_857_143)),
);
}
```
The existing code determines that 1/7 = 0 (seconds), 1/7 = 0 (nanoseconds), 1 billion / 7 = 142,857,142 (extra nanoseconds). The billion comes from multiplying the remainder of the seconds (1) by the number of nanoseconds in a second. However, **this wrongly ignores any remaining nanoseconds**. This PR takes that into consideration, adds a test, and also changes the roundabout way of calculating the remainder into directly computing it.
Note: This is _not_ a rounding error. This result divides evenly.
`@rustbot` label +A-time +C-bug +S-waiting-on-reviewer +T-libs
Go into more detail about panicking in drop.
This patch was sitting around in my drafts. I don't recall the motivation, but I think it was someone expressing confusion over “will likely abort” (since, in fact, a panicking drop _not_ caused by dropping while panicking will predictably _not_ abort).
I hope that the new text will leave people well-informed about why not to panic and when it is reasonable to panic.
Make `rustc_on_unimplemented` std-agnostic for `alloc::rc`
See https://github.com/rust-lang/rust/issues/112923
Just a few lines related to `alloc:rc` for `Send` and `Sync`.
That seems to be all of the `... = "std::..."` issues found, but there a few notes with `std::` inside them still.
r? `@WaffleLapkin`
Add `suggestion` for some `#[deprecated]` items
Consider code:
```rust
fn main() {
let _ = ["a", "b"].connect(" ");
}
```
Currently it shows deprecated warning:
```rust
warning: use of deprecated method `std::slice::<impl [T]>::connect`: renamed to join
--> src/main.rs:2:24
|
2 | let _ = ["a", "b"].connect(" ");
| ^^^^^^^
|
= note: `#[warn(deprecated)]` on by default
```
This PR adds `suggestion` for `connect` and some other deprecated items, so the warning will be changed to this:
```rust
warning: use of deprecated method `std::slice::<impl [T]>::connect`: renamed to join
--> src/main.rs:2:24
|
2 | let _ = ["a", "b"].connect(" ");
| ^^^^^^^
|
= note: `#[warn(deprecated)]` on by default
help: replace the use of the deprecated method
|
2 | let _ = ["a", "b"].join(" ");
| ^^^^
```
custom_mir: change Call() terminator syntax to something more readable
I find our current syntax very hard to read -- I cannot even remember the order of arguments, and having the "next block" *before* the actual function call is very counter-intuitive IMO. So I suggest we use `Call(ret_val = function(v), next_block)` instead.
r? `@JakobDegen`
rustdoc: Add lint `redundant_explicit_links`
Closes#87799.
- Lint warns by default
- Reworks link parser to cache original link's display text
r? `@jyn514`
Inline strlen_rt in CStr::from_ptr
This enables LLVM to optimize this function as if it was strlen (LLVM knows what it does, and can avoid calling it in certain situations) without having to enable std-aware LTO. This is essentially doing what https://github.com/rust-lang/rust/pull/90007 did, except updated for this function being `const`.
Pretty sure it's safe to roll-up, considering last time I did make this change it didn't affect performance (`CStr::from_ptr` isn't really used all that often in Rust code that is checked by rust-perf).
When I was learning Rust I looked for “a modulo function” and couldn’t
find one, so thought I had to write my own; it wasn't at all obvious
that a function with “rem” in the name was the function I wanted.
Hopefully this will save the next learner from that.
However, it does have the disadvantage that the top results in rustdoc
for “mod” are now these aliases instead of the Rust keyword, which
probably isn't ideal.
Optimizing the rest of bool's Ord implementation
After coming across issue #66780, I realized that the other functions provided by Ord (`min`, `max`, and `clamp`) were similarly inefficient for bool. This change provides implementations for them in terms of boolean operators, resulting in much simpler assembly and faster code.
Fixes issue #114653
[Comparison on Godbolt](https://rust.godbolt.org/z/5nb5P8e8j)
`max` assembly before:
```assembly
example::max:
mov eax, edi
mov ecx, eax
neg cl
mov edx, esi
not dl
cmp dl, cl
cmove eax, esi
ret
```
`max` assembly after:
```assembly
example::max:
mov eax, edi
or eax, esi
ret
```
`clamp` assembly before:
```assembly
example:🗜️
mov eax, esi
sub al, dl
inc al
cmp al, 2
jae .LBB1_1
mov eax, edi
sub al, sil
movzx ecx, dil
sub dil, dl
cmp dil, 1
movzx edx, dl
cmovne edx, ecx
cmp al, -1
movzx eax, sil
cmovne eax, edx
ret
.LBB1_1:
; identical assert! code
```
`clamp` assembly after:
```assembly
example:🗜️
test edx, edx
jne .LBB1_2
test sil, sil
jne .LBB1_3
.LBB1_2:
or dil, sil
and dil, dl
mov eax, edi
ret
.LBB1_3:
; identical assert! code
```
Cleaner assert_eq! & assert_ne! panic messages
This PR finishes refactoring of the assert messages per #94005. The panic message format change #112849 used to be part of this PR, but has been factored out and just merged. It might be better to keep both changes in the same release once FCP vote completes.
Modify panic message for `assert_eq!`, `assert_ne!`, the currently unstable `assert_matches!`, as well as the corresponding `debug_assert_*` macros.
```rust
assert_eq!(1 + 1, 3);
assert_eq!(1 + 1, 3, "my custom message value={}!", 42);
```
#### Old messages
```plain
thread 'main' panicked at $DIR/main.rs:6:5:
assertion failed: `(left == right)`
left: `2`,
right: `3`
```
```plain
thread 'main' panicked at $DIR/main.rs:6:5:
assertion failed: `(left == right)`
left: `2`,
right: `3`: my custom message value=42!
```
#### New messages
```plain
thread 'main' panicked at $DIR/main.rs:6:5:
assertion `left == right` failed
left: 2
right: 3
```
```plain
thread 'main' panicked at $DIR/main.rs:6:5:
assertion `left == right` failed: my custom message value=42!
left: 2
right: 3
```
History of fixing #94005
* #94016 was a lengthy PR that was abandoned
* #111030 was similar, but it stringified left and right arguments, and thus caused compile time performance issues, thus closed
* #112849 factored out the two-line formatting of all panic messages
Fixes#94005
r? `@m-ou-se`