Link loop/for keyword
Even though the reference already have all of these, I am just adding related keywords in the see also to let others easily click on the related keyword.
std::iter: document iteration over `&T` and `&mut T`
A colleague of mine is new to Rust, and mentioned that it was “slightly
confusing” to figure out what `&mut` does in iterating over `&mut foo`:
```rust
for value in &mut self.my_vec {
// ...
}
```
My colleague had read the `std::iter` docs and not found the answer
there. There is a brief section at the top about “the three forms of
iteration”, which mentions `iter_mut`, but it doesn’t cover the purpose
of `&mut coll` for a collection `coll`. This patch adds an explanatory
section to the docs. I opted to create a new section so that it can
appear after the note that `impl<I: Iterator> IntoIterator for I`, and
it’s nice for the existing “three forms of iteration” to appear near the
top.
Test Plan:
Ran `./x.py doc library/core`, and the result looked good, including
links. Manually copy-pasted the two doctests into the playground and ran
them.
wchargin-branch: doc-iter-by-reference
Windows TLS: ManuallyDrop instead of mem::forget
The Windows TLS implementation still used `mem::forget` instead of `ManuallyDrop`, leading to the usual problem of "using" the `Box` when it should not be used any more.
Clarify that String::split_at takes a byte index.
To someone skimming through the `String` docs and only reads the first line, the person could interpret "index" to be "char index". Later on in the docs it clarifies, but by adding "byte" it removes that ambiguity.
Dogfood `str_split_once()`
Part of https://github.com/rust-lang/rust/issues/74773.
Beyond increased clarity, this fixes some instances of a common confusion with how `splitn(2)` behaves: the first element will always be `Some()`, regardless of the delimiter, and even if the value is empty.
Given this code:
```rust
fn main() {
let val = "...";
let mut iter = val.splitn(2, '=');
println!("Input: {:?}, first: {:?}, second: {:?}", val, iter.next(), iter.next());
}
```
We get:
```
Input: "no_delimiter", first: Some("no_delimiter"), second: None
Input: "k=v", first: Some("k"), second: Some("v")
Input: "=", first: Some(""), second: Some("")
```
Using `str_split_once()` makes more clear what happens when the delimiter is not found.
Make the kernel_copy tests more robust/concurrent.
These tests write to the same filenames in /tmp and in some cases these files don't get cleaned up properly. This caused issues for us when different users run the tests on the same system, e.g.:
```
---- sys::unix::kernel_copy::tests::bench_file_to_file_copy stdout ----
thread 'sys::unix::kernel_copy::tests::bench_file_to_file_copy' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 13, kind: PermissionDenied, message: "Permission denied" }', library/std/src/sys/unix/kernel_copy/tests.rs:71:10
---- sys::unix::kernel_copy::tests::bench_file_to_socket_copy stdout ----
thread 'sys::unix::kernel_copy::tests::bench_file_to_socket_copy' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 13, kind: PermissionDenied, message: "Permission denied" }', library/std/src/sys/unix/kernel_copy/tests.rs💯10
```
Use `std::sys_common::io__test::tmpdir()` to solve this.
CC ``@the8472.``
Improve documentation for `std::{f32,f64}::mul_add`
Makes it more clear that performance improvement is not guaranteed when using FMA, even when the target architecture supports it natively.
Add some core::cmp::Ordering helpers
...to allow easier equal-to-or-greater-than and less-than-or-equal-to
comparisons.
Prior to Rust 1.42 a greater-than-or-equal-to comparison might be written
either as a match block, or a traditional conditional check like this:
```rust
if cmp == Ordering::Equal || cmp == Ordering::Greater {
// Do something
}
```
Which requires two instances of `cmp`. Don't forget that while `cmp` here
is very short, it could be something much longer in real use cases.
From Rust 1.42 a nicer alternative is possible:
```rust
if matches!(cmp, Ordering::Equal | Ordering::Greater) {
// Do something
}
```
The commit adds another alternative which may be even better in some cases:
```rust
if cmp.is_equal_or_greater() {
// Do something
}
```
The earlier examples could be cleaner than they are if the variants of
`Ordering` are imported such that `Equal`, `Greater` and `Less` can be
referred to directly, but not everyone will want to do that.
The new solution can shorten lines, help avoid logic mistakes, and avoids
having to import `Ordering` / `Ordering::*`.
Enforce no-move rule of ReentrantMutex using Pin and fix UB in stdio
A `sys_common::ReentrantMutex` may not be moved after initializing it with `.init()`. This was not enforced, but only stated as a requirement in the comments on the unsafe functions. This change enforces this no-moving rule using `Pin`, by changing `&self` to a `Pin` in the `init()` and `lock()` functions.
This uncovered a bug I introduced in #77154: stdio.rs (the only user of ReentrantMutex) called `init()` on its ReentrantMutexes while constructing them in the intializer of `SyncOnceCell::get_or_init`, which would move them afterwards. Interestingly, the ReentrantMutex unit tests already had the same bug, so this invalid usage has been tested on all (CI-tested) platforms for a long time. Apparently this doesn't break badly on any of the major platforms, but it does break the rules.\*
To be able to keep using SyncOnceCell, this adds a `SyncOnceCell::get_or_init_pin` function, which makes it possible to work with pinned values inside a (pinned) SyncOnceCell. Whether this function should be public or not and what its exact behaviour and interface should be if it would be public is something I'd like to leave for a separate issue or PR. In this PR, this function is internal-only and marked with `pub(crate)`.
\* Note: That bug is now included in 1.48, while this patch can only make it to ~~1.49~~ 1.50. We should consider the implications of 1.48 shipping with a wrong usage of `pthread_mutex_t` / `CRITICAL_SECTION` / .. which technically invokes UB according to their specification. The risk is very low, considering the objects are not 'used' (locked) before the move, and the ReentrantMutex unit tests have verified this works fine in practice.
Edit: This has been backported and included in 1.48. And soon 1.49 too.
---
In future changes, I want to push this usage of Pin further inside `sys` instead of only `sys_common`, and apply it to all 'unmovable' objects there (`Mutex`, `Condvar`, `RwLock`). Also, while `sys_common`'s mutexes and condvars are already taken care of by #77147 and #77648, its `RwLock` should still be made movable or get pinned.
...to allow easier greater-than-or-equal-to and less-than-or-equal-to
comparisons, and variant checking without needing to import the enum,
similar to `Option::is_none()` / `Option::is_some()`, in situations where
you are dealing with an `Ordering` value. (Simple `PartialOrd` / `Ord`
based evaluation may not be suitable for all situations).
Prior to Rust 1.42 a greater-than-or-equal-to comparison might be written
either as a match block, or a traditional conditional check like this:
```rust
if cmp == Ordering::Equal || cmp == Ordering::Greater {
// Do something
}
```
Which requires two instances of `cmp`. Don't forget that while `cmp` here
is very short, it could be something much longer in real use cases.
From Rust 1.42 a nicer alternative is possible:
```rust
if matches!(cmp, Ordering::Equal | Ordering::Greater) {
// Do something
}
```
The commit adds another alternative which may be even better in some cases:
```rust
if cmp.is_ge() {
// Do something
}
```
The earlier examples could be cleaner than they are if the variants of
`Ordering` are imported such that `Equal`, `Greater` and `Less` can be
referred to directly, but not everyone will want to do that.
The new solution can shorten lines, help avoid logic mistakes, and avoids
having to import `Ordering` / `Ordering::*`.
Constier maybe uninit
I was playing around trying to make `[T; N]::zip()` in #79451 be `const fn`. One of the things I bumped into was `MaybeUninit::assume_init`. Is there any reason for the intrinsic `assert_inhabited<T>()` and therefore `MaybeUninit::assume_init` not being `const`?
---
I have as best as I could tried to follow the instruction in [library/core/src/intrinsics.rs](https://github.com/rust-lang/rust/blob/master/library/core/src/intrinsics.rs#L11). I have no idea what I am doing but it seems to compile after some slight changes after the copy paste. Is this anywhere near how this should be done?
Also any ideas for name of the feature gate? I guess `const_maybe_assume_init` is quite misleading since I have added some more methods. Should I add test? If so what should be tested?
implement better availability probing for copy_file_range
Followup to https://github.com/rust-lang/rust/pull/75428#discussion_r469616547
Previously syscall detection was overly pessimistic. Any attempt to copy to an immutable file (EPERM) would disable copy_file_range support for the whole process.
The change tries to copy_file_range on invalid file descriptors which will never run into the immutable file case and thus we can clearly distinguish syscall availability.
Rollup of 12 pull requests
Successful merges:
- #79732 (minor stylistic clippy cleanups)
- #79750 (Fix trimming of lint docs)
- #79777 (Remove `first_merge` from liveness debug logs)
- #79795 (Privatize some of libcore unicode_internals)
- #79803 (Update xsv to prevent random CI failures)
- #79810 (Account for gaps in def path table during decoding)
- #79818 (Fixes to Rust coverage)
- #79824 (Strip prefix instead of replacing it with empty string)
- #79826 (Simplify visit_{foreign,trait}_item)
- #79844 (Move RWUTable to a separate module)
- #79861 (Update LLVM submodule)
- #79862 (Remove tab-lock and replace it with ctrl+up/down arrows to switch between search result tabs)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Privatize some of libcore unicode_internals
My understanding is that these API are perma unstable, so it doesn't
make sense to pollute docs & IDE completion[1] with them.
[1]: https://github.com/rust-analyzer/rust-analyzer/issues/6738
ext/ucred: Support PID in peer creds on macOS
This is a follow-up to https://github.com/rust-lang/rust/pull/75148 (RFC: https://github.com/rust-lang/rust/issues/42839).
The original PR used `getpeereid` on macOS and the BSDs, since they don't (generally) support the `SO_PEERCRED` mechanism that Linux supplies.
This PR splits the macOS/iOS implementation of `peer_cred()` from that of the BSDs, since macOS supplies the `LOCAL_PEERPID` sockopt as a source of the missing PID. It also adds a `cfg`-gated tests that ensures that platforms with support for PIDs in `UCred` have the expected data.
Use is_write_vectored to optimize the write_vectored implementation for BufWriter
In case when the underlying writer does not have an efficient implementation `write_vectored`, the present implementation of
`write_vectored` for `BufWriter` may still forward vectored writes directly to the writer depending on the total length of the data. This misses the advantage of buffering, as the actually written slice may be small.
Provide an alternative code path for the non-vectored case, where the slices passed to `BufWriter` are coalesced in the buffer before being flushed to the underlying writer with plain `write` calls. The buffer is only bypassed if an individual slice's length is at least as large as the buffer.
Remove a FIXME comment referring to #72919 as the issue has been closed with an explanation provided.
The code in io::stdio before this change misused the ReentrantMutexes,
by calling init() on them and moving them afterwards. Now that
ReentrantMutex requires Pin for init(), this mistake is no longer easy
to make.
Fix SGX CI, take 3
Broken in #79038
r? `@Mark-Simulacrum`
I actually ran `./x.py test --target x86_64-fortanix-unknown-sgx` on the commit before submitting it this time.
Fix incorrect io::Take's limit resulting from io::copy specialization
The specialization introduced in #75272 fails to update `io::Take` wrappers after performing the copy syscalls which bypass those wrappers. The buffer flushing before the copy does update them correctly, but the bytes copied after the initial flush weren't subtracted.
The fix is to subtract the bytes copied from each `Take` in the chain of wrappers, even when an error occurs during the syscall loop. To do so the `CopyResult` enum now has to carry the bytes copied so far in the error case.
Provide IntoInnerError::into_parts
Hi. This is an updated version of the IntoInnerError bits of my previous portmanteau MR #78689. Thanks to `@jyn514` and `@m-ou-se` for helpful comments there.
I have made this insta-stable since it seems like it will probably be uncontroversial, but that is definitely something that someone from the libs API team should be aware of and explicitly consider.
I included a tangentially-related commit providing documentation of the buffer full behaviiour of `&mut [u8] as Write`; the behaviour I am documenting is relied on by the doctest for `into_parts`.