On usize=u64 platforms, the 4th iteration would overflow the `mod_gate`
back to 0. Similarly for usize=u32 platforms, the 3rd iteration would
overflow much the same way.
I tested various approaches to resolving this, including approaches with
`saturating_mul` and `widening_mul` to a double usize. Turns out LLVM
likes `mul_with_overflow` the best. In fact now, that LLVM can see the
iteration count is limited, it will happily unroll the loop into a nice
linear sequence.
You will also notice that the code around the loop got simplified
somewhat. Now that LLVM is handling the loop nicely, there isn’t any
more reasons to manually unroll the first iteration out of the loop
(though looking at the code today I’m not sure all that complexity was
necessary in the first place).
Fixes#103361
Add default trait implementations for "c-unwind" ABI function pointers
Following up on #92964, only add default trait implementations for the `c-unwind` family of function pointers. The previous attempt in #92964 added trait implementations for many more ABIs and ran into concerns regarding the increase in size of the libcore rlib.
An attempt to abstract away function pointer types behind a unified trait to reduce the duplication of trait impls is being discussed in #99531 but this change looks to be blocked on a lang MCP.
Following `@RalfJung's` suggestion in https://github.com/rust-lang/rust/pull/99531#issuecomment-1233440142, this commit is another cut at #92964 but it _only_ adds the impls for `extern "C-unwind" fn` and `unsafe extern "C-unwind" fn`.
I am interested in landing this patch to unblock the stabilization of the `c_unwind` feature.
RFC: https://github.com/rust-lang/rfcs/pull/2945
Tracking Issue: https://github.com/rust-lang/rust/issues/74990
Change process spawning to inherit the parent's signal mask by default
Previously, the signal mask was always reset when a child process is
started. This breaks tools like `nohup` which expect `SIGHUP` to be
blocked for all transitive processes.
With this change, the default behavior changes to inherit the signal mask.
This also changes the signal disposition for `SIGPIPE` to only be changed if the `#[unix_sigpipe]` attribute isn't set.
Mark `std::os::wasi::io::AsFd` etc. as stable.
io_safety was stabilized in Rust 1.63, so mark the io_safety exports in `std::os::wasi::io` as stable.
Fixes#103306.
Previously, the signal mask is always reset when a child process is
started. This breaks tools like `nohup` which expect `SIGHUP` to be
blocked.
With this change, the default behavior changes to inherit the signal mask.
This also changes the signal disposition for `SIGPIPE` to only be
changed if the `#[unix_sigpipe]` attribute isn't set.
Fixed docs typo in `library/std/src/time.rs`
* Changed comment from `Previous rust versions panicked when self was earlier than the current time.` to `Previous rust versions panicked when the current time was earlier than self.`
* Resolves#103282.
Adjust `transmute{,_copy}` to be clearer about which of `T` and `U` is input vs output
This is essentially a documentation-only change (although it does touch code in an irrelevant way).
Following up on #92964, only add default trait implementations for the
`c-unwind` family of function pointers. The previous attempt in #92964
added trait implementations for many more ABIs and ran into concerns
regarding the increase in size of the libcore rlib.
An attempt to abstract away function pointer types behind a unified
trait to reduce the duplication of trait impls is being discussed in #99531
but this change looks to be blocked on a lang MCP.
Following @RalfJung's suggestion in
https://github.com/rust-lang/rust/pull/99531#issuecomment-1233440142,
this commit is another cut at #92964 but it _only_ adds the impls for
`extern "C-unwind" fn` and `unsafe extern "C-unwind" fn`.
I am interested in landing this patch to unblock the stabilization of
the `c_unwind` feature.
RFC: https://github.com/rust-lang/rfcs/pull/2945
Tracking Issue: https://github.com/rust-lang/rust/issues/74990
Make transpose const and inline
r? `@scottmcm`
- These should have been const from the beginning since we're never going to do more than a transmute.
- Inline these always because that's what every other method in MaybeUninit which simply casts does. :) Ok, but a stronger justification is that because we're taking in arrays by `self`, not inlining would defeat the whole purpose of using `MaybeUninit` due to the copying.
Optimize `slice_iter.copied().next_chunk()`
```
OLD:
test iter::bench_copied_array_chunks ... bench: 371 ns/iter (+/- 7)
NEW:
test iter::bench_copied_array_chunks ... bench: 31 ns/iter (+/- 0)
```
The default `next_chunk` implementation suffers from having to assemble the array byte by byte via `next()`, checking the `Option<&T>` and then dereferencing `&T`. The specialization copies the chunk directly from the slice.
More slice::partition_point examples
After seeing the discussion of `binary_search` vs `partition_point` in #101999, I thought some more example code could be helpful.
doc: rewrite doc for uint::{carrying_add,borrowing_sub}
Reword the documentation for bigint helper methods `uint::{carrying_add,borrowing_sub}` (#85532).
The examples were also rewritten to demonstrate how the methods can be used in bignum arithmetic. No loops are used in the examples, but the variable names were chosen to include indices so that it is clear how this can be used in a loop if required.
Also, previously `carrying_add` had an example to say that if the input carry is false, the method is equivalent to `overflowing_add`. While the note was kept, the example was removed and an extra note was added to make sure this equivalence is not assumed for signed integers as well.
Remove the redundant `Some(try_opt!(..))` in `checked_pow`
The final return value doesn't need to be tried at all -- we can just
return the checked option directly. The optimizer can probably figure
this out anyway, but there's no need to make it work here.
Make diagnostic for unsatisfied `Termination` bounds more precise
Don't blindly emit a diagnostic claiming that “*`main` has an invalid return type*” if we encounter a type that should but doesn't implement `std::process::Termination` and isn't actually the return type of the program entry `main`.
Fixes#103052.
``@rustbot`` label A-diagnostics T-compiler T-libs
r? diagnostics
Add `Box<[T; N]>: TryFrom<Vec<T>>`
We have `[T; N]: TryFrom<Vec<T>>` (#76310) and `Box<[T; N]>: TryFrom<Box<[T]>>`, but not this combination.
`vec.into_boxed_slice().try_into()` isn't quite a replacement for this, as that'll reallocate unnecessarily in the error case.
**Insta-stable, so needs an FCP**
(I tried to make this work with `, A`, but that's disallowed because of `#[fundamental]` https://github.com/rust-lang/rust/issues/29635#issuecomment-1247598385)
The final return value doesn't need to be tried at all -- we can just
return the checked option directly. The optimizer can probably figure
this out anyway, but there's no need to make it work here.
Clarify the possible return values of `len_utf16`
`char::len_utf16` always return 1 or 2. Clarify this in the docs, in the same way as `char::len_utf8`.
Documentation BTreeMap::append's behavior for already existing keys
`BTreeMap::append` overwrites existing values with new ones. This commit adds explicit documentation for that.
Add documentation about the memory layout of `UnsafeCell<T>`
The documentation for `UnsafeCell<T>` currently does not make any promises about its memory layout. This PR adds this documentation, namely that the memory layout of `UnsafeCell<T>` is the same as the memory layout of its inner `T`.
# Use case
Without this layout promise, the following cast would not be legally possible:
```rust
fn example<T>(ptr: *mut T) -> *const UnsafeCell<T> {
ptr as *const UnsafeCell<T>
}
```
A use case where this can come up involves FFI. If Rust receives a pointer over a FFI boundary which provides shared read-write access (with some form of custom synchronization), and this pointer is managed by some Rust struct with lifetime `'a`, then it would greatly simplify its (internal) API and safety contract if a `&'a UnsafeCell<T>` can be created from a raw FFI pointer `*mut T`. A lot of safety checks can be done when receiving the pointer for the first time through FFI (non-nullness, alignment, initialize uninit bytes, etc.) and these properties can then be encoded into the `&UnsafeCell<T>` type. Without this documentation guarantee, this is not legal today outside of the standard library.
# Caveats
Casting in the opposite direction is still not valid, even with this documentation change:
```rust
fn example2<T>(ptr: &UnsafeCell<T>) -> &mut T {
let t = ptr as *const UnsafeCell<T> as *mut T;
unsafe { &mut *t }
}
```
This is because the only legal way to obtain a mutable pointer to the contents of the shared reference is through [`UnsafeCell::get`](https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html#method.get) and [`UnsafeCell::raw_get`](https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html#method.raw_get). Although there might be a desire to also make this legal at some point in the future, that part is outside the scope of this PR. Also see this relevant [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/transmuting.20.26.20-.3E.20.26mut).
# Alternatives
Instead of adding a new documentation promise, it's also possible to add a new method to `UnsafeCell<T>` with signature `pub fn from_ptr_bikeshed(ptr: *mut T) -> *const UnsafeCell<T>` which indirectly only allows one-way casting to `*const UnsafeCell<T>`.
std: use `sync::Mutex` for internal statics
Since `sync::Mutex` is now `const`-constructible, it can be used for internal statics, removing the need for `sys_common::StaticMutex`. This adds some extra allocations on platforms which need to box their mutexes (currently SGX and some UNIX), but these will become unnecessary with the lock improvements tracked in #93740.
I changed the program argument implementation on Hermit, it does not need `Mutex` but can use atomics like some UNIX systems (ping `@mkroening` `@stlankes).`