A couple of fixes for dataflow graphviz dumps
A couple of trivial drive-by fixes to issues I noticed while debugging my buggy borrowck code:
One is a fix of the `-Zdump-mir-dataflow` file extensions, the dataflow graphviz files are currently dumped as `..dot`.
<details>
```console
-rw-rw-r-- 1 lqd lqd 13051 Oct 1 23:21 mir_dump/issue_47680.main.-------.borrows.borrowck..dot
-rw-rw-r-- 1 lqd lqd 13383 Oct 1 23:21 mir_dump/issue_47680.main.-------.ever_init.borrowck..dot
-rw-rw-r-- 1 lqd lqd 13591 Oct 1 23:21 mir_dump/issue_47680.main.-------.maybe_init.borrowck..dot
-rw-rw-r-- 1 lqd lqd 9257 Oct 1 23:21 mir_dump/issue_47680.main.-------.maybe_init.elaborate_drops..dot
-rw-rw-r-- 1 lqd lqd 14086 Oct 1 23:21 mir_dump/issue_47680.main.-------.maybe_uninit.borrowck..dot
-rw-rw-r-- 1 lqd lqd 9257 Oct 1 23:21 mir_dump/issue_47680.main.-------.maybe_uninit.elaborate_drops..dot
```
<summary>Some examples on nightly</summary>
</details>
And the other is for the specific `Borrows` dataflow analysis, whose domain is loans but shows locations when dumped (the location where the loan is introduced). It's not a huge deal but we didn't even print these locations in MIR dumps, and in general cross-referencing loan data (like loan liveness) is more annoying without this change.
<details>
![Untitled](https://github.com/user-attachments/assets/b325a6e9-1aee-4655-8441-d3b1b55ded3c)
<summary>Here's how it'll look in case inquisitive minds want to know</summary>
</details>
The visualization state diff display is still suboptimal in loops for some of the effects escaping a block, e.g. a gen that's not dominated/postdominated by a kill will not show up in statement diffs. (This happens in the previous screenshot, there's no `+bw1` anywhere). We can fix that in the future.
Revert #131060 "Drop conditionally applied cargo `-Zon-broken-pipe=kill` flags"
In [#131059] we found out that `-Zon-broken-pipe=kill` is actually **load-bearing**[^1] for
(at least) `rustc` and `rustdoc` to have the kill-process-on-broken-pipe behavior, e.g. `rustc
--print=sysroot | false` will ICE and `rustdoc --print=sysroot | false` will panic on a broken pipe.
This PR reverts 5a7058c5a5 (reverts PR #131060) in favor of a future
fix to *unconditionally* apply `-Zon-broken-pipe=kill` to tool builds and also not drop the
`-Zon-broken-pipe=kill` flag for rustc binary builds.
I could not figure out how to write a regression test for the `rustc --print=sysroot | false`
behavior on Unix, so this is a plain revert for now.
This revert will unfortunately reintroduce #130980 until we fix it again with the different approach.
See more details at <https://github.com/rust-lang/rust/issues/131059#issuecomment-2385822033> and in the timeline below.
### Timeline of kill-process-on-broken-pipe behavior changes
See [`unix_sigpipe` tracking issue #97889][#97889] for more context around unix sigpipe handling.
- From the very beginning since 2014, Rust binaries by default use `sig_ign`. This meant that if
output pipe is broken yet the program tries to use `println!` and such, there will be a broken
pipe panic from std. This lead to ICEs from e.g. `rustc --help | false` [#34376].
- [#49606] mitigated [#34376] by adding an explicit signal handler to `rustc_driver` register a
sigpipe handler with `SIG_DFL` which will cause the binary using `rustc_driver` to terminate if
`rustc_driver::set_sigpipe_handler()` is called. `rustc`'s main binary wrapper uses
`rustc_driver::set_sigpipe_handler()`, and so does `rustdoc`.
- A more universal way to set sigpipe behavior for Unix was introduced as part of [#97889], i.e. `#
[unix_sigpipe = "sig_dfl"]` attribute.
- [#102587] migrated `rustc` to use `#[unix_sigpipe = "sig_dfl"]` instead of
`rustc_driver::set_sigpipe_handler`.
- [#103495] migrated `rustdoc` to use `#[unix_sigpipe = "sig_dfl"]` instead of
`rustc_driver::set_sigpipe_handler`. `rustc_driver::set_sigpipe_handler` was removed.
- Following concerns about sigpipe setting UI in [#97889], the UI for specifying sigpipe behavior
was changed in [#124480] from `#[unix_sigpipe = "sig_dfl"]` attribute to the commmand line flag
`-Zon-broken-pipe=kill`.
- In the same PR, `#[unix_sigpipe = "sig_dfl"]` were removed from `rustc` and `rustdoc` main
binary crate entry points in favor of the command line flag. Kill-process-on-broken-pipe
behavior was preserved by adding `-Zon-broken-pipe=kill` for `rustdoc` tool build step and
`rustc` during compile steps.
- [#126934] added `-Zon-broken-pipe=kill` for tool builds *except* for cargo to help with some miri
tests because at the time the PR was written, this would lead to a couple of cargo test failures.
Conditionally setting `RUSTFLAGS` can lead to tool build invalidation, e.g. building `cargo`
without `-Zon-broken-pipe=kill` but `clippy` with the flag can lead to invalidation of the tool
build cache. This is not a problem at the time, because nothing (not even miri) tests built stage
1 cargo (all used initial cargo).
- In [#130634] we found out that `run-make` tests like `compiler-builtins` needed stage 1 cargo, not
just beta bootstrap cargo, because there can be changes that are present in stage 1 cargo but
absent in beta cargo, which was blocking a beta backport.
- [#130642] and later [#130739] now build stage 1 cargo. And as previously mentioned, since
`-Zon-broken-pipe=kill` was specifically *not* set for cargo, this caused tool build cache
invalidation meaning rebuilds of stage 1 even if nothing in source was changed due to differing
`RUSTFLAGS` since `run-make` also builds `rustdoc` and such [#130980].
[#34376]: https://github.com/rust-lang/rust/issues/34376
[#49606]: https://github.com/rust-lang/rust/pull/49606
[#97889]: https://github.com/rust-lang/rust/issues/97889
[#102587]: https://github.com/rust-lang/rust/pull/102587
[#103495]: https://github.com/rust-lang/rust/pull/103495
[#124480]: https://github.com/rust-lang/rust/pull/124480
[#130634]: https://github.com/rust-lang/rust/issues/130634
[#130642]: https://github.com/rust-lang/rust/pull/130642
[#130739]: https://github.com/rust-lang/rust/pull/130739
[#130980]: https://github.com/rust-lang/rust/issues/130980
[#131059]: https://github.com/rust-lang/rust/issues/131059
[^1]: https://github.com/rust-lang/rust/issues/131059#issuecomment-2385822033
r? ``@onur-ozkan`` (or bootstrap)
panic when an interpreter error gets unintentionally discarded
One important invariant of Miri is that when an interpreter error is raised (*in particular* a UB error), those must not be discarded: it's not okay to just check `foo().is_err()` and then continue executing.
This seems to catch new contributors by surprise fairly regularly, so this PR tries to make it so that *if* this ever happens, we get a panic rather than a silent missed UB bug. The interpreter error type now contains a "guard" that panics on drop, and that is explicitly passed to `mem::forget` when an error is deliberately discarded.
Fixes https://github.com/rust-lang/miri/issues/3855
Add `[Option<T>; N]::transpose`
This PR as a new unstable libs API, `[Option<T>; N]::transpose`, which permits going from `[Option<T>; N]` to `Option<[T; N]>`.
This new API doesn't have an ACP as it was directly asked by T-libs-api in https://github.com/rust-lang/rust/issues/97601#issuecomment-2372109119:
> [..] but it'd be trivial to provide a helper method `.transpose()` that turns array-of-Option into Option-of-array (**and we think that method should exist**; it already does for array-of-MaybeUninit).
r? libs
Fix `mut_mutex_lock` when reference not ultimately mutable
When there is are multiple references where one of the references isn't mutable then this results in a false-positive for `mut_mutex_lock` as it only checks the mutability of the first reference level.
Fix this by using `peel_mid_ty_refs_is_mutable` which correctly determines whether the reference is ultimately mutable and thus whether `Mutex::get_lock()` can actually be used.
Fixes#9854
changelog: [`mut_mutex_lock`]: No longer lints if the mutex is behind multiple references and one of those references isn't mutable
When there is are multiple references where one of the references
isn't mutable then this results in a false-positive for
`mut_mutex_lock` as it only checks the mutability of the first
reference level.
Fix this by using `peel_mid_ty_refs_is_mutable` which correctly
determines whether the reference is ultimately mutable and thus
whether `Mutex::get_lock()` can actually be used.
Fixes#9854
This PR replaces the `LazyBox` wrapper used to allocate the pthread primitives with `OnceBox`, which has a more familiar API mirroring that of `OnceLock`. This cleans up the code in preparation for larger changes like #128184 (from which this PR was split) and allows some neat optimizations, like avoid an acquire-load of the allocation pointer in `Mutex::unlock`, where the initialization of the allocation must have already been observed.
Additionally, I've gotten rid of the TEEOS `Condvar` code, it's just a duplicate of the pthread one anyway and I didn't want to repeat myself.
Update Unicode escapes in `/library/core/src/char/methods.rs`
`char::MAX` is inconsistent on how Unicode escapes should be formatted. This PR resolves that.
ptr::add/sub: do not claim equivalence with `offset(c as isize)`
In https://github.com/rust-lang/rust/pull/110837, the `offset` intrinsic got changed to also allow a `usize` offset parameter. The intention is that this will do an unsigned multiplication with the size, and we have UB if that overflows -- and we also have UB if the result is larger than `usize::MAX`, i.e., if a subsequent cast to `isize` would wrap. ~~The LLVM backend sets some attributes accordingly.~~
This updates the docs for `add`/`sub` to match that intent, in preparation for adjusting codegen to exploit this UB. We use this opportunity to clarify what the exact requirements are: we compute the offset using mathematical multiplication (so it's no problem to have an `isize * usize` multiplication, we just multiply integers), and the result must fit in an `isize`.
Cc `@rust-lang/opsem` `@nikic`
https://github.com/rust-lang/rust/pull/130239 updates Miri to detect this UB.
`sub` still has some cases of UB not reflected in the underlying intrinsic semantics (and Miri does not catch): when we subtract `usize::MAX`, then after casting to `isize` that's just `-1` so we end up adding one unit without noticing any UB, but actually the offset we gave does not fit in an `isize`. Miri will currently still not complain for such cases:
```rust
fn main() {
let x = &[0i32; 2];
let x = x.as_ptr();
// This should be UB, we are subtracting way too much.
unsafe { x.sub(usize::MAX).read() };
}
```
However, the LLVM IR we generate here also is UB-free. This is "just" library UB but not language UB.
Cc `@saethlin;` might be worth adding precondition checks against overflow on `offset`/`add`/`sub`?
Fixes https://github.com/rust-lang/rust/issues/130211
`zombie_processes`: consider `wait()` calls in nested bodies
Fixes#13459
Small oversight. We weren't considering uses of the local in closures.
changelog: none
Rollup of 5 pull requests
Successful merges:
- #130630 (Support clobber_abi and vector/access registers (clobber-only) in s390x inline assembly)
- #131042 (Instantiate binders in `supertrait_vtable_slot`)
- #131079 (Update wasm-component-ld to 0.5.9)
- #131085 (make test_lots_of_insertions test take less long in Miri)
- #131088 (add fixme to remove LLVM_ENABLE_TERMINFO when minimal llvm version is 19)
r? `@ghost`
`@rustbot` modify labels: rollup
make test_lots_of_insertions test take less long in Miri
This is by far the slowest `std` test in Miri, taking >2min in https://github.com/rust-lang/miri-test-libstd CI. So let's make this `count` smaller. The runtime should be quadratic in `count` so reducing it to around 2/3 of it's previous value should cut the total time down to less than half -- making it still the slowest test, but by less of a margin. (And this way we still insert >64 elements into the HashMap, in case that power of 2 matters.)
Update wasm-component-ld to 0.5.9
This updates the `wasm-component-ld` linker binary for the `wasm32-wasip2` target to 0.5.9, pulling in a few bug fixes and recent updates.
Instantiate binders in `supertrait_vtable_slot`
`supertrait_vtable_slot` was previously using structural equality when probing for the vtable slot, which led to an ICE since we need a *subtype* match, not an exact match.
Fixes#131027
r? lcnr