Improve diagnose for unconditional panic when resource limit
Improve diagnostic message for similar issue rust-lang/rust#115021.
When `parallel_compiler=true`, the Rust compiler frontend sets `-Z threads` to match the number of cores, which is reasonable and common. However, in a constrained environment or with an excessive number of cores (such as 377 mentioned below 😑), it could consume all resources and cause a panic.
Setting a default maximum for `-Z threads` in a parallel compiler is challenging. However, the panic error message can guide the user to check the system limit and explicitly lower the thread count according to their needs.
```
14:55:47 thread 'main' panicked at /rustc/f1586001ace26df7cafeb6534eaf76fb2c5513e5/compiler/rustc_interface/src/util.rs:216:18:
14:55:47 called `Result::unwrap()` on an `Err` value: ThreadPoolBuildError { kind: IOError(Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" }) }
...
14:55:47 note: compiler flags: --crate-type lib -C opt-level=z -C embed-bitcode=no -C linker=/cache/84996/rust-sdk/target/shim/aarch64-unknown-linux-ohos/clang -Z unstable-options -C symbol-mangling-version=v0 -Z panic-in-drop=abort -C codegen-units=1 -C debuginfo=1 -C embed-bitcode=yes -Z threads=377 -C link-arg=-Wl,--build-id=sha1 -Z binary-dep-depinfo
```
This prevents a warning about ABI relevant target features not being set
on x86 and arm. In addition it is required for miri to report correct
features in is_*_feature_detected!() if miri switches to the dummy backend.
Allow codegen backends to indicate which crate types they support
This way cargo will drop the unsupported crate types for crates that
specify multiple crate types.
This is a prerequisite for https://github.com/rust-lang/miri/pull/4648.
Skip codegen_crate call in check mode
This way we don't have to spawn the coordinator thread. Some errors will no longer be emitted with this in check mode. For example the check that `-Ctarget-cpu` is passed on targets that need this.
Suggested by `@saethlin`
Add a fast path for lowering trivial consts
The objective of this PR is to improve compilation performance for crates that define a lot of trivial consts. This is a flamegraph of a build of a library crate that is just 100,000 trivial consts, taken from a nightly compiler:
<img width="842" height="280" alt="2025-10-25-164005_842x280_scrot" src="https://github.com/user-attachments/assets/e5400aaf-03bd-4461-b905-054aa82ca60f" />
My objective is to target all of the cycles in `eval_to_const_value_raw` that are not part of `mir_built`, because if you look at the `mir_built` for a trivial const, we already have the value available.
In this PR, the definition of a trivial const is this:
```rust
const A: usize = 0;
```
Specifically, we look for if the `mir_built` body is a single basic block containing one assign statement and a return terminator, where the assign statement assigns an `Operand::Constant(Const::Val)`. The MIR dumps for these look like:
```
const A: usize = {
let mut _0: usize;
bb0: {
_0 = const 0_usize;
return;
}
}
```
The implementation is built around a new query, `trivial_const(LocalDefId) -> Option<(ConstValue, Ty)>` which returns the contents of the `Const::Val` in the `mir_built` if the `LocalDefId` is a trivial const.
Then I added _debug_ assertions to the beginning of `mir_for_ctfe` and `mir_promoted` to prevent trying to get the body of a trivial const, because that would defeat the optimization here. But these are deliberately _debug_ assertions because the consequence of failing the assertion is that compilation is slow, not corrupt. If we made these hard assertions, I'm sure there are obscure scenarios people will run into where the compiler would ICE instead of continuing on compilation, just a bit slower. I'd like to know about those, but I do not think serving up an ICE is worth it.
With the assertions in place, I just added logic around all the places they were hit, to skip over trying to analyze the bodies of trivial consts.
In the future, I'd like to see this work extended by:
* Pushing detection of trivial consts before MIR building
* Including DefKind::Static and DefKind::InlineConst
* Including consts like `_1 = const 0_usize; _0 = &_1`, which would make a lot of promoteds into trivial consts
* Handling less-trivial consts like `const A: usize = B`, which have `Operand::Constant(Const::Unevaluated)`
Add a dummy codegen backend
This allows building a rustc capable of running the frontend without any backend present. While this may not seem all that useful, it allows running the frontend of rustc to report errors or running miri to interpret a program without any backend present. This is useful when you are trying to say run miri in the browser as upstream LLVM can't be compiled for wasm yet. Or to run rustc itself in miri like I did a while ago and caught some UB.
debuginfo: add an unstable flag to write split DWARF to an explicit directory
Bazel requires knowledge of outputs from actions at analysis time, including file or directory name. In order to work around the lack of predictable output name for dwo files, we group the dwo files in a subdirectory of --out-dir as a post-processing step before returning control to bazel. Unfortunately some debugging workflows rely on directly opening the dwo file rather than loading the merged dwp file, and our trick of moving the files breaks those users. We can't just hardlink the file or copy it, because with remote build execution we wouldn't end up with the un-moved file copied back to the developer's workstation. As a fix, we add this unstable flag that causes dwo files to be written to a build-system-controllable location, which then lets bazel hoover up the dwo files, but the objects also have the correct path for the dwo files.
r? `@davidtwco`
This allows building a rustc capable of running the frontend without any
backend present. While this may not seem all that useful, it allows
running the frontend of rustc to report errors or running miri to
interpret a program without any backend present. This is useful when you
are trying to say run miri in the browser as upstream LLVM can't be
compiled for wasm yet. Or to run rustc itself in miri like I did a while
ago and caught some UB.
Bazel requires knowledge of outputs from actions at analysis time,
including file or directory name. In order to work around the lack of
predictable output name for dwo files, we group the dwo files in a
subdirectory of --out-dir as a post-processing step before returning
control to bazel. Unfortunately some debugging workflows rely on
directly opening the dwo file rather than loading the merged dwp file,
and our trick of moving the files breaks those users. We can't just
hardlink the file or copy it, because with remote build execution we
wouldn't end up with the un-moved file copied back to the developer's
workstation. As a fix, we add this unstable flag that causes dwo files
to be written to a build-system-controllable location, which then lets
bazel hoover up the dwo files, but the objects also have the correct
path for the dwo files.
Small string formatting cleanup
This PR is mostly useless. I was going through this file, saw that and corrected it. That's pretty much it. Feel free to close it if it's a bother.
This makes it clearer that it is set by the build system rather than by
the rustc that compiles the current rustc. It also avoids bootstrap
needing to pass --check-cfg llvm_enzyme to rustc.
Strip frontmatter in fewer places
* Stop stripping frontmatter in `proc_macro::Literal::from_str` (RUST-146132)
* Stop stripping frontmatter in expr-ctxt (but not item-ctxt!) `include`s (RUST-145945)
* Stop stripping shebang (!) in `proc_macro::Literal::from_str`
* Not a breaking change because it did compare spans already to ensure there wasn't extra whitespace or comments (`Literal::from_str("#!\n0")` already yields `Err(_)` thankfully!)
* Stop stripping frontmatter+shebang inside some rustdoc code where it doesn't make any observable difference (see self review comments)
* (Stop stripping frontmatter+shebang inside internal test code)
Fixes https://github.com/rust-lang/rust/issues/145945.
Fixes https://github.com/rust-lang/rust/issues/146132.
r? fee1-dead
cleanup and cache proof tree building
There's some cruft left over from when we had deep proof trees. We never encounter overflow when evaluating proof trees. Even if the recursion limit is `0`, we still only hit the overflow limit when evaluating nested goals of the root. The root goal simply inherits the `root_depth` of the `SearchGraph`.
Split `evaluate_root_goal_for_proof_tree` from the rest of the trait solver. This enables us to simplify the implementation of `evaluate_goal_raw` and the `ProofTreeBuilder` as we no longer need to manually track the state of the builder and can instead use separate types for that. It does require making a few internal methods into associated functions taking a `delegate` and a `span` instead of the `EvalCtxt` itself.
I've also split `SearchGraph::evaluate_goal` and `SearchGraph::evaluate_root_goal_for_proof_tree` for the same reason. Both functions don't actually share too much code, so by splitting them each version gets significantly easier to read.
Add a `query evaluate_root_goal_for_proof_tree_raw` to cache proof tree building. This requires arena allocating `inspect::Probe`. I've added a new type alias `I::ProbeRef` for this. We may need to adapt this for rust-analyzer? It would definitely be easy to remove the `Copy` bound here 🤔
This was done in #145740 and #145947. It is causing problems for people
using r-a on anything that uses the rustc-dev rustup package, e.g. Miri,
clippy.
This repository has lots of submodules and subtrees and various
different projects are carved out of pieces of it. It seems like
`[workspace.dependencies]` will just be more trouble than it's worth.
Refactor lint buffering to avoid requiring a giant enum
Lint buffering currently relies on a giant enum `BuiltinLintDiag` containing all the lints that might potentially get buffered. In addition to being an unwieldy enum in a central crate, this also makes `rustc_lint_defs` a build bottleneck: it depends on various types from various crates (with a steady pressure to add more), and many crates depend on it.
Having all of these variants in a separate crate also prevents detecting when a variant becomes unused, which we can do with a dedicated type defined and used in the same crate.
Refactor this to use a dyn trait, to allow using `LintDiagnostic` types directly.
Because the existing `BuiltinLintDiag` requires some additional types in order to decorate some variants, which are only available later in `rustc_lint`, use an enum `DecorateDiagCompat` to handle both the `dyn LintDiagnostic` case and the `BuiltinLintDiag` case.
---
With the infrastructure in place, use it to migrate three of the enum variants to use `LintDiagnostic` directly, as a proof of concept and to demonstrate that the net result is a reduction in code size and a removal of a boilerplate-heavy layer of indirection.
Also remove an unused `BuiltinLintDiag` variant.
Lint buffering currently relies on a giant enum `BuiltinLintDiag`
containing all the lints that might potentially get buffered. In
addition to being an unwieldy enum in a central crate, this also makes
`rustc_lint_defs` a build bottleneck: it depends on various types from
various crates (with a steady pressure to add more), and many crates
depend on it.
Having all of these variants in a separate crate also prevents detecting
when a variant becomes unused, which we can do with a dedicated type
defined and used in the same crate.
Refactor this to use a dyn trait, to allow using `LintDiagnostic` types
directly.
This requires boxing, but all of this is already on the slow path
(emitting an error).
Because the existing `BuiltinLintDiag` requires some additional types in
order to decorate some variants, which are only available later in
`rustc_lint`, use an enum `DecorateDiagCompat` to handle both the `dyn
LintDiagnostic` case and the `BuiltinLintDiag` case.
Add `-Zindirect-branch-cs-prefix`
Cc: ``@azhogin`` ``@Darksonn``
This goes on top of https://github.com/rust-lang/rust/pull/135927, i.e. please skip the first commit here. Please feel free to inherit it there.
In fact, I am not sure if there is any use case for the flag without `-Zretpoline*`. GCC and Clang allow it, though.
There is a `FIXME` for two `ignore`s in the test that I took from another test I did in the past -- they may be needed or not here since I didn't run the full CI. Either way, it is not critical.
Tracking issue: https://github.com/rust-lang/rust/issues/116852.
MCP: https://github.com/rust-lang/compiler-team/issues/868.
Fix adjacent code
Fix duplicate warning; merge test into `tests/ui-fulldeps/internal-lints`
Use `rustc_middle::ty::FnSig::inputs`
Address two review comments
- https://github.com/rust-lang/rust/pull/139345#discussion_r2109006991
- https://github.com/rust-lang/rust/pull/139345#discussion_r2109058588
Use `Instance::try_resolve`
Import `rustc_middle::ty::Ty` as `Ty` rather than `MiddleTy`
Simplify predicate handling
Add more `#[allow(rustc::potential_query_instability)]` following rebase
Remove two `#[allow(rustc::potential_query_instability)]` following rebase
Address review comment
Update compiler/rustc_lint/src/internal.rs
Co-authored-by: lcnr <rust@lcnr.de>