Rollup of 9 pull requests
Successful merges:
- #112806 (Small code improvements in `collect_intra_doc_links.rs`)
- #119766 (Split tait and impl trait in assoc items logic)
- #120139 (Do not normalize closure signature when building `FnOnce` shim)
- #120160 (Manually implement derived `NonZero` traits.)
- #120171 (Fix assume and assert in jump threading)
- #120183 (Add `#[coverage(off)]` to closures introduced by `#[test]` and `#[bench]`)
- #120195 (add several resolution test cases)
- #120259 (Split Diagnostics for Uncommon Codepoints: Add List to Display Characters Involved)
- #120261 (Provide structured suggestion to use trait objects in some cases of `if` arm type divergence)
r? `@ghost`
`@rustbot` modify labels: rollup
Add `#[coverage(off)]` to closures introduced by `#[test]` and `#[bench]`
These closures are an internal implementation detail of the `#[test]` and `#[bench]` attribute macros, so from a user perspective there is no reason to instrument them for coverage.
Skipping them makes coverage reports slightly cleaner, and will also allow other changes to span processing during coverage instrumentation, without having to worry about how they affect the `#[test]` macro.
The `#[coverage(off)]` attribute has no effect when `-Cinstrument-coverage` is not used.
Fixes#120046.
---
Note that this PR has no effect on the user-written function that has the `#[test]` attribute attached to it. That function will still be instrumented as normal.
Manually implement derived `NonZero` traits.
Step 3 as mentioned in https://github.com/rust-lang/rust/pull/100428#pullrequestreview-1767139731.
Manually implement the traits that would cause “borrow of layout constrained field with interior mutability” errors when switching to `NonZero<T>`.
r? ```@dtolnay```
Use `Self` in `NonZero*` implementations.
This slightly reduces the size of the eventual diff when making these generic, since this can be merged independently.
Use `assert_unchecked` instead of `assume` intrinsic in the standard library
Now that a public wrapper for the `assume` intrinsic exists, we can use it in the standard library.
CC #119131
Revert stabilization of trait_upcasting feature
Reverts #118133
This reverts commit 6d2b84b3ed, reversing changes made to 73bc12199e.
The feature has a soundness bug:
* #120222
It is unclear to me whether we'll actually want to destabilize, but I thought it was still prudent to open the PR for easy destabilization once we get there.
Consolidate logic around resolving built-in coroutine trait impls
Deduplicates a lot of code. Requires defining a new lang item for `Coroutine::resume` for consistency, but it seems not harmful at worst, and potentially later useful at best.
r? oli-obk
Rollup of 9 pull requests
Successful merges:
- #118714 ( Explanation that fields are being used when deriving `(Partial)Ord` on enums)
- #119710 (Improve `let_underscore_lock`)
- #119726 (Tweak Library Integer Division Docs)
- #119746 (rustdoc: hide modals when resizing the sidebar)
- #119986 (Fix error counting)
- #120194 (Shorten `#[must_use]` Diagnostic Message for `Option::is_none`)
- #120200 (Correct the anchor of an URL in an error message)
- #120203 (Replace `#!/bin/bash` with `#!/usr/bin/env bash` in rust-installer tests)
- #120212 (Give nnethercote more reviews)
r? `@ghost`
`@rustbot` modify labels: rollup
Shorten `#[must_use]` Diagnostic Message for `Option::is_none`
This shortens the `#[must_use]` diagnostics displayed, in light of the [review comment](https://github.com/rust-lang/rust/pull/62431/files#r300819839) on when this was originally added.
Tweak Library Integer Division Docs
Improved the documentation and diagnostics related to panicking in the division-like methods in std:
* For signed methods that can overflow, clarified "results in overflow" to "self is -1 and rhs is Self::MIN." This is more concise than saying "results in overflow" and then explaining how it could overflow.
* For floor/ceil_div, corrected the documentation and made it more like the documentation in other methods.
* For signed methods that can overflow, explicitly mention that they are not affected by compiler flags.
* Removed all unused rustc_inherit_overflow_checks attributes. The non-division-like operations will never overflow.
* Added track_caller attributes to all methods that can panic. The panic messages will always be correct. For example, division methods all have / before %.
* Edited the saturating_div documentation to be consistent with similar methods.
Explanation that fields are being used when deriving `(Partial)Ord` on enums
When deriving `std::cmp::Ord` or `std::cmp::PartialOrd` on enums, their fields are compared if the variants are equal.
This means that the last assertion in the following snipped panics.
```rust
use std::cmp::{PartialEq, Eq, PartialOrd, Ord};
#[derive(PartialEq, Eq, PartialOrd, Ord)]
enum Sizes {
Small(usize),
Big(usize),
}
fn main() {
let a = Sizes::Big(3);
let b = Sizes::Big(5);
let c = Sizes::Small(10);
assert!( c < a);
assert_eq!(a, c);
}
```
This is more often expected behavior than not, and can be easily circumvented, as discussed in [this thread](https://users.rust-lang.org/t/how-to-sort-enum-variants/52291/4).
But it is addressed nowhere in the documentation, yet.
So I stumbled across this, as I personally did not expect fields being used in `PartialOrd`.
I added the explanation to the documentation.
Add `#[track_caller]` to the "From implies Into" impl
This pr implements what was mentioned in https://github.com/rust-lang/rust/issues/77474#issuecomment-1074480790
This follows from my URLO https://users.rust-lang.org/t/104497
```rust
#![allow(warnings)]
fn main() {
// Gives a good location
let _: Result<(), Loc> = dbg!(Err::<(), _>(()).map_err(|e| e.into()));
// still doesn't work, gives location of `FnOnce::call_once()`
let _: Result<(), Loc> = dbg!(Err::<(), _>(()).map_err(Into::into));
}
#[derive(Debug)]
pub struct Loc {
pub l: &'static std::panic::Location<'static>,
}
impl From<()> for Loc {
#[track_caller]
fn from(_: ()) -> Self {
Loc {
l: std::panic::Location::caller(),
}
}
}
```
Implement iterator specialization traits on more adapters
This adds
* `TrustedLen` to `Skip` and `StepBy`
* `TrustedRandomAccess` to `Skip`
* `InPlaceIterable` and `SourceIter` to `Copied` and `Cloned`
The first two might improve performance in the compiler itself since `skip` is used in several places. Constellations that would exercise the last point are probably rare since it would require an owning iterator that has references as Items somewhere in its iterator pipeline.
Improvements for `Skip`:
```
# old
test iter::bench_skip_trusted_random_access ... bench: 8,335 ns/iter (+/- 90)
# new
test iter::bench_skip_trusted_random_access ... bench: 2,753 ns/iter (+/- 27)
```
Add Ipv6Addr::is_ipv4_mapped
This change consists of cherry-picking the content from the original PR[1], which got closed due to inactivity, and applying the following changes:
* Resolving merge conflicts (obviously)
* Linked to to_ipv4_mapped instead of to_ipv4 in the documentation (seems more appropriate)
* Added the must_use and rustc_const_unstable attributes the original didn't have
I think it's a reasonably useful method to have.
[1] https://github.com/rust-lang/rust/pull/86490
Use `bool` instead of `PartiolOrd` as return value of the comparison closure in `{slice,Iteraotr}::is_sorted_by`
Changes the function signature of the closure given to `{slice,Iteraotr}::is_sorted_by` to return a `bool` instead of a `PartiolOrd` as suggested by the libs-api team here: https://github.com/rust-lang/rust/issues/53485#issuecomment-1766411980.
This means these functions now return true if the closure returns true for all the pairs of values.
Implement strict integer operations that panic on overflow
This PR implements the first part of the ACP for adding panic on overflow style arithmetic operations (https://github.com/rust-lang/libs-team/issues/270), mentioned in #116064.
It adds the following operations on both signed and unsigned integers:
- `strict_add`
- `strict_sub`
- `strict_mul`
- `strict_div`
- `strict_div_euclid`
- `strict_rem`
- `strict_rem_euclid`
- `strict_neg`
- `strict_shl`
- `strict_shr`
- `strict_pow`
Additionally, signed integers have:
- `strict_add_unsigned`
- `strict_sub_unsigned`
- `strict_abs`
And unsigned integers have:
- `strict_add_signed`
The `div` and `rem` operations are the same as normal division and remainder but are added for completeness similar to the corresponding `wrapping_*` operations.
I'm not sure if I missed any operations, I basically found them from the `wrapping_*` and `checked_*` operations on both integer types.
Tweak the threshold for chunked swapping
Thanks to `@AngelicosPhosphoros` for the tests here, which I copied from #98892.
This is an experiment as a simple alternative to that PR that just tweaks the existing threshold, since that PR showed that 3×Align (like `String`) currently doesn't work as well as it could.
Introduce split_at_checked and split_at_mut_checked methods to slices
types (including str) which are non-panicking versions of split_at and
split_at_mut respectively. This is analogous to get method being
non-panicking version of indexing.
Stabilize single-field offset_of
This PR stabilizes offset_of for a single field. There has been some further discussion at https://github.com/rust-lang/rust/issues/106655 about whether this is advisable; I'm opening the PR anyway so that the code is available.
Change return type of unstable `Waker::noop()` from `Waker` to `&Waker`.
The advantage of this is that it does not need to be assigned to a variable to be used in a `Context` creation, which is the most common thing to want to do with a noop waker. It also avoids unnecessarily executing the dynamically dispatched drop function when the noop waker is dropped.
If an owned noop waker is desired, it can be created by cloning, but the reverse is harder to do since it requires declaring a constant. Alternatively, both versions could be provided, like `futures::task::noop_waker()` and `futures::task::noop_waker_ref()`, but that seems to me to be API clutter for a very small benefit, whereas having the `&'static` reference available is a large reduction in boilerplate.
[Previous discussion on the tracking issue starting here](https://github.com/rust-lang/rust/issues/98286#issuecomment-1862159766)
Stabilize `slice_first_last_chunk`
This PR does a few different things based around stabilizing `slice_first_last_chunk`. They are split up so this PR can be by-commit reviewed, I can move parts to a separate PR if desired.
This feature provides a very elegant API to extract arrays from either end of a slice, such as for parsing integers from binary data.
## Stabilize `slice_first_last_chunk`
ACP: https://github.com/rust-lang/libs-team/issues/69
Implementation: https://github.com/rust-lang/rust/issues/90091
Tracking issue: https://github.com/rust-lang/rust/issues/111774
This stabilizes the functionality from https://github.com/rust-lang/rust/issues/111774:
```rust
impl [T] {
pub const fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>;
pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>;
pub const fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>;
pub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>;
pub const fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>;
pub fn split_first_chunk_mut<const N: usize>(&mut self) -> Option<(&mut [T; N], &mut [T])>;
pub const fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>;
pub fn split_last_chunk_mut<const N: usize>(&mut self) -> Option<(&mut [T], &mut [T; N])>;
}
```
Const stabilization is included for all non-mut methods, which are blocked on `const_mut_refs`. This change includes marking the trivial function `slice_split_at_unchecked` const-stable for internal use (but not fully stable).
## Remove `split_array` slice methods
Tracking issue: https://github.com/rust-lang/rust/issues/90091
Implementation: https://github.com/rust-lang/rust/pull/83233#pullrequestreview-780315524
This PR also removes the following unstable methods from the `split_array` feature, https://github.com/rust-lang/rust/issues/90091:
```rust
impl<T> [T] {
pub fn split_array_ref<const N: usize>(&self) -> (&[T; N], &[T]);
pub fn split_array_mut<const N: usize>(&mut self) -> (&mut [T; N], &mut [T]);
pub fn rsplit_array_ref<const N: usize>(&self) -> (&[T], &[T; N]);
pub fn rsplit_array_mut<const N: usize>(&mut self) -> (&mut [T], &mut [T; N]);
}
```
This is done because discussion at #90091 and its implementation PR indicate a strong preference for nonpanicking APIs that return `Option`. The only difference between functions under the `split_array` and `slice_first_last_chunk` features is `Option` vs. panic, so remove the duplicates as part of this stabilization.
This does not affect the array methods from `split_array`. We will want to revisit these once `generic_const_exprs` is further along.
## Reverse order of return tuple for `split_last_chunk{,_mut}`
An unresolved question for #111774 is whether to return `(preceding_slice, last_chunk)` (`(&[T], &[T; N])`) or the reverse (`(&[T; N], &[T])`), from `split_last_chunk` and `split_last_chunk_mut`. It is currently implemented as `(last_chunk, preceding_slice)` which matches `split_last -> (&T, &[T])`. The first commit changes these to `(&[T], &[T; N])` for these reasons:
- More consistent with other splitting methods that return multiple values: `str::rsplit_once`, `slice::split_at{,_mut}`, `slice::align_to` all return tuples with the items in order
- More intuitive (arguably opinion, but it is consistent with other language elements like pattern matching `let [a, b, rest @ ..] ...`
- If we ever added a varidic way to obtain multiple chunks, it would likely return something in order: `.split_many_last::<(2, 4)>() -> (&[T], &[T; 2], &[T; 4])`
- It is the ordering used in the `rsplit_array` methods
I think the inconsistency with `split_last` could be acceptable in this case, since for `split_last` the scalar `&T` doesn't have any internal order to maintain with the other items.
## Unresolved questions
Do we want to reserve the same names on `[u8; N]` to avoid inference confusion? https://github.com/rust-lang/rust/pull/117561#issuecomment-1793388647
---
`slice_first_last_chunk` has only been around since early 2023, but `split_array` has been around since 2021.
`@rustbot` label -T-libs +T-libs-api -T-libs +needs-fcp
cc `@rust-lang/wg-const-eval,` `@scottmcm` who raised this topic, `@clarfonthey` implementer of `slice_first_last_chunk` `@jethrogb` implementer of `split_array`
Zulip discussion: https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Stabilizing.20array-from-slice.20*something*.3FFixes: #111774
Update `fn()` trait implementation docs
Fixes#119903
This was FCP'd and approved for the 1.70.0 release, this is just a docs update to match that change.
Docs: Use non-SeqCst in module example of atomics
I done this for this reasons:
1. The example now shows that there is more Orderings than just SeqCst.
2. People who would copy from example would now have more suitable orderings for the job.
3. SeqCst is both much harder to reason about and not needed in most situations.
IMHO, we should encourage people to think and use memory orderings that is suitable to task instead of blindly defaulting to SeqCst.
r? `@m-ou-se`
Consolidate all associated items on the NonZero integer types into a single impl block per type
**Before:**
```rust
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
pub struct NonZeroI8(i8);
impl NonZeroI8 {
pub const fn new(n: i8) -> Option<Self> ...
pub const fn get(self) -> i8 ...
}
impl NonZeroI8 {
pub const fn leading_zeros(self) -> u32 ...
pub const fn trailing_zeros(self) -> u32 ...
}
impl NonZeroI8 {
pub const fn abs(self) -> NonZeroI8 ...
}
...
```
**After:**
```rust
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
pub struct NonZeroI8(i8);
impl NonZeroI8 {
pub const fn new(n: i8) -> Option<Self> ...
pub const fn get(self) -> i8 ...
pub const fn leading_zeros(self) -> u32 ...
pub const fn trailing_zeros(self) -> u32 ...
pub const fn abs(self) -> NonZeroI8 ...
...
}
```
Having 6-7 different impl blocks per type is not such a problem in today's implementation, but becomes awful upon the switch to a generic `NonZero<T>` type (context: https://github.com/rust-lang/rust/issues/82363#issuecomment-921513910).
In the implementation from https://github.com/rust-lang/rust/pull/100428, there end up being **67** impl blocks on that type.
<img src="https://github.com/rust-lang/rust/assets/1940490/5b68bd6f-8a36-4922-baa3-348e30dbfcc1" width="200"><img src="https://github.com/rust-lang/rust/assets/1940490/2cfec71e-c2cd-4361-a542-487f13f435d9" width="200"><img src="https://github.com/rust-lang/rust/assets/1940490/2fe00337-7307-405d-9036-6fe1e58b2627" width="200">
Without the refactor to a single impl block first, introducing `NonZero<T>` would be a usability regression compared to today's separate pages per type. With all those blocks expanded, Ctrl+F is obnoxious because you need to skip 12× past every match you don't care about. With all the blocks collapsed, Ctrl+F is useless. Getting to a state in which exactly one type's (e.g. `NonZero<u32>`) impl blocks are expanded while the rest are collapsed is annoying.
After this refactor to a single impl block, we can move forward with making `NonZero<T>` a generic struct whose docs all go on the same rustdoc page. The rustdoc will have 12 impl blocks, one per choice of `T` supported by the standard library. The reader can expand a single one of those impl blocks e.g. `NonZero<u32>` to understand the entire API of that type.
Note that moving the API into a generic `impl<T> NonZero<T> { ... }` is not going to be an option until after `NonZero<T>` has been stabilized, which may be months or years after its introduction. During the period while generic `NonZero` is unstable, it will be extra important to offer good documentation on all methods demonstrating the API being used through the stable aliases such as `NonZeroI8`.
This PR follows a `key = $value` syntax for the macros which is similar to the macros we already use for producing a single large impl block on the integer primitives.
1dd4db5062/library/core/src/num/mod.rs (L288-L309)
Best reviewed one commit at a time.