Implement a global value numbering MIR optimization
The aim of this pass is to avoid repeated computations by reusing past assignments. It is based on an analysis of SSA locals, in order to perform a restricted form of common subexpression elimination.
By opportunity, this pass allows for some simplifications by combining assignments. For instance, this pass could be able to see through projections of aggregates to directly reuse the aggregate field (not in this PR).
We handle references by assigning a different "provenance" index to each `Ref`/`AddressOf` rvalue. This ensure that we do not spuriously merge borrows that should not be merged. Meanwhile, we consider all the derefs of an immutable reference to a freeze type to give the same value:
```rust
_a = *_b // _b is &Freeze
_c = *_b // replaced by _c = _a
```
Amend style guide section for formatting where clauses in type aliases
This PR has two parts:
1. Amend wording about breaking before or after the `=`, which is a style guide bugfix to align it with current rustfmt behavior.
2. Explain how to format trailing (#89122) where clauses, which are preferred in both GATs (#90076) and type aliases (#114662).
r? `@joshtriplett`
make link_llvm_intrinsics and platform_intrinsics features internal
These are both a lot like `feature(intrinsics)`, just slightly different syntax, so IMO it should be treated the same (also in terms of: if you get ICEs with this feature, that's on you -- we are not doing "nice" type-checking for intrinsics).
Rollup of 4 pull requests
Successful merges:
- #115934 (Split out the stable part of smir into its own crate to prevent accidental usage of forever unstable things)
- #116149 (Anonymize binders for `refining_impl_trait` check)
- #116178 (Add test for `const async fn`)
- #116187 (Add context to `let: Ty = loop { break };`)
r? `@ghost`
`@rustbot` modify labels: rollup
Anonymize binders for `refining_impl_trait` check
We're naively using the equality impl for `ty::Clause` in the refinement check, which is okay *except* for binders, which carry some information about where they come from in the AST. Those locations are not gonna be equal between traits and impls, so anonymize those clauses so that this doesn't matter.
Fixes#116135
Split out the stable part of smir into its own crate to prevent accidental usage of forever unstable things
Some groundwork for being able to work on https://github.com/rust-lang/project-stable-mir/issues/27 at all
r? `@spastorino`
Skip MIR pass `UnreachablePropagation` when coverage is enabled
When coverage instrumentation and MIR opts are both enabled, coverage relies on two assumptions:
- MIR opts that would delete `StatementKind::Coverage` statements instead move them into bb0 and change them to `CoverageKind::Unreachable`.
- MIR opts won't delete all `CoverageKind::Counter` statements from an instrumented function.
Most MIR opts naturally satisfy the second assumption, because they won't remove coverage statements from bb0, but `UnreachablePropagation` can do so if it finds that bb0 is unreachable. If this happens, LLVM thinks the function isn't instrumented, and it vanishes from coverage reports.
A proper solution won't be possible until after per-function coverage info lands in #116046, but for now we can avoid the problem by turning off this particular pass when coverage instrumentation is enabled.
---
cc `@cjgillot` since I found this while investigating coverage problems encountered by #113970
`@rustbot` label +A-code-coverage +A-mir-opt
Don't store lazyness in `DefKind::TyAlias`
1. Don't store lazyness of a type alias in its `DefKind`, but instead via a query.
2. This allows us to treat type aliases as lazy if `#[feature(lazy_type_alias)]` *OR* if the alias contains a TAIT, rather than having checks for both in separate parts of the codebase.
r? `@oli-obk` cc `@fmease`
Only prevent field projections into opaque types, not types containing opaque types
fixes https://github.com/rust-lang/rust/issues/115778
I did not think that original condition through properly... I'll also need to check the similar check around the other `ProjectionKind::OpaqueCast` creation site (this one is in hir, the other one is in mir), but I'll do that change in another PR that doesn't go into a beta backport.
subst -> instantiate
continues #110793, there are still quite a few uses of `subst` and `substitute`, but changing them all in the same PR was a bit too much, so I've stopped here for now.
Correct codegen of `ConstValue::Indirect` scalar and scalar pair
This concerns 3 tricky cases with `ConstValue::Indirect`:
- if we want a non-pointer scalar;
- if we have non-zero offset;
- if offset points to uninit memory => generate `poison` instead of an ICE. This case could happen in unreachable code, trying to extract a field from the wrong variant.
Those cases are not currently emitted by the compiler, but are exercised by https://github.com/rust-lang/rust/pull/116012.
Gate and validate `#[rustc_safe_intrinsic]`
Copied over from #116159:
> This was added as ungated in https://github.com/rust-lang/rust/pull/100719/files#diff-09c366d3ad3ec9a42125253b610ca83cad6b156aa2a723f6c7e83eddef7b1e8fR502, probably because the author looked at the surrounding attributes, which are ungated because they are gated specially behind the staged_api feature.
>
> I don't think we need to crater this, the attribute is entirely useless without the intrinsics feature, which is already unstable..
r? ``@Nilstrieb``