Validate CopyForDeref and DerefTemps better and remove them from runtime MIR
(split from my WIP rust-lang/rust#145344)
This PR:
- Removes `Rvalue::CopyForDeref` and `LocalInfo::DerefTemp` from runtime MIR
- Using a new mir pass `EraseDerefTemps`
- `CopyForDeref(x)` is turned into `Use(Copy(x))`
- `DerefTemp` is turned into `Boring`
- Not sure if this part is actually necessary, it made more sense in rust-lang/rust#145344 with `DerefTemp` storing actual data that I wanted to keep from having to be kept in sync with the rest of the body in runtime MIR
- Checks in validation that `CopyForDeref` and `DerefTemp` are only used together
- Removes special handling for `CopyForDeref` from many places
- Removes `CopyForDeref` from `custom_mir` reverting rust-lang/rust#111587
- In runtime MIR simple copies can be used instead
- In post cleanup analysis MIR it was already wrong to use due to the lack of support for creating `DerefTemp` locals
- Possibly this should be its own PR?
- Adds an argument to `deref_finder` to avoid creating new `DerefTemp`s and `CopyForDeref` in runtime MIR.
- Ideally we would just avoid making intermediate derefs instead of fixing it at the end of a pass / during shim building
- Removes some usages of `deref_finder` that I found out don't actually do anything
r? oli-obk
In the future this should make it easier to use weak symbols for the
allocator shim on platforms that properly support weak symbols. And it
would allow reusing the allocator shim code for handling default
implementations of the upcoming externally implementable items feature
on platforms that don't properly support weak symbols.
Currently it is possible to avoid linking the allocator shim when
__rust_no_alloc_shim_is_unstable_v2 is defined when linking rlibs
directly as some build systems need. However this requires liballoc to
be compiled with --cfg no_global_oom_handling, which places huge
restrictions on what functions you can call and makes it impossible to
use libstd. Or alternatively you have to define
__rust_alloc_error_handler and (when using libstd)
__rust_alloc_error_handler_should_panic
using #[rustc_std_internal_symbol]. With this commit you can either use
libstd and define __rust_alloc_error_handler_should_panic or not use
libstd and use #[alloc_error_handler] instead. Both options are still
unstable though.
Eventually the alloc_error_handler may either be removed entirely
(though the PR for that has been stale for years now) or we may start
using weak symbols for it instead. For the latter case this commit is a
prerequisite anyway.
interpret `#[used]` as `#[used(compiler)]` on illumos
helps rust-lang/rust#146169 not be as painful: fixes the illumos regression in rust-lang/rust#140872, but `#[used(linker)]` is still erroneous on illumos generally.
illumos' `ld` does not support a flag like either SHF_GNU_RETAIN or SHF_SUNW_NODISCARD, so there is no way to communicate `#[used(linker)]` for that target. Setting `USED_LINKER` to try results in LLVM setting SHF_SUNW_NODISCARD for Solaris-like targets, which is an unknown section header flag for illumos `ld` and prevents sections from being merged that otherwise would.
As a motivating example, the `inventory` crate produces `#[used]` items to merge into `.init_array`. Because those items have an unknown section header flag they are not merged with the default `.init_array` with `frame_dummy`, and end up never executed.
Downgrading `#[used]` to `#[used(compiler)]` on illumos keeps so-attributed items as preserved as they had been before https://github.com/rust-lang/rust/pull/140872. As was the case before that change, because rustc passes `-z ignore` to illumos `ld`, it's possible that `used` sections are GC'd at link time. https://github.com/rust-lang/rust/issues/146169 describes this unfortunate circumstance.
----
as it turns out, `tests/ui/attributes/used_with_archive.rs` had broken on `x86_64-unknown-illumos`, and this patch fixes it. the trials and tribulations of tier 2 :(
r? ````@Noratrieb```` probably?
illumos' `ld` does not support a flag like either SHF_GNU_RETAIN or
SHF_SUNW_NODISCARD, so there is no way to communicate `#[used(linker)]`
for that target. Setting `USED_LINKER` to try results in LLVM setting
SHF_SUNW_NODISCARD for Solaris-like targets, which is an unknown section
header flag for illumos `ld` and prevents sections from being merged
that otherwise would.
As a motivating example, the `inventory` crate produces
`#[used]` items to merge into `.init_array`. Because those items have an
unknown section header flag they are not merged with the default
`.init_array` with `frame_dummy`, and end up never executed.
Downgrading `#[used]` to `#[used(compiler)]` on illumos keeps
so-attributed items as preserved as they had been before
https://github.com/rust-lang/rust/pull/140872. As was the case before
that change, because rustc passes `-z ignore` to illumos `ld`, it's
possible that `used` sections are GC'd at link time.
https://github.com/rust-lang/rust/issues/146169 describes this
unfortunate circumstance.
Introduce debuginfo to statements in MIR
The PR introduces support for debug information within dead statements. Currently, only the reference statement is supported, which is sufficient to fix rust-lang/rust#128081.
I don't modify Stable MIR, as I don't think we need debug information when using it.
This PR represents the debug information for the dead reference statement via `#dbg_value`. For example, `let _foo_b = &foo.b` becomes `#dbg_value(ptr %foo, !22, !DIExpression(DW_OP_plus_uconst, 4, DW_OP_stack_value), !26)`. You can see this here: https://rust.godbolt.org/z/d43js6adv.
The general principle for handling debug information is to never provide less debug information than the optimized LLVM IR.
The current rules for dropping debug information in this PR are:
- If the LLVM IR cannot represent a reference address, it's replaced with poison or simply dropped. For example, see: https://rust.godbolt.org/z/shGqPec8W. I'm using poison in all such cases now.
- All debuginfos is dropped when merging multiple successor BBs. An example is available here: https://rust.godbolt.org/z/TE1q3Wq6M.
I doesn't drop debuginfos in `MatchBranchSimplification`, because LLVM also pick one branch for it.
If the `LocalRef` is `LocalRef::Place`, we can refer to it directly,
because the local of place is an indirect pointer.
Such a statement is `_1 = &(_2.1)`.
If the `LocalRef` is `LocalRef::Operand`,
the `OperandRef` should provide the pointer of the reference.
Such a statement is `_1 = &((*_2).1)`.
But there is a special case that hasn't been handled, scalar pairs like `(&[i32; 16], i32)`.
Don't enable shared memory by default with Wasm atomics
This prepares us for a future where LLVM eventually stabilizes the atomics target feature, in which case we don't want to inflate atomics with threads. Otherwise users would be stuck with shared memory even when they don't want it/need it.
### Context
Currently the atomics target features is unstable and can't be used without re-building Std with it (`-Zbuild-std`).
Enabling the atomics target feature automatically enables shared memory.
Shared memory is required to actually allow multi-threading.
However, shared memory comes with a performance overhead when atomic instructions aren't able to be lowered to regular memory access instructions or when interacting with certain Web APIs.
So it is very undesirable to enable shared memory by default for the majority of users.
While it is possible to use atomics without shared memory, the question remains what use-case this scenario has.
The only one I can think of would involve multiple memories, where the main memory remains un-shared but a second shared memory exists. While Rust doesn't support multiple memories, it might be possible with inline assembly (rust-lang/rust#136382).
So alternatively, we might consider *not* enabling atomics by default even when LLVM does. In which case everything would remain the same.
---
This will break current Web multi-threading users. To address this they can add the following `RUSTFLAGS`:
```
-Clink-args=--shared-memory,--max-memory=1073741824,--import-memory,--export=__wasm_init_tls,--export=__tls_size,--export=__tls_align,--export=__tls_base
```
We could add a new experimental flag that enables the right linker arguments for users, but I feel that's not in Rusts scope. Or like suggested before: a Rust-only `threads` target feature.
Addresses rust-lang/rust#77839.
r? ``@alexcrichton``
Turn ProjectionElem::Subtype into CastKind::Subtype
I noticed that drop elaboration can't, in general, handle `ProjectionElem::SubType`. It creates a disjoint move path that overlaps with other move paths. (`Subslice` does too, and I'm working on a different PR to make that special case less fragile.) If its skipped and treated as the same move path as its parent then `MovePath.place` has multiple possible projections. (It would probably make sense to remove all `Subtype` projections for the canonical place but it doesn't make sense to have this special case for a problem that doesn't actually occur in real MIR.)
The only reason this doesn't break is that `Subtype` is always the sole projection of the local its applied to. For the same reason, it works fine as a `CastKind` so I figured that makes more sense than documenting and validating this hidden invariant.
cc rust-lang/rust#112651, rust-lang/rust#133258
r? Icnr (bc you've been the main person dealing with `Subtype` it looks like)
Much of the compiler calls functions on Align projected from AbiAlign.
AbiAlign impls Deref to its inner Align, so we can simplify these away.
Also, it will minimize disruption when AbiAlign is removed.
For now, preserve usages that might resolve to PartialOrd or PartialEq,
as those have odd inference.
[win] Use find-msvc-tools instead of cc to find the linker and rc on Windows
`find-msvc-tools` was factored out from `cc` to allow updating the use in `rustc_codegen_ssa` (finding the linker when running the Rust compiler) and `rustc_windows_rc` (finding the Windows Resource Compiler when running the Rust compiler) to be separate from the use in `rustc_llvm` (building LLVM as part of building the Rust compiler).
Add panic=immediate-abort
MCP: https://github.com/rust-lang/compiler-team/issues/909
This adds a new panic strategy, `-Cpanic=immediate-abort`. This panic strategy essentially just codifies use of `-Zbuild-std-features=panic_immediate_abort`. This PR is intended to just set up infrastructure, and while it will change how the compiler is invoked for users of the feature, there should be no other impacts.
In many parts of the compiler, `PanicStrategy::ImmediateAbort` behaves just like `PanicStrategy::Abort`, because actually most parts of the compiler just mean to ask "can this unwind?" so I've added a helper function so we can say `sess.panic_strategy().unwinds()`.
The panic and unwind strategies have some level of compatibility, which mostly means that we can pre-compile the sysroot with unwinding panics then the sysroot can be linked with aborting panics later. The immediate-abort strategy is all-or-nothing, enforced by `compiler/rustc_metadata/src/dependency_format.rs` and this is tested for in `tests/ui/panic-runtime/`. We could _technically_ be more compatible with the other panic strategies, but immediately-aborting panics primarily exist for users who want to eliminate all the code size responsible for the panic runtime. I'm open to other use cases if people want to present them, but not right now. This PR is already large.
`-Cpanic=immediate-abort` sets both `cfg(panic = "immediate-abort")` _and_ `cfg(panic = "abort")`. bjorn3 pointed out that people may be checking for the abort cfg to ask if panics will unwind, and also the sysroot feature this is replacing used to require `-Cpanic=abort` so this seems like a good back-compat step. At least for the moment. Unclear if this is a good idea indefinitely. I can imagine this being confusing.
The changes to the standard library attributes are purely mechanical. Apart from that, I removed an `unsafe` we haven't needed for a while since the `abort` intrinsic became safe, and I've added a helpful diagnostic for people trying to use the old feature.
To test that `-Cpanic=immediate-abort` conflicts with other panic strategies, I've beefed up the core-stubs infrastructure a bit. There is now a separate attribute to set flags on it.
I've added a test that this produces the desired codegen, called `tests/run-make-cargo/panic-immediate-abort-codegen/` and also a separate run-make-cargo test that checks that we can build a binary.
Enable `limit_rdylib_exports` on wasm targets
This commit updates the target specification of wasm targets to set the `limit_rdylib_exports` value to `true` like it is on other native platforms. This was originally not implemented long ago as `wasm-ld` didn't have options for symbol exports, but since then it's grown a `--export` flag and such to control this. A custom case is needed in the linker implementation to handle wasm targets as `wasm-ld` doesn't support linker scripts used on other targets, but other than that the implementation is straightforward.
The goal of this commit is enable building dynamic libraries on `wasm32-wasip2` which don't export every single symbol in the Rust standard library. Currently, without otherwise control over symbol visibility, all symbols end up being exported which generates excessively large binaries because `--gc-sections` ends up doing nothing as it's all exported anyway.
naked_asm: emit a label starting with `func_end`
The `cargo asm` tool (`cargo install cargo-show-asm`) pattern matches on such labels to figure out where functions end: normal functions generated by LLVM always do have such a label. We don't guarantee that naked functions emit such a label, but having `cargo asm` work is convenient.
be45f67454/src/asm/statements.rs (L897-L901)
To make the label name unique it's suffixed with the name of the current symbol.
r? ```@Amanieu```
This commit updates the target specification of wasm targets to set the
`limit_rdylib_exports` value to `true` like it is on other native
platforms. This was originally not implemented long ago as `wasm-ld`
didn't have options for symbol exports, but since then it's grown a
`--export` flag and such to control this. A custom case is needed in the
linker implementation to handle wasm targets as `wasm-ld` doesn't
support linker scripts used on other targets, but other than that the
implementation is straightforward.
The goal of this commit is enable building dynamic libraries on
`wasm32-wasip2` which don't export every single symbol in the Rust
standard library. Currently, without otherwise control over symbol
visibility, all symbols end up being exported which generates
excessively large binaries because `--gc-sections` ends up doing nothing
as it's all exported anyway.
The `cargo asm` tool pattern matches on such labels to figure out where functions end: normal functions generated by LLVM always do have such a label. We don't guarantee that naked functions emit such a label, but having `cargo asm` work is convenient
Clean up `ty::Dynamic`
1. As a follow-up to PR rust-lang/rust#143036, remove `DynKind` entirely.
2. Inside HIR ty lowering, consolidate modules `dyn_compatibility` and `lint` into `dyn_trait`
* `dyn_compatibility` wasn't about dyn compatibility itself, it's about lowering trait object types
* `lint` contained dyn-Trait-specific diagnostics+lints only
Remove Rvalue::Len again.
Now that we have `RawPtrKind::FakeForPtrMetadata`, we can reimplement `Rvalue::Len` using `PtrMetadata(&raw const (fake) place)`.
r? ``@scottmcm``
initial implementation of the darwin_objc unstable feature
Tracking issue: https://github.com/rust-lang/rust/issues/145496
This feature makes it possible to reference Objective-C classes and selectors using the same ABI used by native Objective-C on Apple/Darwin platforms. Without it, Rust code interacting with Objective-C must resort to loading classes and selectors using costly string-based lookups at runtime. With it, these references can be loaded efficiently at dynamic load time.
r? ```@tmandry```
try-job: `*apple*`
try-job: `x86_64-gnu-nopt`