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`
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);
```
```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!
```
```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
```
This PR is a simpler subset of the #111030, but it does NOT stringify the original left and right source code assert expressions, thus should be faster to compile.