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`
compiler: Document and reduce `fn provide`s in hir crates
I found it hard to follow all these tiny micro-indirections. Much like you shouldn't pass around `&u32` if you can help it, you probably shouldn't use an indirection if the indirection overhead itself is literally bigger than the amount of data you are organizing. Generally a new `fn provide` amounts to around 3 LOC:
- the signature with opening brace
- the `rustc_middle::query::Providers` import
- an end brace
I am not even counting the cost in time and thought to go find the other `provide`, read it, understand, "Ah, yes, these functions", and then go to those. Thus I say we should collapse indirections of `provide` for modules that only export 1~2 queries. For higher-count indirections, I left them as-is, as I don't understand the crate well enough to judge their worth.
Then I dropped a pointer to the actual module of interest for all these instances of the same function. I think documenting them is important because the comment that it relates to the query system makes it obvious that they have **nothing** to do with the rest of the module's logic and I can carry on ignoring them. Actively doing so is another cognitive cost, but much more minimal.
There is also a small correctness issue in that all of these functions are technically mutating state. It's not a huge deal, but it's still easier to check all these mutations do not overlap if we have less instances of `fn provide` to check.
remove redundant #[must_use]
Fixes these clippy warnings:
```
warning: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`
--> library/core/src/cmp.rs:1456:5
|
1456 | fn __chaining_lt(&self, other: &Rhs) -> ControlFlow<bool> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: either add some descriptive message or remove the attribute
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#double_must_use
= note: `-D clippy::double-must-use` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::double_must_use)]`
warning: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`
--> library/core/src/cmp.rs:1465:5
|
1465 | fn __chaining_le(&self, other: &Rhs) -> ControlFlow<bool> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: either add some descriptive message or remove the attribute
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#double_must_use
warning: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`
--> library/core/src/cmp.rs:1474:5
|
1474 | fn __chaining_gt(&self, other: &Rhs) -> ControlFlow<bool> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: either add some descriptive message or remove the attribute
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#double_must_use
warning: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`
--> library/core/src/cmp.rs:1483:5
|
1483 | fn __chaining_ge(&self, other: &Rhs) -> ControlFlow<bool> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: either add some descriptive message or remove the attribute
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#double_must_use
```
use unsigned_abs instead of `abs` on signed int to silence clippy
Use `unsigned_abs` instead of `abs` on signed int to silence clippy. Alternatively we could allow the lint, but if codegen is not affected, then this seems preferable.
update coherence example
## PR Summary
Small PR - Commit 0533ff7d41 moved the `coherence_different_hidden_ty.rs` file. This PR adjusts sources to changes.
Fast path nitpicks
Miscellaneous commits that I didn't really want to fold into anything else.
Fixes one theoretical bug with the fast path not considering polarity for `T: !Sized` bounds.
We want to keep StableMIR definitions and logic separate from any sort of conversion and usage of internal rustc code. So we bundle all unstable items that have no stability guarantees into `stable_mir::unstable`.
add a new trait `InternalCx`, which defines the methods that are fine to call from `RustcInternal`. `RustcInternal::internal()` then takes a `impl InternalCx<'tcx>` instead of `TyCtxt<'tcx>`.
make `tcx` in `SmirCtxt` public, since we need to pass it to `RustcInternal::internal()` in `SmirInterface`.
note that this commit delete `convert/error.rs`, we would use `SmirError::from_internal` instead.
**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)`.
This commit removes the `Tables` field from `SmirCtxt`, since borrows of `tables` should only be managed by `SmirInterface`.
This change prevents `SmirCtxt` from holding separate borrows and requires passing `tables` explicitly when needed.
We use the `traits.rs` 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`.
The previous `rustc_smir::alloc` had many direct calls to rustc queries.
This commit 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.
- rewrite all `SmirInterface` apis.
- add `BridgeTys` to impl those associated types in `Bridge`.
- move `**_def()` stuffs living in `impl Tables` from `rustc_internal` to `stable_mir`.
MIR inliner maintains unused var_debug_info
Only `full` debuginfo level promises variable-level debug information, but the MIR inline pass needlessly preserved the local variable debug info for the `limited` level too.