Assorted improvements for `rustc_middle::mir::traversal`
r? `@cjgillot`
I'm not _entirely_ sure about all changes, although I do like all of them. If you'd like I can drop some commits. Best reviewed on a commit-by-commit basis, I think, since they are fairly isolated.
Prototype using const generic for simd_shuffle IDX array
cc https://github.com/rust-lang/rust/issues/85229
r? `@workingjubilee` on the design
TLDR: there is now a `fn simd_shuffle_generic<T, U, const IDX: &'static [u32]>(x: T, y: T) -> U;` intrinsic that allows replacing
```rust
simd_shuffle(a, b, const { stuff })
```
with
```rust
simd_shuffle_generic::<_, _, {&stuff}>(a, b)
```
which makes the compiler implementations much simpler, if we manage to at some point eliminate `simd_shuffle`.
There are some issues with this today though (can't do math without bubbling it up in the generic arguments). With this change, we can start porting the simple cases and get better data on the others.
fix(suggestion): insert projection to associated types
Fixes#98562
This PR has fixed some help suggestions for unsupported syntax, such as `fn f<T>(_:T) where T: IntoIterator, std::iter::IntoIterator::Item = () {}` to `fn f<T: IntoIterator<Item = ()>>(_T) {}`.
stabilize combining +bundle and +whole-archive link modifiers
Per discussion on https://github.com/rust-lang/rust/issues/108081 combining +bundle and +whole-archive already works and can be stabilized independently of other aspects of the packed_bundled_libs feature. There is no risk of regression because this was not previously allowed.
r? `@petrochenkov`
Reveal opaque types before drop elaboration
fixes https://github.com/rust-lang/rust/issues/113594
r? `@cjgillot`
cc `@JakobDegen`
This pass was introduced in https://github.com/rust-lang/rust/pull/110714
I moved it before drop elaboration (which only cares about the hidden types of things, not the opaque TAIT or RPIT type) and set it to run unconditionally (instead of depending on the optimization level and whether the inliner is active)
Make `adt_const_params` feature suggestion consistent with other features and improve when it is emitted
Makes the suggestion to add `adt_const_params` formatted like every other feature gate (notably this makes it such that the playground recognizes it). Additionally improves the situations in which that help is emitted so that it's only emitted when the type would be valid or the type *could* be valid (using a slightly incorrect heuristic that favors suggesting the feature over not) instead of, for example, implying that adding the feature would allow the use of `String`.
Also adds the "the only supported types are integers, `bool` and `char`" note to the errors on fn and raw pointers.
r? `@compiler-errors`
Fix `noop_method_call` detection
This needs to be merged before #116198 can compile. The error occurs before the compiler is built so this needs to be a separate PR.
new solver: remove provisional cache
The provisional cache is a performance optimization if there are large, interleaving cycles. Such cycles generally do not exist. It is incredibly complex and unsound in all trait solvers which have one: the old solver, chalk, and the new solver ([link](https://github.com/rust-lang/rust/blob/master/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs)).
Given the assumption that it is not perf-critical and also incredibly complex, remove it from the new solver, only checking whether a goal is on the stack. While writing this, I uncovered two additional soundness bugs, see the inline comments for them.
r? `@compiler-errors`
Stabilize `impl_trait_projections`
Closes#115659
## TL;DR:
This allows us to mention `Self` and `T::Assoc` in async fn and return-position `impl Trait`, as you would expect you'd be able to.
Some examples:
```rust
#![feature(return_position_impl_trait_in_trait, async_fn_in_trait)]
// (just needed for final tests below)
// ---------------------------------------- //
struct Wrapper<'a, T>(&'a T);
impl Wrapper<'_, ()> {
async fn async_fn() -> Self {
//^ Previously rejected because it returns `-> Self`, not `-> Wrapper<'_, ()>`.
Wrapper(&())
}
fn impl_trait() -> impl Iterator<Item = Self> {
//^ Previously rejected because it mentions `Self`, not `Wrapper<'_, ()>`.
std::iter::once(Wrapper(&()))
}
}
// ---------------------------------------- //
trait Trait<'a> {
type Assoc;
fn new() -> Self::Assoc;
}
impl Trait<'_> for () {
type Assoc = ();
fn new() {}
}
impl<'a, T: Trait<'a>> Wrapper<'a, T> {
async fn mk_assoc() -> T::Assoc {
//^ Previously rejected because `T::Assoc` doesn't mention `'a` in the HIR,
// but ends up resolving to `<T as Trait<'a>>::Assoc`, which does rely on `'a`.
// That's the important part -- the elided trait.
T::new()
}
fn a_few_assocs() -> impl Iterator<Item = T::Assoc> {
//^ Previously rejected for the same reason
[T::new(), T::new(), T::new()].into_iter()
}
}
// ---------------------------------------- //
trait InTrait {
async fn async_fn() -> Self;
fn impl_trait() -> impl Iterator<Item = Self>;
}
impl InTrait for &() {
async fn async_fn() -> Self { &() }
//^ Previously rejected just like inherent impls
fn impl_trait() -> impl Iterator<Item = Self> {
//^ Previously rejected just like inherent impls
[&()].into_iter()
}
}
```
## Technical:
Lifetimes in return-position `impl Trait` (and `async fn`) are duplicated as early-bound generics local to the opaque in order to make sure we are able to substitute any late-bound lifetimes from the function in the opaque's hidden type. (The [dev guide](https://rustc-dev-guide.rust-lang.org/return-position-impl-trait-in-trait.html#aside-opaque-lifetime-duplication) has a small section about why this is necessary -- this was written for RPITITs, but it applies to all RPITs)
Prior to #103491, all of the early-bound lifetimes not local to the opaque were replaced with `'static` to avoid issues where relating opaques caused their *non-captured* lifetimes to be related. This `'static` replacement led to strange and possibly unsound behaviors (https://github.com/rust-lang/rust/issues/61949#issuecomment-508836314) (https://github.com/rust-lang/rust/issues/53613) when referencing the `Self` type alias in an impl or indirectly referencing a lifetime parameter via a projection type (via a `T::Assoc` projection without an explicit trait), since lifetime resolution is performed on the HIR, when neither `T::Assoc`-style projections or `Self` in impls are expanded.
Therefore an error was implemented in #62849 to deny this subtle behavior as a known limitation of the compiler. It was attempted by `@cjgillot` to fix this in #91403, which was subsequently unlanded. Then it was re-attempted to much success (🎉) in #103491, which is where we currently are in the compiler.
The PR above (#103491) fixed this issue technically by *not* replacing the opaque's parent lifetimes with `'static`, but instead using variance to properly track which lifetimes are captured and are not. The PR gated any of the "side-effects" of the PR behind a feature gate (`impl_trait_projections`) presumably to avoid having to involve T-lang or T-types in the PR as well. `@cjgillot` can clarify this if I'm misunderstanding what their intention was with the feature gate.
Since we're not replacing (possibly *invariant*!) lifetimes with `'static` anymore, there are no more soundness concerns here. Therefore, this PR removes the feature gate.
Tests:
* `tests/ui/async-await/feature-self-return-type.rs`
* `tests/ui/impl-trait/feature-self-return-type.rs`
* `tests/ui/async-await/issues/issue-78600.rs`
* `tests/ui/impl-trait/capture-lifetime-not-in-hir.rs`
---
r? cjgillot on the impl (not much, just removing the feature gate)
I'm gonna mark this as FCP for T-lang and T-types.
Simplify some of the logic in the `invalid_reference_casting` lint
This PR simplifies 2 areas of the logic for the `invalid_reference_casting` lint:
- The init detection: we now use the newly added `expr_or_init` function instead of a manual detection
- The ref-to-mut-ptr casting detection logic: I simplified this logic by caring less hardly about the order of the casting operations
Those two simplifications permits us to detect more cases, as can be seen in the test output changes.
The current structure is clumsy, calling `alloc_raw_without_grow` in one
function, and then if that fails, calling another function that calls
`alloc_raw_without_grow` again.
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
```
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).
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``
lint towards rejecting consts in patterns that do not implement PartialEq
I think we definitely don't want to allow such consts, so even while the general plan around structural matching is up in the air, we can start the process of getting non-PartialEq matches out of the ecosystem.
Don't use a thread to load the dep graph
This removes the use of a thread to load the dep graph. It's not currently useful as we immediately block on it.
r? `@oli-obk`
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.
ConstParamTy: require Eq as supertrait
As discussed with `@BoxyUwu` [on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/260443-project-const-generics/topic/.60ConstParamTy.60.20and.20.60Eq.60).
We want to say that valtree equality on const generic params agrees with `==`, but that only makes sense if `==` actually exists, hence we should have an appropriate bound. Valtree equality is an equivalence relation, so such a type can always be `Eq` and not just `PartialEq`.
Use placeholders to prevent using inferred RPITIT types to imply their own well-formedness
The issue here is that we use the same signature to do RPITIT inference as we do to compute implied bounds. To fix this, when gathering the assumed wf types for the method, we replace all of the infer vars (that will be eventually used to infer RPITIT types) with type placeholders, which imply nothing about lifetime bounds.
This solution kind of sucks, but I'm not certain there's another feasible way to fix this. If anyone has a better solution, I'd be glad to hear it.
My naive first solution was, instead of using placeholders, to replace the signature with the RPITIT projections that it originally started out with. But turns out that we can't just use the unnormalized signature of the trait method in `implied_outlives_bounds` since we normalize during WF computation -- that would cause a query cycle in `collect_return_position_impl_trait_in_trait_tys`.
idk who to request review...
r? `@lcnr` or `@aliemjay` i guess.
Fixes#116060
Point at more causes of expectation of break value when possible
Follow up to #116071.
r? `@compiler-errors`
Disregard the first commit, which is in the other PR.
Pass name of object file to LLVM so it can correctly emit S_OBJNAME in pdb files on Windows
This should be the remaining fix to close https://github.com/rust-lang/rust/issues/96475
Setting ObjectFilenameForDebug in llvm::TargetOptions, so llvm it can emit S_OBJNAME in pdb files on Windows.
Without a proper pdb parsing I am not able to add a unit test for this. The string is already appearing in the pdb file so I cannot just use grep.
`@rustbot` label: +A-debuginfo
Rename the legacy feature gating macro
It had a really confusing name by shadowing the previous name, which has
caused issues in the past where people added their new syntax in the
legacy location.
This makes it clear.
Also adds a comment about the return type notation gating, which confused me why it was here at first before `@compiler-errors` told me why.
Fix debug printing of tuple
Self-explanatory. Didn't create a UI test, but I guess I could -- not sure where debug output shows up in rustc_attrs to make a sufficient test, tho.
Add Zba, Zbb, and Zbs as target features for riscv64-linux-android
This pull request adds the Zba, Zbb, and Zbs target features to the `riscv64-linux-android` target specification. These features have been enabled and tested internally in Android infrastructure.
Add Minimal Std implementation for UEFI
# Implemented modules:
1. alloc
2. os_str
3. env
4. math
# Related Links
Tracking Issue: https://github.com/rust-lang/rust/issues/100499
API Change Proposal: https://github.com/rust-lang/libs-team/issues/87
# Additional Information
This was originally part of https://github.com/rust-lang/rust/pull/100316. Since that PR was becoming too unwieldy and cluttered, and with suggestion from `@dvdhrm,` I have extracted a minimal std implementation to this PR.
The example in `src/doc/rustc/src/platform-support/unknown-uefi.md` has been tested for `x86_64-unknown-uefi` and `i686-unknown-uefi` in OVMF. It would be great if someone more familiar with AARCH64 can help with testing for that target.
Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
It had a really confusing name by shadowing the previous name, which has
caused issues in the past where people added their new syntax in the
legacy location.
This makes it clear.
Raise minimum supported Apple OS versions
This implements the proposal to raise the minimum supported Apple OS versions as laid out in the now-completed MCP (https://github.com/rust-lang/compiler-team/issues/556).
As of this PR, rustc and the stdlib now support these versions as the baseline:
- macOS: 10.12 Sierra
- iOS: 10
- tvOS: 10
- watchOS: 5 (Unchanged)
In addition to everything this breaks indirectly, these changes also erase the `armv7-apple-ios` target (currently tier 3) because the oldest supported iOS device now uses ARMv7s. Not sure what the policy around tier3 target removal is but shimming it is not an option due to the linker refusing.
[Per comment](https://github.com/rust-lang/compiler-team/issues/556#issuecomment-1297175073), this requires a FCP to merge. cc `@wesleywiser.`
More accurate suggestion for `self.` and `Self::`
Detect that we can't suggest `self.` in an associated function without `&self` receiver.
Partially address #115992.
r? ``@compiler-errors``
Check that closure/generator's interior/capture types are sized
check that closure upvars and generator interiors are sized. this check is only necessary when `unsized_fn_params` or `unsized_locals` is enabled, so only check if those are active.
Fixes#93622Fixes#61335Fixes#68543
Point at cause of expectation of `break` value when possible
When encountering a type error within the value of a `break` statement, climb the HIR tree to identify if the expectation comes from an assignment or a return type (if the loop is the tail expression of a `fn`).
Fix#115905.
Rollup of 6 pull requests
Successful merges:
- #115770 (Match on elem first while building move paths)
- #115999 (Capture scrutinee of if let guards correctly)
- #116056 (Make unsized casts illegal)
- #116061 (Remove TaKO8Ki from review rotation)
- #116062 (Change `start` to `#[start]` in some diagnosis)
- #116067 (Open the FileEncoder file for reading and writing)
r? `@ghost`
`@rustbot` modify labels: rollup
Open the FileEncoder file for reading and writing
Maybe I just don't know `File` well enough, but the previous comment didn't make it clear enough to me that we can't use `File::create`. This one does.
Fixes https://github.com/rust-lang/rust/issues/116055
r? `@WaffleLapkin`
Match on elem first while building move paths
While working on https://github.com/rust-lang/rust/pull/115025 `@lcnr` and I observed "move_paths_for" function matched on the `Ty` instead of `Projection` which seems flawed as it's the `Projection`s that cause the problem not the type.
r? `@lcnr`
[breaking change] Validate crate name in `--extern` [MCP 650]
Reject non-ASCII-identifier crate names passed to the CLI option `--extern` (`rustc`, `rustdoc`).
Implements [MCP 650](https://github.com/rust-lang/compiler-team/issues/650) (except that we only allow ASCII identifiers not arbitrary Rust identifiers).
Fixes#113035.
[As mentioned on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/233931-t-compiler.2Fmajor-changes/topic/Disallow.20non-identifier-valid.20--extern.20cr.E2.80.A6.20compiler-team.23650/near/376826988), doing a crater run probably doesn't make sense since it wouldn't yield anything. Most users don't interact with `rustc` directly but only ever through Cargo which always passes a valid crate name to `--extern` when it invokes `rustc` and `rustdoc`. In any case, the user wouldn't be able to use such a crate name in the source code anyway.
Note that I'm not using [`rustc_session::output::validate_crate_name`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/output/fn.validate_crate_name.html) (used for `--crate-name` and `#![crate_name]`) since the latter doesn't reject non-ASCII crate names and ones that start with a digit.
As an aside, I've also thought about getting rid of `validate_crate_name` entirely in a separate PR (with another MCP) in favor of `is_ascii_ident` to reject more weird `--crate-name`s, `#![crate_name]`s and file names but I think that would lead to a lot of actual breakage, namely because of file names starting with a digit. In `tests/ui` 9 tests would be impacted for example.
CC `@estebank`
r? `@est31`
adjust how closure/generator types are printed
I saw `&[closure@$DIR/issue-20862.rs:2:5]` and I thought it is a slice type, because that's usually what `&[_]` is... it took me a while to realize that this is just a confusing printer and actually there's no slice. Let's use something that cannot be mistaken for a regular type.
Allow `-Z treat-err-as-bug=0`
Makes `-Z treat-err-as-bug=0` behave as if the option wasn't present instead of asking the value to be ⩾ 1. This enables a quick on/off of the option, as you only need to change one character instead of removing the whole `-Z`.
Also update some text, e.g.
```bash
$ rustc -Z help | grep treat-err-as-bug
-Z treat-err-as-bug=val -- treat error number `val` that occurs as bug
```
where the value could be interpreted as an error code instead of an ordinal.
give FutureIncompatibilityReason variants more explicit names
Also make the `reason` field mandatory when declaring a lint, to make sure this is a deliberate decision.
Move `DepKind` to `rustc_query_system` and define it as `u16`
This moves the `DepKind` type to `rustc_query_system` where it's defined with an inner `u16` field. This decouples it from `rustc_middle` and is a step towards letting other crates define dep kinds. It also allows some type parameters to be removed. The `DepKind` trait is replaced with a `Deps` trait. That's used when some operations or information about dep kinds which is unavailable in `rustc_query_system` are still needed.
r? `@cjgillot`
This happens because variances are constructed from ty generics,
and ty generics are always constructed with lifetimes first.
See compiler/rustc_hir_analysis/src/collect/generics_of.rs:248-269
Fixes#83556
rustc_hir_analysis: add a helper to check function the signature mismatches
This function is now used to check `#[panic_handler]`, `start` lang item, `main`, `#[start]` and intrinsic functions.
The diagnosis produced are now closer to the ones produced by trait/impl method signature mismatch.
This is the first time I do anything with rustc_hir_analysis/rustc_hir_typeck, so comments and suggestions about things I did wrong or that could be improved will be appreciated.
Suggest desugaring to return-position `impl Future` when an `async fn` in trait fails an auto trait bound
First commit allows us to store the span of the `async` keyword in HIR.
Second commit implements a suggestion to desugar an `async fn` to a return-position `impl Future` in trait to slightly improve the `Send` situation being discussed in #115822.
This suggestion is only made when `#![feature(return_type_notation)]` is not enabled -- if it is, we should instead suggest an appropriate where-clause bound.
coverage: Don't bother renumbering expressions on the Rust side
The LLVM API that we use to encode coverage mappings already has its own code for removing unused coverage expressions and renumbering the rest.
This lets us get rid of our own complex renumbering code, making it easier to change our coverage code in other ways.
---
Now that we have tests for coverage mappings (#114843), I've been able to verify that this PR doesn't make the coverage mappings worse, thanks to an explicit simplification step.
interpret: more consistently use ImmTy in operators and casts
The diff in src/tools/miri/src/shims/x86/sse2.rs should hopefully suffice to explain why this is nicer. :)
rename mir::Constant -> mir::ConstOperand, mir::ConstKind -> mir::Const
Also, be more consistent with the `to/eval_bits` methods... we had some that take a type and some that take a size, and then sometimes the one that takes a type is called `bits_for_ty`.
Turns out that `ty::Const`/`mir::ConstKind` carry their type with them, so we don't need to even pass the type to those `eval_bits` functions at all.
However this is not properly consistent yet: in `ty` we have most of the methods on `ty::Const`, but in `mir` we have them on `mir::ConstKind`. And indeed those two types are the ones that correspond to each other. So `mir::ConstantKind` should actually be renamed to `mir::Const`. But what to do with `mir::Constant`? It carries around a span, that's really more like a constant operand that appears as a MIR operand... it's more suited for `syntax.rs` than `consts.rs`, but the bigger question is, which name should it get if we want to align the `mir` and `ty` types? `ConstOperand`? `ConstOp`? `Literal`? It's not a literal but it has a field called `literal` so it would at least be consistently wrong-ish...
``@oli-obk`` any ideas?
Prevent promotion of const fn calls in inline consts
We don't wanna make that mistake we did for statics and consts worse by letting more code use it.
r? ``@RalfJung``
cc https://github.com/rust-lang/rust/issues/76001
Improve invalid UTF-8 lint by finding the expression initializer
This PR introduce a small mechanism to walk up the HIR through bindings, if/else, consts, ... when trying lint on invalid UTF-8.
Fixes https://github.com/rust-lang/rust/issues/115208
The LLVM API that we use to encode coverage mappings already has its own code
for removing unused coverage expressions and renumbering the rest.
This lets us get rid of our own complex renumbering code, making it easier to
change our coverage code in other ways.
After coverage instrumentation and MIR transformations, we can sometimes end up
with coverage expressions that always have a value of zero. Any expression
operand that refers to an always-zero expression can be replaced with a literal
`Operand::Zero`, making the emitted coverage mapping data smaller and simpler.
This simplification step is mostly redundant with the simplifications performed
inline in `expressions_with_regions`, except that it does a slightly more
thorough job in some cases (because it checks for always-zero expressions
*after* other simplifications).
However, adding this simplification step will then let us greatly simplify that
code, without affecting the quality of the emitted coverage maps.
Fall back to the unoptimized implementation in read_binary_file if File::metadata lies
Fixes https://github.com/rust-lang/rust/issues/115458
r? `@jackh726` because you approved the previous PR