Add lint against ambiguous wide pointer comparisons
This PR is the resolution of https://github.com/rust-lang/rust/issues/106447 decided in https://github.com/rust-lang/rust/issues/117717 by T-lang.
## `ambiguous_wide_pointer_comparisons`
*warn-by-default*
The `ambiguous_wide_pointer_comparisons` lint checks comparison of `*const/*mut ?Sized` as the operands.
### Example
```rust
let ab = (A, B);
let a = &ab.0 as *const dyn T;
let b = &ab.1 as *const dyn T;
let _ = a == b;
```
### Explanation
The comparison includes metadata which may not be expected.
-------
This PR also drops `clippy::vtable_address_comparisons` which is superseded by this one.
~~One thing: is the current naming right? `invalid` seems a bit too much.~~
Fixes https://github.com/rust-lang/rust/issues/117717
guarantee that char and u32 are ABI-compatible
In https://github.com/rust-lang/rust/pull/116894 we added a guarantee that `char` has the same alignment as `u32`, but there is still one axis where these types could differ: function call ABI. So let's nail that down as well: in a function signature, `char` and `u32` are completely equivalent.
This is a new stable guarantee, so it will need t-lang approval.
`tokenstream::Spacing` appears on all `TokenTree::Token` instances,
both punct and non-punct. Its current usage:
- `Joint` means "can join with the next token *and* that token is a
punct".
- `Alone` means "cannot join with the next token *or* can join with the
next token but that token is not a punct".
The fact that `Alone` is used for two different cases is awkward.
This commit augments `tokenstream::Spacing` with a new variant
`JointHidden`, resulting in:
- `Joint` means "can join with the next token *and* that token is a
punct".
- `JointHidden` means "can join with the next token *and* that token is a
not a punct".
- `Alone` means "cannot join with the next token".
This *drastically* improves the output of `print_tts`. For example,
this:
```
stringify!(let a: Vec<u32> = vec![];)
```
currently produces this string:
```
let a : Vec < u32 > = vec! [] ;
```
With this PR, it now produces this string:
```
let a: Vec<u32> = vec![] ;
```
(The space after the `]` is because `TokenTree::Delimited` currently
doesn't have spacing information. The subsequent commit fixes this.)
The new `print_tts` doesn't replicate original code perfectly. E.g.
multiple space characters will be condensed into a single space
character. But it's much improved.
`print_tts` still produces the old, uglier output for code produced by
proc macros. Because we have to translate the generated code from
`proc_macro::Spacing` to the more expressive `token::Spacing`, which
results in too much `proc_macro::Along` usage and no
`proc_macro::JointHidden` usage. So `space_between` still exists and
is used by `print_tts` in conjunction with the `Spacing` field.
This change will also help with the removal of `Token::Interpolated`.
Currently interpolated tokens are pretty-printed nicely via AST pretty
printing. `Token::Interpolated` removal will mean they get printed with
`print_tts`. Without this change, that would result in much uglier
output for code produced by decl macro expansions. With this change, AST
pretty printing and `print_tts` produce similar results.
The commit also tweaks the comments on `proc_macro::Spacing`. In
particular, it refers to "compound tokens" rather than "multi-char
operators" because lifetimes aren't operators.
remove redundant imports
detects redundant imports that can be eliminated.
for #117772 :
In order to facilitate review and modification, split the checking code and removing redundant imports code into two PR.
r? `@petrochenkov`
Stablize arc_unwrap_or_clone
Fixes: #93610
This likely needs FCP. I created this PR as it's stabilization is trivial and FCP can be just conducted here. Not sure how to ping the libs API team (last attempt didn't work apparently according to GH UI)
detects redundant imports that can be eliminated.
for #117772 :
In order to facilitate review and modification, split the checking code and
removing redundant imports code into two PR.
Add emulated TLS support
This is a reopen of https://github.com/rust-lang/rust/pull/96317 . many android devices still only use 128 pthread keys, so using emutls can be helpful.
Currently LLVM uses emutls by default for some targets (such as android, openbsd), but rust does not use it, because `has_thread_local` is false.
This commit has some changes to allow users to enable emutls:
1. add `-Zhas-thread-local` flag to specify that std uses `#[thread_local]` instead of pthread key.
2. when using emutls, decorate symbol names to find thread local symbol correctly.
3. change `-Zforce-emulated-tls` to `-Ztls-model=emulated` to explicitly specify whether to generate emutls.
r? `@Amanieu`
OnceLock: Add note about drop and statics
Hi! Just a minor documentation addition, I've attempted to build docs locally but ran in to issues, so am not 100% sure this change will render correctly.
Elaborate on ip_addr bit conversion endianness
Adds explanation of how endianness is handled when converting `Ipv4Addr` and `Ipv6Addr` to and from bits. This is intended to unblock stabilization of the affected methods.
Addresses #113744
Before this fix we applied padding before manually doing what
`convert_benchmarks_to_tests()` does. Instead use
`convert_benchmarks_to_tests()` if applicable and then apply padding
afterwards so it becomes correct. (Benches should only be padded when
run as benches to make it easy to compare the benchmark numbers.)
Currently LLVM uses emutls by default
for some targets (such as android, openbsd),
but rust does not use it, because `has_thread_local` is false.
This commit has some changes to allow users to enable emutls:
1. add `-Zhas-thread-local` flag to specify
that std uses `#[thread_local]` instead of pthread key.
2. when using emutls, decorate symbol names
to find thread local symbol correctly.
3. change `-Zforce-emulated-tls` to `-Ztls-model=emulated`
to explicitly specify whether to generate emutls.
Use `unwinding` crate for unwinding on Xous platform
This patch adds support for using [unwinding](https://github.com/nbdd0121/unwinding) on platforms where libunwinding isn't viable. An example of such a platform is `riscv32imac-unknown-xous-elf`.
### Background
The Rust project maintains a fork of llvm at [llvm-project](https://github.com/rust-lang/llvm-project/) where it applies patches on top of the llvm project. This mostly seems to be to get unwinding support for the SGX project, and there may be other patches that I'm unaware of.
There is a lot of machinery in the build system to support compiling `libunwind` on other platforms, and I needed to add additional patches to llvm in order to add support for Xous.
Rather than continuing down this path, it seemed much easier to use a Rust-based library. The `unwinding` crate by `@nbdd0121` fits this description perfectly.
### Future work
This could potentially replace the custom patches for `libunwind` on other platforms such as SGX, and could enable unwinding support on many more exotic platforms.
### Anti-goals
This is not designed to replace `libunwind` on tier-one platforms or those where unwinding support already exists. There is already a well-established approach for unwinding there. Instead, this aims to enable unwinding on new platforms where C++ code may be difficult to compile.
The main() function takes an argument that contains the eh_frame
address. Implement `unwinding` support by looking for unwinding data at
this address.
Signed-off-by: Sean Cross <sean@xobs.io>
std: Invert logic for inclusion of `sys_common::net`
The `library/std/src/sys_common/net.rs` module is intended to define common implementations of networking-related APIs across a variety of platforms that share similar APIs (e.g. Berkeley-style sockets and all). This module is not included for more fringe targets however such as UEFI or "unknown" targets to libstd (those classified as `restricted-std`). Previously the `sys_common/net.rs` file was set up such that an allow-list indicated it shouldn't be used. This commit inverts the logic to have an allow-list of when it should be used instead.
The goal of this commit is to make it a bit easier to experiment with a new Rust target. Currently more esoteric targets are required to get an exception in this `cfg_if` block to use `crate::sys::net` such as for unsupported targets. With this inversion of logic only targets which actually support networking will be listed, where most of those are lumped under `cfg(unix)`.
Given that this change is likely to cause some breakage for some target by accident I've attempted to be somewhat robust with this by following these steps to defining the new predicate for inverted logic.
1. Take all supported targets and filter out all `cfg(unix)` ones as these should all support `sys_common/net.rs`.
2. Take remaining targets and filter out `cfg(windows)` ones.
3. The remaining dozen-or-so targets were all audited by hand. Mostly this included `target_os = "hermit"` and `target_os = "solid_asp3"` which required an allow-list entry, but remaining targets were all already excluded (didn't use `sys_common/net.rs` so they were left out.
If this causes breakage it should be relatively easy to fix and I'd be happy to follow-up with any PRs necessary.
Split `Vec::dedup_by` into 2 cycles
First cycle runs until we found 2 same elements, second runs after if there any found in the first one. This allows to avoid any memory writes until we found an item which we want to remove.
This leads to significant performance gains if all `Vec` items are kept: -40% on my benchmark with unique integers.
Results of benchmarks before implementation (including new benchmark where nothing needs to be removed):
* vec::bench_dedup_all_100 74.00ns/iter +/- 13.00ns
* vec::bench_dedup_all_1000 572.00ns/iter +/- 272.00ns
* vec::bench_dedup_all_100000 64.42µs/iter +/- 19.47µs
* __vec::bench_dedup_none_100 67.00ns/iter +/- 17.00ns__
* __vec::bench_dedup_none_1000 662.00ns/iter +/- 86.00ns__
* __vec::bench_dedup_none_10000 9.16µs/iter +/- 2.71µs__
* __vec::bench_dedup_none_100000 91.25µs/iter +/- 1.82µs__
* vec::bench_dedup_random_100 105.00ns/iter +/- 11.00ns
* vec::bench_dedup_random_1000 781.00ns/iter +/- 10.00ns
* vec::bench_dedup_random_10000 9.00µs/iter +/- 5.62µs
* vec::bench_dedup_random_100000 449.81µs/iter +/- 74.99µs
* vec::bench_dedup_slice_truncate_100 105.00ns/iter +/- 16.00ns
* vec::bench_dedup_slice_truncate_1000 2.65µs/iter +/- 481.00ns
* vec::bench_dedup_slice_truncate_10000 18.33µs/iter +/- 5.23µs
* vec::bench_dedup_slice_truncate_100000 501.12µs/iter +/- 46.97µs
Results after implementation:
* vec::bench_dedup_all_100 75.00ns/iter +/- 9.00ns
* vec::bench_dedup_all_1000 494.00ns/iter +/- 117.00ns
* vec::bench_dedup_all_100000 58.13µs/iter +/- 8.78µs
* __vec::bench_dedup_none_100 52.00ns/iter +/- 22.00ns__
* __vec::bench_dedup_none_1000 417.00ns/iter +/- 116.00ns__
* __vec::bench_dedup_none_10000 4.11µs/iter +/- 546.00ns__
* __vec::bench_dedup_none_100000 40.47µs/iter +/- 5.36µs__
* vec::bench_dedup_random_100 77.00ns/iter +/- 15.00ns
* vec::bench_dedup_random_1000 681.00ns/iter +/- 86.00ns
* vec::bench_dedup_random_10000 11.66µs/iter +/- 2.22µs
* vec::bench_dedup_random_100000 469.35µs/iter +/- 20.53µs
* vec::bench_dedup_slice_truncate_100 100.00ns/iter +/- 5.00ns
* vec::bench_dedup_slice_truncate_1000 2.55µs/iter +/- 224.00ns
* vec::bench_dedup_slice_truncate_10000 18.95µs/iter +/- 2.59µs
* vec::bench_dedup_slice_truncate_100000 492.85µs/iter +/- 72.84µs
Resolves#77772
P.S. Note that this is same PR as #92104 I just missed review then forgot about it.
Also, I cannot reopen that pull request so I am creating a new one.
I responded to remaining questions directly by adding commentaries to my code.
Use OnceCell in cell module documentation
The spanning tree example in the std cell module implementation was created before `OnceCell` was added to Rust so it uses `RefCell`. However, in this case using `OnceCell` seems more appropriate and produces simpler code. As a bonus, this also means that all three cell types are presented in the examples of std cell module.
Add support for making lib features internal
We have the notion of an "internal" lang feature: a feature that is never intended to be stabilized, and using which can cause ICEs and other issues without that being considered a bug.
This extends that idea to lib features as well. It is an alternative to https://github.com/rust-lang/rust/pull/115623: instead of using an attribute to declare lib features internal, we simply do this based on the name. Everything ending in `_internals` or `_internal` is considered internal.
Then we rename `core_intrinsics` to `core_intrinsics_internal`, which fixes https://github.com/rust-lang/rust/issues/115597.
Make the following API stable:
// in core::any
pub fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str
Const stability is not added because this relies on `type_name` which is also
not const. That has a blocking issue.
Fixes#66359
portable-simd: fix test suite build
``@workingjubilee`` ``@calebzulawski`` don't we run these portable-simd tests on rustc CI? Currently they don't even build here.
move exposed-provenance APIs into separate feature gate
We have already stated explicitly for all the 'exposed' functions that
> Using this method means that code is *not* following strict provenance rules.
However, they were part of the same feature gate and still described as part of the strict provenance experiment. Unfortunately, their semantics are much less clear and certainly nowhere near stabilization, so in preparation for an attempt to stabilize the strict provenance APIs, I suggest we split the things related to "exposed" into their own feature gate. I also used this opportunity to better explain how Exposed Provenance fits into the larger plan here: this is *one possible candidate* for `as` semantics, but we don't know if it is actually viable, so we can't really promise that it is equivalent to `as`. If it works out we probably want to make `as` equivalent to the 'exposed' APIs; if it doesn't, we will remove them again and try to find some other semantics for `as`.
Add substring API for `OsStr`
This adds a method for taking a substring of an `OsStr`, which in combination with [`OsStr::as_encoded_bytes()`](https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.as_encoded_bytes) makes it possible to implement most string operations in safe code.
API:
```rust
impl OsStr {
pub fn slice_encoded_bytes<R: ops::RangeBounds<usize>>(&self, range: R) -> &Self;
}
```
Motivation, examples and research at https://github.com/rust-lang/libs-team/issues/306.
Tracking issue: #118485
cc `@epage`
r? libs-api
The `library/std/src/sys_common/net.rs` module is intended to define
common implementations of networking-related APIs across a variety of
platforms that share similar APIs (e.g. Berkeley-style sockets and all).
This module is not included for more fringe targets however such as UEFI
or "unknown" targets to libstd (those classified as `restricted-std`).
Previously the `sys_common/net.rs` file was set up such that an
allow-list indicated it shouldn't be used. This commit inverts the logic
to have an allow-list of when it should be used instead.
The goal of this commit is to make it a bit easier to experiment with a
new Rust target. Currently more esoteric targets are required to get an
exception in this `cfg_if` block to use `crate::sys::net` such as for
unsupported targets. With this inversion of logic only targets which
actually support networking will be listed, where most of those are
lumped under `cfg(unix)`.
Given that this change is likely to cause some breakage for some target
by accident I've attempted to be somewhat robust with this by following
these steps to defining the new predicate for inverted logic.
1. Take all supported targets and filter out all `cfg(unix)` ones as
these should all support `sys_common/net.rs`.
2. Take remaining targets and filter out `cfg(windows)` ones.
3. The remaining dozen-or-so targets were all audited by hand. Mostly
this included `target_os = "hermit"` and `target_os = "solid_asp3"`
which required an allow-list entry, but remaining targets were all
already excluded (didn't use `sys_common/net.rs` so they were left
out.
If this causes breakage it should be relatively easy to fix and I'd be
happy to follow-up with any PRs necessary.
Use `usize::repeat_u8` instead of implementing `repeat_byte` in `memchr.rs`
It's simpler that way and the tricks don't actually make a difference: https://godbolt.org/z/zrvYY1dGx
remove the memcpy-on-equal-ptrs assumption
One of the libc we support, musl, [defines `memcpy` with `restrict` pointers](https://git.musl-libc.org/cgit/musl/tree/src/string/memcpy.c#n5). This in fact matches the definition in the C standard. Calling that `memcpy` with overlapping pointers is clearly UB, who knows what the compiler did when optimizing this `memcpy` -- it certainly assumed source and destination to be disjoint.
Lucky enough, it does not seem like we actually need this assumption that `memcpy(p, p, n)` is always allowed. clang and GCC need it since they use `memcpy` to compile C assignments, but [we use memmove for similar code](https://godbolt.org/z/bcW85WYcM). There are no known cases where LLVM introduces calls to memcpy on equal pointers itself. (And if there were, that would be a soundness bug in rustc due to the musl issue mentioned above.)
This does mean we must make sure to never call the LLVM `memcpy` builtin on equal ranges even though the LangRef says that is allowed. Currently that is the case so we just need to make sure it remains the case. :) Cc `@rust-lang/opsem` `@rust-lang/wg-llvm`
Implement thread parking for xous
This follows the pattern set by [the Windows parker](ddef56d5df/library/std/src/sys/windows/thread_parking.rs) when it uses keyed events. An atomic variable is used to track the state and optimize the fast path, while notifications are send via the ticktime server to block and unblock the thread.
ping `@xobs`
`@rustbot` label +T-libs +A-atomic
r? libs
unify read_to_end and io::copy impls for reading into a Vec
This ports over the initial probe (to avoid allocation) and the dynamic read sizing from the io::copy specialization to the `default_read_to_end` implementation which already had its own optimizations for different cases.
I think it should be a best-of-both now.
suggested by `@a1phyr` in https://github.com/rust-lang/rust/pull/117576#issuecomment-1803408492
Expand in-place iteration specialization to Flatten, FlatMap and ArrayChunks
This enables the following cases to collect in-place:
```rust
let v = vec![[0u8; 4]; 1024]
let v: Vec<_> = v.into_iter().flatten().collect();
let v: Vec<Option<NonZeroUsize>> = vec![NonZeroUsize::new(0); 1024];
let v: Vec<_> = v.into_iter().flatten().collect();
let v = vec![u8; 4096];
let v: Vec<_> = v.into_iter().array_chunks::<4>().collect();
```
Especially the nicheful-option-flattening should be useful in real code.
Fix comments for unsigned non-zero `checked_add`, `saturating_add`
While looking at #118313, I happened to notice that two of the expanded comments appear to be slightly inaccurate.
For these two methods, `other` is an ordinary unsigned integer, so it can be zero.
Since the sum of non-zero and zero is always non-zero, the safety argument holds even when `other` is zero.
Update mod comment
The comment of `ASCII_CASE_MASK` on line 477 is `If 6th bit is set ascii is lower case.` but the original comment of `*self ^ ((self.is_ascii_lowercase() as u8) * ASCII_CASE_MASK)` was `Toggle the fifth bit if this is a lowercase letter`
For these two methods, `other` is an ordinary unsigned integer, so it can be zero.
Since the sum of non-zero and zero is always non-zero, the safety argument
holds even when `other` is zero.
rustdoc: Remove space from fake-variadic fn ptr impls
before: `for fn (T₁, T₂, …, Tₙ) -> Ret`
after: `for fn(T₁, T₂, …, Tₙ) -> Ret`
I don't think we usually have spaces there, so it looks weird.
cc `@notriddle` since you added the space in https://github.com/rust-lang/rust/pull/98180 (or rather, added the feature with a space included).
Non null convenience ops
Based on https://github.com/rust-lang/libs-team/issues/251.
I went through all of the methods on `*mut` and added every method, which does not require additional safety conditions, to `NonNull`. (exceptions: `guaranteed_eq`, `guaranteed_ne`, `with_metadata_of`, it's unclear if they are useful here...)
I'm also not sure what types should the "second pointer parameter" be. `*mut`/`*const` might be more permissible, but given that `NonNull` doesn't coerce to them, it might also be annoying. For now I chose the "use `NonNull` everywhere" path, but I'm not sure it's the correct one...
<sub>I'm eepy, so I probably messed up somewhere while copying...</sub>
cc `@scottmcm`
r? libs-api
Add `debug_assert_nounwind` and convert `assert_unsafe_precondition`
`assert_unsafe_precondition` checks non-CTFE-evaluable conditions in runtime and performs no-op in compile time, while many of its current usage can be checked during const eval.
Fixes error count display is different when there's only one error left
Supersedes #114759
### What did I do?
I did the small change in `rustc_errors` by hand. Then I did the other changes in `/compiler` by hand, those were just find replace on `*.rs` in the workspace. The changes in run-make are find replace for `run-make` in the workspace.
All other changes are blessed using `x test TEST --bless`. I blessed the tests that were blessed in #114759.
### how to review this nightmare
ping bors with an `r+`. You should check that my logic is sound and maybe quickly scroll through the diff, but fully verifying it seems fairly hard to impossible. I did my best to do this correctly.
Thank you `@adrianEffe` for bringing this up and your initial implementation.
cc `@flip1995,` you said you want to do a subtree sync asap
cc `@RalfJung` maybe you want to do a quick subtree sync afterwards as well for Miri
r? `@WaffleLapkin`
Indicate that multiplication in Layout::array cannot overflow
Since https://github.com/rust-lang/rust/pull/113113, we have added a check that skips calling into the allocator at all if `capacity == 0`. The global, default allocator will not actually try to allocate though; it returns a dangling pointer explicitly. However, these two checks are not merged/deduplicated by LLVM and so we're comparing to zero twice whenever vectors are allocated/grown. Probably cheap, but also potentially expensive in code size and seems like an unfortunate miss.
This removes that extra check by telling LLVM that the multiplication as part of Layout::array can't overflow, turning the original non-zero value into a zero value afterwards. In my checks locally this successfully drops the duplicate comparisons.
See https://rust.godbolt.org/z/b6nPP9dcK for a code example.
```rust
pub fn foo(elements: usize) -> Vec<u32> {
Vec::with_capacity(elements)
}
```
r? `@scottmcm` since you touched this in a32305a80f - curious if you have thoughts on doing this / can confirm my model of this being correct.
Use an absolute path to the NUL device
While a bare "NUL" *should* be redirected to the NUL device, especially in this simple case, let's be explicit that we aren't opening a file called "NUL" and instead open it directly.
This will also set a good example for people copying std code.
r? libs
Update windows-bindgen and define `INVALID_HANDLE_VALUE` ourselves
We generate bindings to the Windows API via the `windows-bindgen` crate, which is ultimately what's also used to generate the `windows-sys` and `windows` crates. However, there currently is some custom sauce just for std which makes it a bit different from the vanilla bindings. I would love for us to reduce and eventually remove the differences entirely so that std is using the exact same bindings as everyone else. Maybe in the future we can even just have a normal dependency on `windows-sys`.
This PR removes one of those special things. Our definition of `INVALID_HANDLE_VALUE` relies on an experimental nightly feature for strict provenance, so lets bring that back in house. It also excludes it from the codegen step though that isn't strictly necessary as we override it in any case.
This PR also updates windows-bingen to 0.52.0.
Improve rewind documentation
The persistent use of an internal cursor for readers is expected for buffer data types that aren't read all at once, but for files it leads to the confusing situation where calling `read_to_end` on the same file handle multiple times only returns the contents of the file for the first call. This PR adds a note to the documentation clarifying that in that case, `rewind()` must first be called.
I'm unsure if this is the right location for the docs update. Maybe it should also be duplicated on `File`?
This allows LLVM to optimize comparisons to zero before & after the
multiplication into one, saving on code size and eliminating an (always
true) branch from most Vec allocations.
kmc-solid: I/O safety
Adds the I/O safety API (#87329) for socket file descriptors in [`*-kmc-solid_*`](https://doc.rust-lang.org/nightly/rustc/platform-support/kmc-solid.html) Tier 3 targets. All new public items are gated by the `solid_ext` library feature.
This PR adds the following public types and traits:
std::os::solid::io::AsFd
std::os::solid::io::BorrowedFd
std::os::solid::io::OwnedFd
std::os::solid::prelude::AsFd (re-export)
std::os::solid::prelude::BorrowedFd (re-export)
std::os::solid::prelude::OwnedFd (re-export)
And trait implementations:
From<std::net::TcpListener> for std::os::solid::io::OwnedFd
From<std::net::TcpStream> for std::os::solid::io::OwnedFd
From<std::net::UdpSocket> for std::os::solid::io::OwnedFd
From<std::os::solid::io::OwnedFd> for std::net::TcpListener
From<std::os::solid::io::OwnedFd> for std::net::TcpStream
From<std::os::solid::io::OwnedFd> for std::net::UdpSocket
std::fmt::Debug for std::os::solid::io::BorrowedFd<'_>
std::fmt::Debug for std::os::solid::io::OwnedFd
std::io::IsTerminal for std::os::solid::io::BorrowedFd<'_>
std::io::IsTerminal for std::os::solid::io::OwnedFd
std::os::fd::AsRawFd for std::os::solid::io::BorrowedFd<'_>
std::os::fd::AsRawFd for std::os::solid::io::OwnedFd
std::os::fd::FromRawFd for std::os::solid::io::OwnedFd
std::os::fd::IntoRawFd for std::os::solid::io::OwnedFd
std::os::solid::io::AsFd for &impl std::os::solid::io::AsFd
std::os::solid::io::AsFd for &mut impl std::os::solid::io::AsFd
std::os::solid::io::AsFd for Arc<impl std::os::solid::io::AsFd>
std::os::solid::io::AsFd for Box<impl std::os::solid::io::AsFd>
std::os::solid::io::AsFd for Rc<impl std::os::solid::io::AsFd>
std::os::solid::io::AsFd for std::net::TcpListener
std::os::solid::io::AsFd for std::net::TcpStream
std::os::solid::io::AsFd for std::net::UdpSocket
std::os::solid::io::AsFd for std::os::solid::io::BorrowedFd<'_>
std::os::solid::io::AsFd for std::os::solid::io::OwnedFd
Taking advantage of the above change, this PR also refactors the internal details of `std::sys::solid::net` to match the design of other targets, e.g., by redefining `Socket` as a newtype of `OwnedFd`.
Fix some clippy lints for library/std/src/sys/windows
These issues were shown by running `x clippy` on `library/std` and filtering for `windows/` paths. I think running clippy on the full std would be great but I wanted to start smaller and with something that's hopefully easier to review. It'd be good to eventually run clippy in CI but that's a bigger conversation.
I've created separate commits for each clippy lint fixed (with the commit title set to the lint name) and reviewed the changes myself. Most of the fixes here are trivial.
r? libs
This is where our Windows API bindings previously (and incorrectly) used `*mut` instead of `*const` pointers. Now that the bindings have been corrected, the mutable references (which auto-convert to `*mut`) are unnecessary and we can use shared references.
feat: specialize `SpecFromElem` for `()`
# Description
This PR adds a specialization `SpecFromElem for ()` which allows to significantly reduce `vec![(), N]` time in debug builds (specifically, tests) turning it from observable $O(n)$ to $O(1)$.
# Observing the change
The problem this PR aims to fix explicitly is slow `vec![(), N]` on big `N`s which may appear in tests (see [Background section](#Background) for more details).
The minimal example to see the problem:
```rust
#![feature(test)]
extern crate test;
#[cfg(test)]
mod tests {
const HUGE_SIZE: usize = i32::MAX as usize + 1;
#[bench]
fn bench_vec_literal(b: &mut test::Bencher) {
b.iter(|| vec![(); HUGE_SIZE]);
}
#[bench]
fn bench_vec_repeat(b: &mut test::Bencher) {
b.iter(|| [(); 1].repeat(HUGE_SIZE));
}
}
```
<details><summary>Output</summary>
<p>
```bash
cargo +nightly test -- --report-time -Zunstable-options
Compiling huge-zst-vec-literal-bench v0.1.0 (/home/progrm_jarvis/RustroverProjects/huge-zst-vec-literal-bench)
Finished test [unoptimized + debuginfo] target(s) in 0.31s
Running unittests src/lib.rs (target/debug/deps/huge_zst_vec_literal_bench-e43b1ef287ba8b36)
running 2 tests
test tests::bench_vec_repeat ... ok <0.000s>
test tests::bench_vec_literal ... ok <14.382s>
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 14.38s
Doc-tests huge-zst-vec-literal-bench
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
```
</p>
</details>
> [!IMPORTANT]
> This problem is only observable in Debug (unoptimized) builds, while Release (optimized) ones do not observe this problem. It still is worth fixing it, IMO, since the original scenario observes the problem in tests for which optimizations are disabled by default and it seems unreasonable to override this for the whole project while the problem is very local.
# Background
While working on a crate for a custom data format which has an `i32::MAX` limit on its list's sizes, I wrote the following test to ensure that this invariant is upheld:
```rust
#[test]
fn lists_should_have_i32_size() {
assert!(
RawNbtList::try_from(vec![(); i32::MAX as usize]).is_ok(),
"lists should permit the size up to {}",
i32::MAX
);
assert!(
RawNbtList::try_from(vec![(); i32::MAX as usize + 1]).is_err(),
"lists should have the size of at most {}",
i32::MAX
);
}
```
Soon I discovered that this takes $\approx 3--4s$ per assertion on my machine, almost all of which is spent on `vec![..]`.
While this would be logical for a non-ZST vector (which would require actual $O(n)$ allocation), here `()` was used intentionally considering that for ZSTs size-changing operations should anyway be $O(1)$ (at least from allocator perspective). Yet, this "overhead" is logical if we consider that in general case `clone()` (which is used by `Vec` literal) may have a non-trivial implementation and thus each element has to actually be visited (even if they occupy no space).
In my specific case, the following (contextual) equivalent solved the issue:
```rust
#[test]
fn lists_should_have_i32_size() {
assert!(
RawNbtList::try_from([(); 1].repeat(i32::MAX as usize)).is_ok(),
"lists should permit the size up to {}",
i32::MAX
);
assert!(
RawNbtList::try_from([(); 1].repeat(i32::MAX as usize + 1)).is_err(),
"lists should have the size of at most {}",
i32::MAX
);
}
```
which works since `repeat` explicitly uses `T: Copy` and so does not have to think about non-trivial `Clone`.
But it still may be counter-intuitive for users to observe such long time on the "canonical" vec literal thus the PR.
# Generic solution
This change is explicitly non-generic. Initially I considered it possible to implement in generically, but this would require the specialization to have the following type requirements:
- ✅ the type must be a ZST: easily done via
```rust
if core::mem::size_of::<T>() == 0 {
todo!("specialization")
}
```
or
```rust
use core::mem::SizedTypeProperties;
if T::IS_ZST {
todo!("specialization")
}
```
- :white_check_mark`: the type must implement `Copy`: implementable non-conflictable via a separate specialization:
```rust
trait IsCopyZst: Sized {
fn is_copy_zst() -> bool;
}
impl<T> IsCopyZst for T {
fn is_copy_zst() -> bool {
false
}
}
impl<T: Copy> IsCopyZst for T {
fn is_copy_zst() -> bool {
Self::IS_ZST
}
}
```
- ❌ the type should have a trivial `Clone` implementation: since `vec![t; n]` is specified to use `clone()`, we can only use this "performance optimization" when we are guaranteed that `clone()` does nothing except for copying.
The latter is the real blocker for a generic fix since I am unaware of any way to get this information in a compiler-guaranteed way.
While there may be a fix for this (my friend `@CertainLach` has suggested a potential solution by an perma-unstable fn in `Clone` like `is_trivially_cloneable()` defaulting to `false` and only overridable by `rustc` on derive), this is surely out of this PRs scope.
While a better approach would be to implement it for all ZSTs
which are `Copy` and have trivial `Clone`,
the last property cannot be detected for now.
Signed-off-by: Petr Portnov <me@progrm-jarvis.ru>
While a bare "NUL" *should* be redirected to the NUL device, especially in this simple case, let's be explicit that we aren't opening a file called "NUL" and instead open it directly.
This will also set a good example for people copying std code.
Adjust frame IP in backtraces relative to image base for SGX target
This is followup to https://github.com/rust-lang/backtrace-rs/pull/566.
The backtraces printed by `panic!` or generated by `std::backtrace::Backtrace` in SGX target are not usable. The frame addresses need to be relative to image base address so they can be used for symbol resolution. Here's an example panic backtrace generated before this change:
```
$ cargo r --target x86_64-fortanix-unknown-sgx
...
stack backtrace:
0: 0x7f8fe401d3a5 - <unknown>
1: 0x7f8fe4034780 - <unknown>
2: 0x7f8fe401c5a3 - <unknown>
3: 0x7f8fe401d1f5 - <unknown>
4: 0x7f8fe401e6f6 - <unknown>
```
Here's the same panic after this change:
```
$ cargo +stage1 r --target x86_64-fortanix-unknown-sgx
stack backtrace:
0: 0x198bf - <unknown>
1: 0x3d181 - <unknown>
2: 0x26164 - <unknown>
3: 0x19705 - <unknown>
4: 0x1ef36 - <unknown>
```
cc `@jethrogb` and `@workingjubilee`
Add Seek::seek_relative
The `BufReader` struct has a `seek_relative` method because its `Seek::seek` implementation involved dumping the internal buffer (https://github.com/rust-lang/rust/issues/31100).
Unfortunately, there isn't really a good way to take advantage of that method in generic code. This PR adds the same method to the main `Seek` trait with the straightforward default method, and an override for `BufReader` that calls its implementation.
_Also discussed in [this](https://internals.rust-lang.org/t/add-seek-seek-relative/19546) internals.rust-lang.org thread._
Remove option_payload_ptr; redundant to offset_of
The `option_payload_ptr` intrinsic is no longer required as `offset_of` supports traversing enums (#114208). This PR removes it in order to dogfood offset_of (as suggested at https://github.com/rust-lang/rust/issues/106655#issuecomment-1790907626). However, it will not build until those changes reach beta (which I think is within the next 8 days?) so I've opened it as a draft.
Expose tests for {f32,f64}.total_cmp in docs
Expose tests for {f32,f64}.total_cmp in docs
Uncomment the helpful `assert_eq!` line, which is stripped out completely in docs, and leaves the reader to mentally play through the algorithm, or go to the playground and add a println!, to see what the result will be.
(If these tests are known to fail on some platforms, is there some mechanism to conditionalize this or escape the test so the `assert_eq!` source will be visible on the web? I am a newbie, which is why I was reading docs ;)
impl more traits for ptr::Alignment, add mask method
Changes:
* Adds `rustc_const_unstable` attributes where missing
* Makes `log2` method const
* Adds `mask` method
* Implements `Default`, which is equivalent to `Alignment::MIN`
No longer included in PR:
* Removes indirection of `AlignmentEnum` type alias (this was intentional)
* Implements `Display`, `Binary`, `Octal`, `LowerHex`, and `UpperHex` (should go through libs-api instead)
* Controversially implements `LowerExp` and `UpperExp` using `p` instead of `e` to indicate a power of 2 (also should go through libs-api)
Tracking issue for `ptr::Alignment`: #102070
Reenable effects in libcore
With #116670, #117531, and #117171, I think we would be comfortable with re-enabling the effects feature for more testing in libcore.
r? `@oli-obk`
cc `@fmease`
cc #110395
Add T: ?Sized to `RwLockReadGuard` and `RwLockWriteGuard`'s Debug impls.
For context, `MutexGuard` has `+ ?Sized` on its `Debug` impl, and all three have `+ ?Sized` on their `Display` impls.
It looks like the `?Sized` was just missed when the impls were added (the impl for `MutexGuard` was added in the same PR (https://github.com/rust-lang/rust/pull/38006) with support for `T: Debug + ?Sized`, and `RwLock*Guard`s did allow `T: ?Sized` types already); the `Display` impls were added later (https://github.com/rust-lang/rust/pull/42822) with support for `T: Debug + ?Sized` types.
I think this needs a T-libs-api FCP? I'm not sure if this also needs an ACP. If so I can make one.
These are changes to (stable) trait impls on stable types so will be insta-stable.
`@rustbot` label +T-libs-api
Remove asmjs
Fulfills [MCP 668](https://github.com/rust-lang/compiler-team/issues/668).
`asmjs-unknown-emscripten` does not work as-specified, and lacks essential upstream support for generating asm.js, so it should not exist at all.
feat: implement `DoubleEndedSearcher` for `CharArray[Ref]Searcher`
This PR implements `DoubleEndedSearcher` for both `CharArraySearcher` and `CharArrayRefSearcher`. I'm not sure whether this was just overlooked or if there is a reason for it, but since it behaves exactly like `CharSliceSearcher`, I think the implementations should be appropriate.
document ABI compatibility
I don't think we have any central place where we document our ABI compatibility rules, so let's create one. The `fn()` pointer type seems like a good place since ABI questions can only become relevant when invoking a function through a function pointer.
This will likely need T-lang FCP.
avoid exhaustive i16 test in Miri
https://github.com/rust-lang/rust/pull/116301 added a test that is way too slow to be running in Miri. So let's only test a few hopefully representative cases.
Xous as an operating system is compiled with gcc-type personalities when
it comes to unwinding. This enables unwinding inside panics on Xous,
which enables Rust tests.
Signed-off-by: Sean Cross <sean@xobs.io>
The `unwinding` crate supports processing unwinding data, and is written
entirely in Rust. This allows it to be ported to new platforms more
easily than using the llvm-based `libunwind`.
While `libunwind` is very well supported on major targets, it is
difficult to use on other targets. SGX is an example of this where Rust
carries custom patches in order to enable backtrace support.
This adds an alternative for supported architectures. Rather than
providing a custom target, `unwinding` allows for a solution that is
completely written in Rust.
This adds `xous` as the first consumer, and forthcoming patches will
modify libstd to take advantage of this.
Signed-off-by: Sean Cross <sean@xobs.io>
Custom MIR: Support cleanup blocks
Cleanup blocks are declared with `bb (cleanup) = { ... }`.
`Call` and `Drop` terminators take an additional argument describing the unwind action, which is one of the following:
* `UnwindContinue()`
* `UnwindUnreachable()`
* `UnwindTerminate(reason)`, where reason is `ReasonAbi` or `ReasonInCleanup`
* `UnwindCleanup(block)`
Also support unwind resume and unwind terminate terminators:
* `UnwindResume()`
* `UnwindTerminate(reason)`
Cleanup blocks are declared with `bb (cleanup) = { ... }`.
`Call` and `Drop` terminators take an additional argument describing the
unwind action, which is one of the following:
* `UnwindContinue()`
* `UnwindUnreachable()`
* `UnwindTerminate(reason)`, where reason is `ReasonAbi` or `ReasonInCleanup`
* `UnwindCleanup(block)`
Also support unwind resume and unwind terminate terminators:
* `UnwindResume()`
* `UnwindTerminate(reason)`
Add `std:#️⃣:{DefaultHasher, RandomState}` exports (needs FCP)
This implements rust-lang/libs-team#267 to move the libstd hasher types to `std::hash` where they belong, instead of `std::collections::hash_map`.
<details><summary>The below no longer applies, but is kept for clarity.</summary>
This is a small refactor for #27242, which moves the definitions of `RandomState` and `DefaultHasher` into `std::hash`, but in a way that won't be noticed in the public API.
I've opened rust-lang/libs-team#267 as a formal ACP to move these directly into the root of `std::hash`, but for now, they're at least separated out from the collections code in a way that will make moving that around easier.
I decided to simply copy the rustdoc for `std::hash` from `core::hash` since I think it would be ideal for the two to diverge longer-term, especially if the ACP is accepted. However, I would be willing to factor them out into a common markdown document if that's preferred.
</details>
Clarify UB in `get_unchecked(_mut)`
Inspired by #116915, it was unclear to me what exactly "out-of-bounds index" means in `get_unchecked`.
One could [potentially](https://rust.godbolt.org/z/hxM764orW) interpret it that `get_unchecked` is just another way to write `offset`, but I think `get_unchecked(len)` is supposed to be UB even though `.offet(len)` is well-defined (as is `.get_unchecked(..len)`), so write that more directly in the docs.
**libs-api folks**: Can you confirm whether this is what you expect this to mean? And is the situation any different for `<*const [T]>::get_unchecked`?
patterns: reject raw pointers that are not just integers
Matching against `0 as *const i32` is fine, matching against `&42 as *const i32` is not.
This extends the existing check against function pointers and wide pointers: we now uniformly reject all these pointer types during valtree construction, and then later lint because of that. See [here](https://github.com/rust-lang/rust/pull/116930#issuecomment-1784654073) for some more explanation and context.
Also fixes https://github.com/rust-lang/rust/issues/116929.
Cc `@oli-obk` `@lcnr`
Refactor the if/else checking on cmp::Ordering variants to a
"branchless" reassignment of left and right. This change results
in fewer branches and instructions.
Removes the private type `std::sys::solid::net::FileDesc`, replacing its
only usage in `std::sys::solid::net::Socket` with `std::os::solid::io::
OwnedFd`.
Documentation cleanup for core::error::Request.
This part of the documentation currently render like this:
![image](https://github.com/rust-lang/rust/assets/249196/b34cb907-4ce4-4e85-beca-510d8aa1fefb)
The new version renders like this:
![image](https://github.com/rust-lang/rust/assets/249196/fe18398a-15fb-42a7-82a4-f1856d48bd79)
Fixes:
* Add missing closing back tick.
* Remove spurious double back ticks.
* Add missing newline to render bullet point correctly.
* Fix grammar "there are methods calledrequest_ref and request_value are available" -> "there are methods calledrequest_ref and request_value".
* Change "methods" to "functions", which seems more appropriate for free functions.
document that the null pointer has the 0 address
Fixes https://github.com/rust-lang/rust/issues/116895
Will need t-lang FCP, but I think this is fairly uncontroversial -- there's probably already tons of code out there that relies on this.