`tests/ui`: A New Order [25/N]
> [!NOTE]
>
> Intermediate commits are intended to help review, but will be squashed prior to merge.
Some `tests/ui/` housekeeping, to trim down number of tests directly under `tests/ui/`. Part of rust-lang/rust#133895.
r? `@tgross35`
`tests/ui`: A New Order [24/N]
> [!NOTE]
>
> Intermediate commits are intended to help review, but will be squashed prior to merge.
Some `tests/ui/` housekeeping, to trim down number of tests directly under `tests/ui/`. Part of rust-lang/rust#133895.
r? `@tgross35`
`tests/ui`: A New Order [22/N]
> [!NOTE]
>
> Intermediate commits are intended to help review, but will be squashed prior to merge.
Some `tests/ui/` housekeeping, to trim down number of tests directly under `tests/ui/`. Part of rust-lang/rust#133895.
r? `@tgross35`
`tests/ui`: A New Order [21/N]
> [!NOTE]
>
> Intermediate commits are intended to help review, but will be squashed prior to merge.
Some `tests/ui/` housekeeping, to trim down number of tests directly under `tests/ui/`. Part of rust-lang/rust#133895.
r? `@tgross35`
`tests/ui`: A New Order [18/N]
> [!NOTE]
>
> Intermediate commits are intended to help review, but will be squashed prior to merge.
Some `tests/ui/` housekeeping, to trim down number of tests directly under `tests/ui/`. Part of rust-lang/rust#133895.
r? `@tgross35`
`tests/ui`: A New Order [14/N]
> [!NOTE]
>
> Intermediate commits are intended to help review, but will be squashed prior to merge.
Some `tests/ui/` housekeeping, to trim down number of tests directly under `tests/ui/`. Part of rust-lang/rust#133895.
r? `@jieyouxu`
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- https://github.com/rust-lang/rust/pull/142005
- https://github.com/rust-lang/rust/pull/142103
- https://github.com/rust-lang/rust/pull/142324
- https://github.com/rust-lang/rust/pull/142383
---
try-job: aarch64-gnu
clean up GVN TypeId test
addresses https://github.com/rust-lang/rust/pull/142789#discussion_r2184897992
This is an attempt to clarify what this test is actually supposed to test and make it less dependent on `TypeId` internals (it now depends on the output of `type_name` instead).
I verified that this version still miscompiles on `nightly-2025-02-11`.
r? ``@oli-obk`` ``@RalfJung``
remove special-casing of boxes from match exhaustiveness/usefulness analysis
As a first step in replacing `box_patterns` with `deref_patterns`, this treats box patterns as deref patterns in the THIR and exhaustiveness analysis. This allows a bunch of special-casing to be removed. The emitted MIR is unchanged.
Incidentally, this fixes a bug caused by box patterns being treated like structs rather than pointers, where enabling `exhaustive_patterns` (rust-lang/rust#51085) could give rise to spurious `unreachable_patterns` lints on arms required for exhaustiveness. Following the lint's advice to remove the match arm would result in an error. I'm not sure what the current state of `exhaustive_patterns` is with regard to reference/box opsem, or whether there's any intention to have `unreachable_patterns` be more granular than the whole arm, but regardless this should hopefully make them easier to handle consistently.
Tracking issue for deref patterns: rust-lang/rust#87121
r? `@Nadrieril`
Assign dependency bump PRs to me
These PRs sometimes get lost as GH reduces their visibility, so I wanted to get an assignment so I can help these PRs land
Make metadata a workproduct and reuse it
This PR aims to skip the generation of metadata by reusing the infrastructure that already exists for compiled codegen-units, namely "workproducts".
This can yield substantial gains (~10%) when we can demonstrate that metadata does not change between an incremental session and the next. This is the case if the crate is unchanged, or if all the changes are in upstream crates and have no effect on it. This latter case is most interesting, as it arises regularly for users with several crates in their workspace.
TODO:
- [x] Materialize the fact that metadata encoding relies on the relative order of definitions;
- [x] Refactor the handling of doc links.
Make __rust_alloc_error_handler_should_panic a function
Fixesrust-lang/rust#143253
`__rust_alloc_error_handler_should_panic` is a static but was being exported as a function.
For most targets this doesn't matter, but Arm64EC Windows uses different decorations for exported variables vs functions, hence it fails to link when `-Z oom=abort` is enabled.
We've had issues in the past with statics like this (see rust-lang/rust#141061) but the tldr; is that Arm64EC needs symbols correctly exported as either a function or data, and data MUST and MUST ONLY be marked `dllimport` when the symbol is being imported from another binary, which is non-trivial to calculate for these compiler-generated statics.
So, instead, the easiest thing to do is to make `__rust_alloc_error_handler_should_panic` a function instead.
Since `__rust_alloc_error_handler_should_panic` isn't involved in any linking shenanigans, I've marked it as `AlwaysInline` with the hopes that the various backends will see that it is just returning a constant and perform the same optimizations as the previous implementation.
r? `@bjorn3`
Make -Ztrack-diagnostics emit like a note
[#t-compiler/diagnostics > Rendering -Ztrack-diagnostics like a note](https://rust-lang.zulipchat.com/#narrow/channel/147480-t-compiler.2Fdiagnostics/topic/Rendering.20-Ztrack-diagnostics.20like.20a.20note/with/526608647)
As discussed on the Zulip thread above, I want to make `-Ztrack-diagnostics` emit like a `note`. This is because I find its current output jarring, and the fact that it gets rendered completely left-aligned, [even in the middle of a snippet](86e05cd300/tests/ui/track-diagnostics/track6.stderr), seems like something that should be changed. Turning it into a `note` seems like the best choice, as it would align it with the rest of the output, and `note` is already used for somewhat similar things, like seeing why a lint was fired.
---
Note: turning `-Ztrack-diagnostics` into a `note` will also make `annotate-snippets` API a bit cleaner
Refactor StableMIR
This PR refactors stable-mir according to the guidance in [this doc](https://hackmd.io/jBRkZLqAQL2EVgwIIeNMHg). It reverses the dependency between `rustc_smir` and `stable_mir`, making `rustc_smir` completely agnostic of `stable_mir`.
Under the new architecture, the `rustc_smir` crate would retain direct access to rustc queries, while `stable_mir` should proxy all such requests through `rustc_smir` instead of accessing rustc's internals directly. `stable_mir` would only be responsible for the conversion between internal and stable constructs.
This PR mainly introduces these changes:
- **Bridge / Tables<'tcx, B: Bridge>**
```rust
/// A trait defining types that are used to emulate StableMIR components, which is really
/// useful when programming in stable_mir-agnostic settings.
pub trait Bridge {
type DefId: Copy + Debug + PartialEq + IndexedVal;
type AllocId: Copy + Debug + PartialEq + IndexedVal;
type Span: Copy + Debug + PartialEq + IndexedVal;
type Ty: Copy + Debug + PartialEq + IndexedVal;
type InstanceDef: Copy + Debug + PartialEq + IndexedVal;
type TyConstId: Copy + Debug + PartialEq + IndexedVal;
type MirConstId: Copy + Debug + PartialEq + IndexedVal;
type Layout: Copy + Debug + PartialEq + IndexedVal;
type Error: SmirError;
}
pub struct Tables<'tcx, B: Bridge> {
tcx: TyCtxt<'tcx>,
pub(crate) def_ids: IndexMap<DefId, B::DefId>,
pub(crate) alloc_ids: IndexMap<AllocId, B::AllocId>,
pub(crate) spans: IndexMap<rustc_span::Span, B::Span>,
pub(crate) types: IndexMap<Ty<'tcx>, B::Ty>,
pub(crate) instances: IndexMap<ty::Instance<'tcx>, B::InstanceDef>,
pub(crate) ty_consts: IndexMap<ty::Const<'tcx>, B::TyConstId>,
pub(crate) mir_consts: IndexMap<mir::Const<'tcx>, B::MirConstId>,
pub(crate) layouts: IndexMap<rustc_abi::Layout<'tcx>, B::Layout>,
}
```
Since `rustc_smir` needs these stable types somewhere, using associated types is a good approach.
- **SmirContainer / SmirInterface**
```rust
/// A container which is used for TLS.
pub struct SmirContainer<'tcx, B: Bridge> {
pub tables: RefCell<Tables<'tcx, B>>,
pub cx: RefCell<SmirCtxt<'tcx, B>>,
}
impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
// ...
}
/// Provides direct access to rustc's internal queries.
///
/// The [`crate::stable_mir::compiler_interface::SmirInterface`] must go through
/// this context to obtain rustc-level information.
pub struct SmirCtxt<'tcx, B: Bridge> {
tcx: TyCtxt<'tcx>,
_marker: PhantomData<B>,
}
```
This PR moves `Tables` from `SmirCtxt` to a new `SmirContainer` struct, since mutable borrows of `tables` should only be managed by `SmirInterface`. This change prevents `SmirCtxt` from holding separate borrows and requires passing `tables` explicitly when needed:
```rust
impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> {
// ...
/// Get the body of an Instance which is already monomorphized.
pub fn instance_body(
&self,
instance: ty::Instance<'tcx>,
tables: &mut Tables<'tcx, B>,
) -> Option<Body<'tcx>> {
tables
.instance_has_body(instance)
.then(|| BodyBuilder::new(self.tcx, instance).build(tables))
}
// ...
}
```
This PR introduces `SmirContainer` as a separate struct rather than bundling it into a `SmirInterface` struct. This separation makes the architecture more modular and easier to reason about.
- **context/traits.rs**
We use this file to define traits that are used for encapsulating the associated functions in the rustc's internals. This is much easier to use and maintain than directly cramming everything into `SmirCtxt`. Here is a real-world use case:
```rust
impl RustcInternal for ExistentialTraitRef {
type T<'tcx> = rustc_ty::ExistentialTraitRef<'tcx>;
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
) -> Self::T<'tcx> {
use rustc_smir::context::SmirExistentialTraitRef;
cx.new_from_args(self.def_id.0.internal(tables, cx), self.generic_args.internal(tables, cx))
}
}
```
- **Separation of `rustc_smir::alloc`**
The previous `rustc_smir::alloc` had many direct calls to rustc queries. This PR splits it into two parts: `rustc_smir::alloc` and `stable_mir::alloc`. Following the same pattern as `SmirCtxt` and `SmirInterface`, the `rustc_smir::alloc` handles all direct interactions with rustc queries and performs the actual memory allocations, while the `stable_mir::alloc` is responsible for constructing stable components.
- **Removal of `convert/error.rs`**
We use `SmirError::from_internal` instead, since implementing `Stable` for these internal errors would be redundant—`tables` is not actually used. If we later need to add something like `LayoutError` to `stable_mir`, we could implement it as follows:
```rust
impl SmirError for stable_mir::LayoutError {
fn from_internal<T: Debug>(err: T) -> Self {
// ...
}
}
```
**Unresolved questions:**
- There are still a few direct calls to rustc's internals scattered across `impl Stable`s, but most of them appear to be relatively stable, e.g., `mir::interpret::ConstAllocation::inner(self)` and `mir::syntax::SwitchTargets::otherwise(self)`.
r? `@celinval`
This removes special-casing of boxes from `rustc_pattern_analysis`, as a
first step in replacing `box_patterns` with `deref_patterns`.
Incidentally, it fixes a bug caused by box patterns being represented as
structs rather than pointers, where `exhaustive_patterns` could generate
spurious `unreachable_patterns` lints on arms required for
exhaustiveness; following the lint's advice would result in an error.