Rework `init` and `cleanup`
This PR reworks the code in `std` that runs before and after `main` and centralizes this code respectively in the functions `init` and `cleanup` in both `sys_common` and `sys`. This makes is easy to see what code is executed during initialization and cleanup on each platform just by looking at e.g. `sys::windows::init`.
Full list of changes:
- new module `rt` in `sys_common` to contain `init` and `cleanup` and the runtime macros.
- `at_exit` and the mechanism to register exit handlers has been completely removed. In practice this was only used for closing sockets on windows and flushing stdout, which have been moved to `cleanup`.
- <s>On windows `alloc` and `net` initialization is now done in `init`, this saves a runtime check in every allocation and network use.</s>
Explicitly implement `!Send` and `!Sync` for `sys::{Args, Env}`
Remove the field `_dont_send_or_sync_me: PhantomData<*mut ()>` in favor of an explicit implementation of `!Send` and `!Sync`.
Move `sys_common::poison` to `sync::poison`
`sys_common` should not contain publicly exported types, only platform-independent abstractions on top of `sys`, which `sys_common::poison` is not. There is thus no reason for the module to not live under `sync`.
Part of #84187.
Remove `sys::args::Args::inner_debug` and use `Debug` instead
This removes the method `sys::args::Args::inner_debug` on all platforms and implements `Debug` for `Args` instead.
I believe this creates a more natural API for the different platforms under `sys`: export a type `Args: Debug + Iterator + ...` vs. `Args: Iterator + ...` and with a method `inner_debug`.
Move `sys_common::rwlock::StaticRWLock` etc. to `sys::unix::rwlock`
This moves `sys_common::rwlock::StaticRwLock`, `RWLockReadGuard` and `RWLockWriteGuard` to `sys::unix::rwlock`. They are already `#[cfg(unix)]` and don't need to be in `sys_common`.
Replace `Void` in `sys` with never type
This PR replaces several occurrences in `sys` of the type `enum Void {}` with the Rust never type (`!`).
The name `Void` is unfortunate because in other languages (C etc.) it refers to a unit type, not an uninhabited type.
Note that the previous stabilization of the never type was reverted, however all uses here are implementation details and not publicly visible.
Move `sys::vxworks` code to `sys::unix`
Follow-up to #77666, `sys::vxworks` is almost identical to `sys::unix`, the only differences are the `rand`, `thread_local_dtor`, and `process` implementation. Since `vxworks` is `target_family = unix` anyway, there is no reason for the code not to live inside of `sys::unix` like all the other unix-OSes.
e41f378f82/compiler/rustc_target/src/spec/vxworks_base.rs (L12)
``@rustbot`` label: +T-libs-impl
Replace all `fmt.pad` with `debug_struct`
This replaces any occurrence of:
- `f.pad("X")` with `f.debug_struct("X").finish()`
- `f.pad("X { .. }")` with `f.debug_struct("X").finish_non_exhaustive()`
This is in line with existing formatting code such as
1255053067/library/std/src/sync/mpsc/mod.rs (L1470-L1475)
Add `Unsupported` to `std::io::ErrorKind`
I noticed a significant portion of the uses of `ErrorKind::Other` in std is for unsupported operations.
The notion that a specific operation is not available on a target (and will thus never succeed) seems semantically distinct enough from just "an unspecified error occurred", which is why I am proposing to add the variant `Unsupported` to `std::io::ErrorKind`.
**Implementation**:
The following variant will be added to `std::io::ErrorKind`:
```rust
/// This operation is unsupported on this platform.
Unsupported
```
`std::io::ErrorKind::Unsupported` is an error returned when a given operation is not supported on a platform, and will thus never succeed; there is no way for the software to recover. It will be used instead of `Other` where appropriate, e.g. on wasm for file and network operations.
`decode_error_kind` will be updated to decode operating system errors to `Unsupported`:
- Unix and VxWorks: `libc::ENOSYS`
- Windows: `c::ERROR_CALL_NOT_IMPLEMENTED`
- WASI: `wasi::ERRNO_NOSYS`
**Stability**:
This changes the kind of error returned by some functions on some platforms, which I think is not covered by the stability guarantees of the std? User code could depend on this behavior, expecting `ErrorKind::Other`, however the docs already mention:
> Errors that are `Other` now may move to a different or a new `ErrorKind` variant in the future. It is not recommended to match an error against `Other` and to expect any additional characteristics, e.g., a specific `Error::raw_os_error` return value.
The most recent variant added to `ErrorKind` was `UnexpectedEof` in `1.6.0` (almost 5 years ago), but `ErrorKind` is marked as `#[non_exhaustive]` and the docs warn about exhaustively matching on it, so adding a new variant per se should not be a breaking change.
The variant `Unsupported` itself could be marked as `#[unstable]`, however, because this PR also immediately uses this new variant and changes the errors returned by functions I'm inclined to agree with the others in this thread that the variant should be insta-stabilized.
Deprecate the core::raw / std::raw module
It only contains the `TraitObject` struct which exposes components of wide pointer. Pointer metadata APIs are designed to replace this: https://github.com/rust-lang/rust/issues/81513
This commit adds a variant of the `thread_local!` macro as a new
`thread_local_const_init!` macro which requires that the initialization
expression is constant (e.g. could be stuck into a `const` if so
desired). This form of thread local allows for a more efficient
implementation of `LocalKey::with` both if the value has a destructor
and if it doesn't. If the value doesn't have a destructor then `with`
should desugar to exactly as-if you use `#[thread_local]` given
sufficient inlining.
The purpose of this new form of thread locals is to precisely be
equivalent to `#[thread_local]` on platforms where possible for values
which fit the bill (those without destructors). This should help close
the gap in performance between `thread_local!`, which is safe, relative
to `#[thread_local]`, which is not easy to use in a portable fashion.
Fix join_paths error display.
On unix, the error from `join_paths` looked like this:
```
path segment contains separator `58`
```
This PR changes it to look like this:
```
path segment contains separator `:`
```
Move `std::sys_common::alloc` to new module `std::sys::common`
6b56603e35/library/std/src/sys_common/mod.rs (L7-L13)
It was my impression that the goal for `std::sys` has changed from extracting it into a separate crate to making std work with features. However the fact remains that there is a lot of interdependence between `sys` and `sys_common`, this is because `sys_common` contains two types of code:
- abstractions over the different platform implementations in `std::sys` (for example [`std::sys_common::mutex`](https://github.com/rust-lang/rust/blob/master/library/std/src/sys_common/mutex.rs))
- code shared between platforms (for example [`std::sys_common::alloc`](https://github.com/rust-lang/rust/blob/master/library/std/src/sys_common/alloc.rs))
This PR attempts to address this by adding a new module `common` to `std::sys` which will contain code shared between platforms, `alloc.rs` in this case but more can be moved over in the future.
Stabilize `bufreader_seek_relative`
This PR marks `BufReader::seek_relative` as stable - the associated issue, #31100, has passed the final comment period without any issues, and from what I understand, the only thing left to stabilize this is to submit a PR marking the method as stable.
Closes#31100.