Remove `DiagCtxt` API duplication
`DiagCtxt` defines the internal API for creating and emitting diagnostics: methods like `struct_err`, `struct_span_warn`, `note`, `create_fatal`, `emit_bug`. There are over 50 methods.
Some of these methods are then duplicated across several other types: `Session`, `ParseSess`, `Parser`, `ExtCtxt`, and `MirBorrowckCtxt`. `Session` duplicates the most, though half the ones it does are unused. Each duplicated method just calls forward to the corresponding method in `DiagCtxt`. So this duplication exists to (in the best case) shorten chains like `ecx.tcx.sess.parse_sess.dcx.emit_err()` to `ecx.emit_err()`.
This API duplication is ugly and has been bugging me for a while. And it's inconsistent: there's no real logic about which methods are duplicated, and the use of `#[rustc_lint_diagnostic]` and `#[track_caller]` attributes vary across the duplicates.
This PR removes the duplicated API methods and makes all diagnostic creation and emission go through `DiagCtxt`. It also adds `dcx` getter methods to several types to shorten chains. This approach scales *much* better than API duplication; indeed, the PR adds `dcx()` to numerous types that didn't have API duplication: `TyCtxt`, `LoweringCtxt`, `ConstCx`, `FnCtxt`, `TypeErrCtxt`, `InferCtxt`, `CrateLoader`, `CheckAttrVisitor`, and `Resolver`. These result in a lot of changes from `foo.tcx.sess.emit_err()` to `foo.dcx().emit_err()`. (You could do this with more types, but it gets into diminishing returns territory for types that don't emit many diagnostics.)
After all these changes, some call sites are more verbose, some are less verbose, and many are the same. The total number of lines is reduced, mostly because of the removed API duplication. And consistency is increased, because calls to `emit_err` and friends are always preceded with `.dcx()` or `.dcx`.
r? `@compiler-errors`
Give temporaries in if let guards correct scopes
Temporaries in if-let guards have scopes that escape the match arm, this causes problems because the drops might be for temporaries that are not storage live. This PR changes the scope of temporaries in if-let guards to be limited to the arm:
```rust
_ if let Some(s) = std::convert::identity(&Some(String::new())) => {}
// Temporary for Some(String::new()) is dropped here ^
```
We also now deduplicate temporaries between copies of the guard created for or-patterns:
```rust
// Only create a single Some(String::new()) temporary variable
_ | _ if let Some(s) = std::convert::identity(&Some(String::new())) => {}
```
This changes MIR building to pass around `ExprId`s rather than `Expr`s so that we have a way to index different expressions.
cc #51114Closes#116079
Unify SourceFile::name_hash and StableSourceFileId
This PR adapts the existing `StableSourceFileId` type so that it can be used instead of the `name_hash` field of `SourceFile`. This simplifies a few things that were kind of duplicated before.
The PR should also fix issues https://github.com/rust-lang/rust/issues/112700 and https://github.com/rust-lang/rust/issues/115835, but I was not able to reproduce these issues in a regression test. As far as I can tell, the root cause of these issues is that the id of the originating crate is not hashed in the `HashStable` impl of `Span` and thus cache entries that should have been considered invalidated were loaded. After this PR, the `stable_id` field of `SourceFile` includes information about the originating crate, so that ICE should not occur anymore.
Stabilize ip_in_core feature
Finally the last stage of https://github.com/rust-lang/rfcs/pull/2832. Since the FCP was [just completed with disposition *merge*](https://github.com/rust-lang/rust/issues/108443#issuecomment-1867864920), I create the stabilization PR for the `ip_in_core` feature. Allowing usage of `core::net` on stable Rust.
The error type `core::net::AddrParseError` itself becomes stable with this PR. However, `core::error::Error` is still unstable, so the `Error` impl for this type is not available on stable rust. Simply because `error_in_core` is not stable yet, but that should be fine!
Subtree sync for rustc_codegen_cranelift
This implements simd_masked_store and fixes two borked subtree syncs that forgot to sync back some changes to the rust repo.
r? `@ghost`
`@rustbot` label +A-codegen +A-cranelift +T-compiler
Exhaustiveness: Improve complexity on some wide matches
https://github.com/rust-lang/rust/issues/118437 revealed an exponential case in exhaustiveness checking. While [exponential cases are unavoidable](https://compilercrim.es/rust-np/), this one only showed up after my https://github.com/rust-lang/rust/pull/117611 rewrite of the algorithm. I remember anticipating a case like this and dismissing it as unrealistic, but here we are :').
The tricky match is as follows:
```rust
match command {
BaseCommand { field01: true, .. } => {}
BaseCommand { field02: true, .. } => {}
BaseCommand { field03: true, .. } => {}
BaseCommand { field04: true, .. } => {}
BaseCommand { field05: true, .. } => {}
BaseCommand { field06: true, .. } => {}
BaseCommand { field07: true, .. } => {}
BaseCommand { field08: true, .. } => {}
BaseCommand { field09: true, .. } => {}
BaseCommand { field10: true, .. } => {}
// ...20 more of the same
_ => {}
}
```
To fix this, this PR formalizes a concept of "relevancy" (naming is hard) that was already used to decide what patterns to report. Now we track it for every row, which in wide matches like the above can drastically cut on the number of cases we explore. After this fix, the above match is checked with linear-many cases instead of exponentially-many.
Fixes https://github.com/rust-lang/rust/issues/118437
r? `@cjgillot`
Remove metadata decoding DefPathHash cache
My expectation is that this cache is largely useless. Decoding a DefPathHash from metadata is essentially a pair of memory loads - there's no heavyweight processing involved. Caching it behind a HashMap just adds extra cost and incurs hashing overheads for the indices.
Based on https://github.com/rust-lang/rust/pull/119238.
Skip duplicate stable crate ID encoding into metadata
Instead, we store just the local crate hash as a bare u64. On decoding,
we recombine it with the crate's stable crate ID stored separately in
metadata. The end result is that we save ~8 bytes/DefIndex in metadata
size.
One key detail here is that we no longer distinguish in encoded metadata
between present and non-present DefPathHashes. It used to be highly
likely we could distinguish as we used DefPathHash::default(), an
all-zero representation. However in theory even that is fallible as
nothing strictly prevents the StableCrateId from being zero. In review it
was pointed out that we should never have a missing hash for a DefIndex anyway,
so this shouldn't matter.
fix minor mistake in comments describing VecDeque resizing
Avoiding confusion where one of the items in the deque seems to disappear in two of the three cases
improve container runner script
First commit fixes#118930
Second commit is mostly for development purposes. In read-only mode submodules cannot be initialized due to access limitations (see the log below), which means that tools cannot be built.
```sh
Updating submodule src/tools/cargo
error: could not lock config file .git/config: Read-only file system
error: could not lock config file .git/config: Read-only file system
fatal: Failed to register url for submodule path 'src/tools/cargo'
error: could not lock config file .git/config: Read-only file system
error: could not lock config file .git/config: Read-only file system
fatal: Failed to register url for submodule path 'src/tools/cargo'
Build completed unsuccessfully in 0:00:00
```
This cache is largely useless. Decoding a DefPathHash from metadata is
essentially a pair of memory loads - there's no heavyweight processing
involved. Caching it behind a HashMap just adds extra cost and incurs
hashing overheads.
Instead, we store just the local crate hash as a bare u64. On decoding,
we recombine it with the crate's stable crate ID stored separately in
metadata. The end result is that we save ~8 bytes/DefIndex in metadata
size.
One key detail here is that we no longer distinguish in encoded metadata
between present and non-present DefPathHashes. It used to be highly
likely we could distinguish as we used DefPathHash::default(), an
all-zero representation. However in theory even that is fallible as
nothing strictly prevents the StableCrateId from being zero.