Refactor `try_execute_query`
This merges `JobOwner::try_start` into `try_execute_query`, removing `TryGetJob` in the processes. 3 new functions are extracted from `try_execute_query`: `execute_job`, `cycle_error` and `wait_for_query`. This makes the control flow a bit clearer and improves performance.
Based on https://github.com/rust-lang/rust/pull/109046.
<table><tr><td rowspan="2">Benchmark</td><td colspan="1"><b>Before</b></th><td colspan="2"><b>After</b></th></tr><tr><td align="right">Time</td><td align="right">Time</td><td align="right">%</th></tr><tr><td>🟣 <b>clap</b>:check</td><td align="right">1.7134s</td><td align="right">1.7061s</td><td align="right"> -0.43%</td></tr><tr><td>🟣 <b>hyper</b>:check</td><td align="right">0.2519s</td><td align="right">0.2510s</td><td align="right"> -0.35%</td></tr><tr><td>🟣 <b>regex</b>:check</td><td align="right">0.9517s</td><td align="right">0.9481s</td><td align="right"> -0.38%</td></tr><tr><td>🟣 <b>syn</b>:check</td><td align="right">1.5389s</td><td align="right">1.5338s</td><td align="right"> -0.33%</td></tr><tr><td>🟣 <b>syntex_syntax</b>:check</td><td align="right">5.9488s</td><td align="right">5.9258s</td><td align="right"> -0.39%</td></tr><tr><td>Total</td><td align="right">10.4048s</td><td align="right">10.3647s</td><td align="right"> -0.38%</td></tr><tr><td>Summary</td><td align="right">1.0000s</td><td align="right">0.9962s</td><td align="right"> -0.38%</td></tr></table>
r? `@cjgillot`
Split `execute_job` into `execute_job_incr` and `execute_job_non_incr`
`execute_job` was a bit large, so this splits it in 2. Performance was neutral locally, but this may affect bootstrap times.
Optimize dep node backtrace and ignore fatal errors
This attempts to optimize https://github.com/rust-lang/rust/pull/91742 while also passing through fatal errors.
r? `@cjgillot`
Check that a query has not completed and is not executing before starting it
This fixes a race in the query system where we only checked if the query was currently executing, but not if it was already completed, causing queries to re-execute.
r? `@cjgillot`
Ensure value is on the on-disk cache before returning from `ensure()`.
The current logic for `ensure()` a query just checks that the node is green in the dependency graph.
However, a lot of places use `ensure()` to prevent the query from being called later. This is the case before stealing a query result.
If the query is actually green but the value is not available in the on-disk cache, `ensure` would return, but a subsequent call to the full query would run the code, and attempt to read from a stolen value.
This PR conforms the query system to the usage by checking whether the queried value is loadable from disk before returning.
Sadly, I can't manage to craft a proper test...
Should fix all instances of "attempted to read from stolen value".
Simplify message paths
This makes it easier to open the messages file. Right now I have to first click on the `locales` dir to open it, and then on the `en-US.ftl` file. `Cargo.toml` and `build.rs` files are also in the top level, and I think there should not be more than one file, so a directory isn't really needed. The [chosen strategy for pontoon adoption](https://rust-lang.zulipchat.com/#narrow/stream/336883-i18n/topic/pontoon.20and.20next.20steps) is out of tree. Even if this descision is changed in the future, the `messages.ftl` approach is also compatible with non-english translations living in-tree, as long as the non-english translations don't live in the `compiler/rustc_foo/` directories but in different ones. That would also be helpful for grepability purposes.
The commit was the result of automated changes:
```
for p in compiler/rustc_*; do mv $p/locales/en-US.ftl $p/messages.ftl; rmdir $p/locales; done
for p in compiler/rustc_*; do sed -i "s#\.\./locales/en-US.ftl#../messages.ftl#" $p/src/lib.rs; done
```
r? `@davidtwco`
This makes it easier to open the messages file while developing on features.
The commit was the result of automatted changes:
for p in compiler/rustc_*; do mv $p/locales/en-US.ftl $p/messages.ftl; rmdir $p/locales; done
for p in compiler/rustc_*; do sed -i "s#\.\./locales/en-US.ftl#../messages.ftl#" $p/src/lib.rs; done
Make `rustc_query_system` take `QueryConfig` by instance.
This allows for easy switching between virtual tables and specialized instances for queries. It also has the benefit of less turbofish. `QueryStorage` has also been merged with `QueryCache`.
Split out from https://github.com/rust-lang/rust/pull/107937.
r? `@cjgillot`
errors: generate typed identifiers in each crate
Instead of loading the Fluent resources for every crate in `rustc_error_messages`, each crate generates typed identifiers for its own diagnostics and creates a static which are pulled together in the `rustc_driver` crate and provided to the diagnostic emitter.
There are advantages and disadvantages to this change..
#### Advantages
- Changing a diagnostic now only recompiles the crate for that diagnostic and those crates that depend on it, rather than `rustc_error_messages` and all crates thereafter.
- This approach can be used to support first-party crates that want to supply translatable diagnostics (e.g. `rust-lang/thorin` in https://github.com/rust-lang/rust/pull/102612#discussion_r985372582, cc `@JhonnyBillM)`
- We can extend this a little so that tools built using rustc internals (like clippy or rustdoc) can add their own diagnostic resources (much more easily than those resources needing to be available to `rustc_error_messages`)
#### Disadvantages
- Crates can only refer to the diagnostic messages defined in the current crate (or those from dependencies), rather than all diagnostic messages.
- `rustc_driver` (or some other crate we create for this purpose) has to directly depend on *everything* that has error messages.
- It already transitively depended on all these crates.
#### Pending work
- [x] I don't know how to make `rustc_codegen_gcc`'s translated diagnostics work with this approach - because `rustc_driver` can't depend on that crate and so can't get its resources to provide to the diagnostic emission. I don't really know how the alternative codegen backends are actually wired up to the compiler at all.
- [x] Update `triagebot.toml` to track the moved FTL files.
r? `@compiler-errors`
cc #100717
Instead of loading the Fluent resources for every crate in
`rustc_error_messages`, each crate generates typed identifiers for its
own diagnostics and creates a static which are pulled together in the
`rustc_driver` crate and provided to the diagnostic emitter.
Signed-off-by: David Wood <david.wood@huawei.com>
Use a lock-free datastructure for source_span
follow up to the perf regression in https://github.com/rust-lang/rust/pull/105462
The main regression is likely the CStore, but let's evaluate the perf impact of this on its own
Don't call `with_reveal_all_normalized` in const-eval when `param_env` has inference vars in it
**what:** This slightly shifts the order of operations from an existing hack:
5b6ed253c4/compiler/rustc_middle/src/ty/consts/kind.rs (L225-L230)
in order to avoid calling a tcx query (`TyCtxt::reveal_opaque_types_in_bounds`, via `ParamEnv::with_reveal_all_normalized`) when a param-env has inference variables in it.
**why:** This allows us to enable fingerprinting of query keys/values outside of incr-comp in deubg mode, to make sure we catch other places where we're passing infer vars and other bad things into query keys. Currently that (bbf33836b9) crashes because we introduce inference vars into a param-env in the blanket-impl finder in rustdoc 😓5b6ed253c4/src/librustdoc/clean/blanket_impl.rs (L43)
See the CI failure here: https://github.com/rust-lang/rust/actions/runs/4058194838/jobs/6984834619
Factor query arena allocation out from query caches
This moves the logic for arena allocation out from the query caches into conditional code in the query system. The specialized arena caches are removed. A new `QuerySystem` type is added in `rustc_middle` which contains the arenas, providers and query caches.
Performance seems to be slightly regressed:
<table><tr><td rowspan="2">Benchmark</td><td colspan="1"><b>Before</b></th><td colspan="2"><b>After</b></th></tr><tr><td align="right">Time</td><td align="right">Time</td><td align="right">%</th></tr><tr><td>🟣 <b>clap</b>:check</td><td align="right">1.8053s</td><td align="right">1.8109s</td><td align="right"> 0.31%</td></tr><tr><td>🟣 <b>hyper</b>:check</td><td align="right">0.2600s</td><td align="right">0.2597s</td><td align="right"> -0.10%</td></tr><tr><td>🟣 <b>regex</b>:check</td><td align="right">0.9973s</td><td align="right">1.0006s</td><td align="right"> 0.34%</td></tr><tr><td>🟣 <b>syn</b>:check</td><td align="right">1.6048s</td><td align="right">1.6051s</td><td align="right"> 0.02%</td></tr><tr><td>🟣 <b>syntex_syntax</b>:check</td><td align="right">6.2992s</td><td align="right">6.3159s</td><td align="right"> 0.26%</td></tr><tr><td>Total</td><td align="right">10.9664s</td><td align="right">10.9922s</td><td align="right"> 0.23%</td></tr><tr><td>Summary</td><td align="right">1.0000s</td><td align="right">1.0017s</td><td align="right"> 0.17%</td></tr></table>
Incremental performance is a bit worse:
<table><tr><td rowspan="2">Benchmark</td><td colspan="1"><b>Before</b></th><td colspan="2"><b>After</b></th></tr><tr><td align="right">Time</td><td align="right">Time</td><td align="right">%</th></tr><tr><td>🟣 <b>clap</b>:check:initial</td><td align="right">2.2103s</td><td align="right">2.2247s</td><td align="right"> 0.65%</td></tr><tr><td>🟣 <b>hyper</b>:check:initial</td><td align="right">0.3335s</td><td align="right">0.3349s</td><td align="right"> 0.41%</td></tr><tr><td>🟣 <b>regex</b>:check:initial</td><td align="right">1.2597s</td><td align="right">1.2650s</td><td align="right"> 0.42%</td></tr><tr><td>🟣 <b>syn</b>:check:initial</td><td align="right">2.0521s</td><td align="right">2.0613s</td><td align="right"> 0.45%</td></tr><tr><td>🟣 <b>syntex_syntax</b>:check:initial</td><td align="right">7.8275s</td><td align="right">7.8583s</td><td align="right"> 0.39%</td></tr><tr><td>Total</td><td align="right">13.6832s</td><td align="right">13.7442s</td><td align="right"> 0.45%</td></tr><tr><td>Summary</td><td align="right">1.0000s</td><td align="right">1.0046s</td><td align="right"> 0.46%</td></tr></table>
It does seem like LLVM optimizers struggle a bit with the current state of the query system.
Based on top of https://github.com/rust-lang/rust/pull/107782 and https://github.com/rust-lang/rust/pull/107802.
r? `@cjgillot`